File

src/app/pages/checkout-page/checkout-page.component.ts

Description

Checkout page component

Implements

OnInit

Example

Metadata

selector app-checkout-page
styleUrls checkout-page.component.scss
templateUrl ./checkout-page.component.html

Index

Properties
Methods

Constructor

constructor(afs: FirebaseFirestoreService, auth: FirebaseAuthService, navigation: NavigationService)

Constructor

Parameters :
Name Type Optional Description
afs FirebaseFirestoreService

Firebase Storage Service

auth FirebaseAuthService

Firebase Auth Service

navigation NavigationService

Navigation Service

Methods

loadPaypalScript
loadPaypalScript()

Load paypal checkout script into DOM

Returns : Promise<any>
ngOnInit
ngOnInit()

Initalize component

Returns : void
renderPaypalButton
renderPaypalButton()

Render paypal button

Returns : void
setTemplate
setTemplate(template: string)

Set template

Parameters :
Name Type Optional Description
template string

Template name

Returns : void

Properties

Public cartItems
cartItems: ShoppingCartItem[]
Type : ShoppingCartItem[]

Cart items

Public checkOrderStatus
checkOrderStatus: string
Type : string

checkOrderStatus

checkoutCheckOrder
checkoutCheckOrder: TemplateRef<any>
Type : TemplateRef<any>
Decorators : ViewChild

checkoutCheckOrder

checkoutContactDetails
checkoutContactDetails: TemplateRef<any>
Type : TemplateRef<any>
Decorators : ViewChild

checkoutContactDetails

checkoutPaymentDelivery
checkoutPaymentDelivery: TemplateRef<any>
Type : TemplateRef<any>
Decorators : ViewChild

checkoutPaymentDelivery

Public checkType
checkType: any
Type : any
Default value : SHOPPINGCARTITEMTYPE

checkType variable

Public contactDetailsStatus
contactDetailsStatus: string
Type : string

contactDetailsStatus

Public didPaypalScriptLoad
didPaypalScriptLoad:
Default value : false

Display loading

Public invoice_number
invoice_number: string
Type : string

Invoice number

Public loading
loading:
Default value : true

Loading

loadingTmpl
loadingTmpl: TemplateRef<any>
Type : TemplateRef<any>
Decorators : ViewChild

loadingTmpl

Private log
log:
Default value : Log.create('CheckoutPageComponent')

Logger

Public paymentDeliveryStatus
paymentDeliveryStatus: string
Type : string

paymentDeliveryStatus

Public paypalConfig
paypalConfig: any
Type : any

paypal config

Public paypalItems
paypalItems: TransactionItem[]
Type : TransactionItem[]
Default value : []
Public shipping
shipping:
Default value : 0
Public subTotal
subTotal:
Default value : 0
Public template
template: TemplateRef<any>
Type : TemplateRef<any>

template

Public transaction
transaction: Transaction
Type : Transaction
Public user
user: User
Type : User

User

import { Component, OnInit, TemplateRef, ViewChild } from '@angular/core';
import * as localforage from 'localforage';
import { Log } from 'ng2-logger';

import { environment } from '../../../environments/environment';
import { User } from '../../classes/user';
import { COUNTRY } from '../../enums/country';
import { CURRENCY } from '../../enums/currency';
import { SHOPPINGCARTITEMTYPE } from '../../enums/shopping-cart-item-type';
import { ShoppingCartItem } from '../../interfaces/shopping-cart-item';
import { Transaction, TransactionItem } from '../../interfaces/transaction';
import { FirebaseAuthService } from '../../services/auth/firebase-auth/firebase-auth.service';
import { FirebaseFirestoreService } from '../../services/firebase/firestore/firebase-firestore.service';
import { FirebaseStorageService } from '../../services/firebase/storage/firebase-storage.service';
import { NavigationService } from '../../services/navigation/navigation.service';

declare let paypal: any;

/**
 * Checkout page component
 * @author Daniel Sogl, Anna Riesch
 */
@Component({
  selector: 'app-checkout-page',
  templateUrl: './checkout-page.component.html',
  styleUrls: ['./checkout-page.component.scss']
})
export class CheckoutPageComponent implements OnInit {
  /** Logger */
  private log = Log.create('CheckoutPageComponent');

  /** User */
  public user: User;

  /** Cart items */
  public cartItems: ShoppingCartItem[];
  public paypalItems: TransactionItem[] = [];

  /** contactDetailsStatus */
  public contactDetailsStatus: string;
  /** paymentDeliveryStatus */
  public paymentDeliveryStatus: string;
  /** checkOrderStatus */
  public checkOrderStatus: string;

  /** Display loading */
  public didPaypalScriptLoad = false;
  /** Loading */
  public loading = true;

  /** paypal config */
  public paypalConfig: any;

  /** Invoice number */
  public invoice_number: string;
  /** checkType variable */
  public checkType: any = SHOPPINGCARTITEMTYPE;

  public transaction: Transaction;

  public shipping = 0;
  public subTotal = 0;

  /** template */
  public template: TemplateRef<any>;
  /** loadingTmpl */
  @ViewChild('loadingTmpl') loadingTmpl: TemplateRef<any>;
  /** checkoutContactDetails */
  @ViewChild('checkoutContactDetails') checkoutContactDetails: TemplateRef<any>;
  /** checkoutPaymentDelivery */
  @ViewChild('checkoutPaymentDelivery')
  checkoutPaymentDelivery: TemplateRef<any>;
  /** checkoutCheckOrder */
  @ViewChild('checkoutCheckOrder') checkoutCheckOrder: TemplateRef<any>;

  /**
   * Constructor
   * @param {FirebaseStorageService} afs Firebase Storage Service
   * @param {FirebaseAuthService} auth Firebase Auth Service
   * @param {NavigationService} navigation Navigation Service
   */
  constructor(
    private afs: FirebaseFirestoreService,
    private auth: FirebaseAuthService,
    private navigation: NavigationService
  ) {}

  /**
   * Initalize component
   */
  ngOnInit() {
    this.log.color = 'orange';
    this.log.d('Component initialized');
    this.setTemplate('contactDetails');

    localforage
      .getItem('cart-items')
      .then((items: ShoppingCartItem[]) => {
        this.cartItems = items;
        this.auth.user.subscribe(user => {
          if (user) {
            this.user = user;
            this.log.d('Loaded user', this.user);

            this.invoice_number = this.afs.getId();
            for (let i = 0; i < this.cartItems.length; i++) {
              if (
                this.cartItems[i].itemType === SHOPPINGCARTITEMTYPE.PRINT &&
                this.shipping === 0
              ) {
                this.shipping = 4.95;
              }
              this.paypalItems.push({
                currency: CURRENCY.EUR,
                description: JSON.stringify(this.cartItems[i].info),
                name: `${this.cartItems[i].eventname}/${
                  this.cartItems[i].name
                }`,
                price: this.cartItems[i].price,
                quantity: this.cartItems[i].amount,
                sku: this.cartItems[i].itemType,
                tax: 0.19
              });
              this.subTotal +=
                this.cartItems[i].price * this.cartItems[i].amount;
            }

            this.transaction = {
              invoice_number: this.invoice_number,
              description: 'EventPicking Bestellung',
              reference_id: this.auth.getCurrentFirebaseUser().uid,
              amount: {
                currency: CURRENCY.EUR,
                total: this.subTotal + this.shipping,
                details: {
                  tax: 0,
                  shipping: this.shipping,
                  subtotal: this.subTotal
                }
              },
              item_list: {
                items: this.paypalItems,
                shipping_address: {
                  city: this.user.deliveryAdress.city,
                  country_code: COUNTRY.GERMANY,
                  line1: `${this.user.deliveryAdress.street} ${
                    this.user.deliveryAdress.streetnumber
                  }`,
                  phone: this.user.deliveryAdress.phone,
                  postal_code: this.user.deliveryAdress.zip,
                  recipient_name: `${this.user.deliveryAdress.name} ${
                    this.user.deliveryAdress.lastname
                  }`
                },
                shipping_method: 'DHL oder EMail',
                shipping_phone_number: this.user.deliveryAdress.phone
              }
            };

            this.log.d('Translaction', this.transaction);
            this.paypalConfig = {
              env: 'sandbox',
              locale: 'de_DE',
              client: {
                sandbox: environment.paypal_sandbox
              },
              style: {
                label: 'paypal',
                size: 'responsive', // small | medium | large | responsive
                shape: 'rect', // pill | rect
                color: 'blue', // gold | blue | silver | black
                tagline: false
              },
              commit: true,
              payment: (data, actions) => {
                return actions.payment.create({
                  payment: {
                    transactions: [this.transaction]
                  }
                });
              },
              onAuthorize: (data, actions) => {
                return actions.payment.execute().then(payment => {
                  // Save transaction into firestore
                  this.transaction.date = new Date().toDateString();
                  this.transaction.status = 'pending';
                  this.transaction.email = this.auth.getCurrentFirebaseUser().email;
                  this.transaction.photographer = this.cartItems[0].photographer;
                  this.afs
                    .saveTransaction(this.transaction)
                    .then(() => {
                      this.log.d('Saved transaction');
                      localforage.setItem('cart-items', []);
                      this.navigation.navigateTo('payment-success');
                    })
                    .catch(err => {
                      this.log.er('Error saving transaction', err);
                    });
                });
              },
              onCancel: (data, actions) => {
                // Buyer cancelled the payment
                return;
              },

              onError: err => {
                // An error occurred during the transaction
                console.log('Error', err);
                return;
              }
            };
          }
        });
      })
      .catch(err => {
        this.log.er('Error loading local storage items');
      });
  }

  /**
   * Set template
   * @param  {string} template Template name
   */
  setTemplate(template: string) {
    switch (template) {
      case 'contactDetails':
        this.template = this.checkoutContactDetails;
        break;
      case 'paymentDelivery':
        this.template = this.checkoutPaymentDelivery;
        break;
      case 'checkOrder':
        this.template = this.checkoutCheckOrder;
        break;
      default:
        this.template = this.loadingTmpl;
        break;
    }
  }

  /**
   * Render paypal button
   */
  renderPaypalButton() {
    if (!this.didPaypalScriptLoad) {
      this.loadPaypalScript().then(() => {
        paypal.Button.render(this.paypalConfig, '#paypal-button');
        this.loading = false;
      });
    }
  }

  /**
   * Load paypal checkout script into DOM
   * @returns {Promise<any>}
   */
  loadPaypalScript(): Promise<any> {
    this.didPaypalScriptLoad = true;
    return new Promise((resolve, reject) => {
      const scriptElement = document.createElement('script');
      scriptElement.src = 'https://www.paypalobjects.com/api/checkout.js';
      scriptElement.onload = resolve;
      document.body.appendChild(scriptElement);
    });
  }
}
<div class="row mt-5 pt-5">
  <div class="col-sm-12">
    <ul class="stepper stepper-horizontal">
      <li [class.active]="template === checkoutContactDetails">
        <a>
          <span class="circle">1</span>
          <span class="label">{{ 'NAV.CONTACT_DETAILS' | translate }}</span>
        </a>
      </li>
      <li [class.active]="template === checkoutPaymentDelivery">
        <a>
          <span class="circle">2</span>
          <span class="label">{{ 'NAV.PAYMENT_DELIVERY' | translate }}</span>
        </a>
      </li>
      <li [class.active]="template === checkoutCheckOrder">
        <a>
          <span class="circle">
            3
          </span>
          <span class="label">{{ 'NAV.CHECK_ORDER' | translate }}</span>
        </a>
      </li>
    </ul>
    <div class="row m-5">
      <ng-container *ngTemplateOutlet="template"></ng-container>
    </div>
  </div>

  <!--checkout-templates-->
  <ng-template #loadingTmpl>
    <mdb-spinner spinnerType="big" spinnerColor="blue"></mdb-spinner>
  </ng-template>

  <ng-template #checkoutContactDetails>
    <div class="container" *ngIf="user">
      <h2>{{ 'LABELS.CONTACT_DETAILS' | translate }}</h2>
      <p>{{ user.email }}</p>
      <br>
      <div class="row">
        <div class="col-6">
          <h2>{{ 'LABELS.DELIVERY_ADDRESS' | translate }}</h2>
          <p>{{ user.name }} {{ user.lastname }}</p>
          <p>{{ user.deliveryAdress.street }} {{ user.deliveryAdress.streetnumber }}</p>
          <p>{{ user.deliveryAdress.zip }} {{ user.deliveryAdress.city }}</p>
        </div>
        <!--col1-->
        <div class="col-6">
          <h2>{{ 'LABELS.BILLING_ADDRESS' | translate }}</h2>
          <p>{{ user.name }} {{ user.lastname }}</p>
          <p>{{ user.billingAdress.street }} {{ user.billingAdress.streetnumber }}</p>
          <p>{{ user.billingAdress.zip }} {{ user.billingAdress.city }}</p>
        </div>
        <!--col1-->
      </div>
      <!--row-->
      <div class="row justify-content-end">
        <p>
          <button id="checkout3_send_order" type="button" class="btn pink waves-effect" (click)="setTemplate('paymentDelivery')" mdbRippleRadius>{{ 'BUTTONS.NEXT' | translate }}</button>
        </p>
      </div>
    </div>
    <!--container-->
  </ng-template>

  <ng-template #checkoutPaymentDelivery>
    <div class="container">
      <h2>{{ 'LABELS.PAYMENT_SHIPPING_DETAILS' | translate }}</h2>
      <br>
      <div class="row justify-content-left">
        <div class="col-12">
          <h3>{{ 'LABELS.PAYMENT_METHOD' | translate }}</h3>
          <!-- PayPal Logo -->
          <a href="https://www.paypal.com/de/webapps/mpp/paypal-popup" title="So funktioniert PayPal">
            <img src="https://www.paypalobjects.com/webstatic/de_DE/i/de-pp-logo-150px.png" border="0" alt="PayPal Logo" />
          </a>
          <!-- PayPal Logo -->
        </div>
        <!--col1-->
      </div>
      <!--row-->
      <div class="row justify-content-left">
        <div class="col-8">
          <p class="padded">Nach dem Abschicken des Auftrags werden Sie auf die offizielle PayPal-Seite geleitet, um dort komfortabel und sicher
            zu bezahlen.
          </p>
        </div>
        <!--col1-->
      </div>
      <!--row-->
      <div class="row justify-content-left">
        <div class="col-12">
          <h3>{{ 'LABELS.DELIVERY_COSTS' | translate }}</h3>
        </div>
        <!--col1-->
      </div>
      <!--row-->
      <div class="row">
        <div class="col-9">
          <p>Druckerei: Lieferung in 7-10 Tagen</p>
          <p>Download: Lieferung in 5-15 Minuten</p>
        </div>
        <!--col1-->
        <div class="col-3">
          <p class="price">4,95€</p>
          <p class="price">Kostenlos</p>
        </div>
        <!--col2-->
      </div>
      <!--row-->
      <!-- Buttons to previous or next step -->
      <div class="row justify-content-end">
        <button id="checkout3_back" type="button" class="btn pink waves-effect" (click)="setTemplate('contactDetails')" mdbRippleRadius>{{ 'BUTTONS.BACK' | translate }}</button>
        <button id="checkout3_send_order" type="button" class="btn pink waves-effect" (click)="setTemplate('checkOrder'); renderPaypalButton()"
          mdbRippleRadius>{{ 'BUTTONS.NEXT' | translate }}</button>
        <!-- END buttons -->
      </div>
      <!--row-->
    </div>
    <!--container-->
  </ng-template>

  <ng-template #checkoutCheckOrder>
    <div class="container">
      <h2>{{ 'LABELS.ORDER_DETAILS' | translate }}</h2>
      <br>
      <div class="row">
        <div class="col-12">
          <table class="table table-striped table-responsive-sm">
            <thead id="sum_row" class="indigo">
              <tr>
                <th scope="col">{{ 'NAV.CART_QUANTITY' | translate }}</th>
                <th scope="col">{{ 'NAV.CART_ITEM' | translate }}</th>
                <th scope="col">{{ 'NAV.CART_TYPE' | translate }}</th>
                <th scope="col">{{ 'NAV.CART_SIZE' | translate }}</th>
                <th scope="col">{{ 'NAV.CART_PRICE' | translate }}</th>
              </tr>
            </thead>
            <tbody>
              <tr class="table-bordered" *ngFor="let item of cartItems; let i = index">
                <td>{{ item?.amount }}</td>
                <td>{{ item?.name }}</td>
                <td>
                  <i *ngIf="item.itemType === checkType.PRINT" class="fa fa-print fa-lg" aria-hidden="true"></i>
                  <i *ngIf="item.itemType === checkType.DOWNLOAD" class="fa fa-download fa-lg" aria-hidden="true"></i>
                </td>
                <td>{{ item?.format }}</td>
                <td>{{ item?.price | number:'0.2' }}€</td>
              </tr>
              <tr class="table background-white">
                <td>Zwischensumme</td>
                <td></td>
                <td></td>
                <td></td>
                <td>{{ subTotal | number:'0.2-2' }}€</td>
              </tr>
              <tr class="table  background-white">
                <td>+ Versandkosten</td>
                <td></td>
                <td></td>
                <td></td>
                <td>{{ shipping | number:'0.2-2' }}€</td>
              </tr>
              <tr class="table  background-white">
                <td>{{'LABELS.TOTAL'|translate}}</td>
                <td></td>
                <td></td>
                <td></td>
                <td>{{ subTotal + shipping | number:'0.2-2' }}€</td>
              </tr>
            </tbody>
          </table>
        </div>
        <!--col1-->
      </div>
      <!--row-->
      <div class="row">
        <div class="col-12">
          <br> Indem Sie Ihre Bestellung aufgeben, akzeptieren Sie unsere
          <a class="pink-text" target="_blank" href="./gtc">Allgemeinen Geschäftsbedingungen</a> und unsere
          <a class="pink-text" target="_blank" href="./data-protection">Datenschutzrichtlinie</a>.
          <br>
        </div>
        <!--col-->
      </div>
      <!--row-->
      <!-- Buttons to previous or next step -->
      <div class="row justify-content-end">
        <button id="checkout3_back" type="button" class="btn pink waves-effect" (click)="setTemplate('paymentDelivery')" mdbRippleRadius>{{ 'BUTTONS.BACK' | translate }}</button>
        <div id="paypal-button"></div>
        <!-- END buttons -->
      </div>
      <!--row-->
    </div>
    <!--container-->
  </ng-template>
  <!--END checkout-templates-->
</div>
Legend
Html element
Component
Html element with directive

results matching ""

    No results matching ""