Browse Source

feat(admin-ui): Add controls to settle authorized payments

Relates to #117
Michael Bromley 6 years ago
parent
commit
32006aea3c

+ 13 - 0
admin-ui/src/app/common/generated-types.ts

@@ -3418,6 +3418,13 @@ export type GetOrderQueryVariables = {
 
 export type GetOrderQuery = ({ __typename?: 'Query' } & { order: Maybe<({ __typename?: 'Order' } & OrderWithLinesFragment)> });
 
+export type SettlePaymentMutationVariables = {
+  id: Scalars['ID']
+};
+
+
+export type SettlePaymentMutation = ({ __typename?: 'Mutation' } & { settlePayment: Maybe<({ __typename?: 'Payment' } & Pick<Payment, 'id' | 'transactionId' | 'amount' | 'method' | 'state' | 'metadata'>)> });
+
 export type AssetFragment = ({ __typename?: 'Asset' } & Pick<Asset, 'id' | 'createdAt' | 'name' | 'fileSize' | 'mimeType' | 'type' | 'preview' | 'source'>);
 
 export type ProductVariantFragment = ({ __typename?: 'ProductVariant' } & Pick<ProductVariant, 'id' | 'enabled' | 'languageCode' | 'name' | 'price' | 'currencyCode' | 'priceIncludesTax' | 'priceWithTax' | 'stockOnHand' | 'trackInventory' | 'sku'> & { taxRateApplied: ({ __typename?: 'TaxRate' } & Pick<TaxRate, 'id' | 'name' | 'value'>), taxCategory: ({ __typename?: 'TaxCategory' } & Pick<TaxCategory, 'id' | 'name'>), options: Array<({ __typename?: 'ProductOption' } & Pick<ProductOption, 'id' | 'code' | 'languageCode' | 'name'>)>, facetValues: Array<({ __typename?: 'FacetValue' } & Pick<FacetValue, 'id' | 'code' | 'name'> & { facet: ({ __typename?: 'Facet' } & Pick<Facet, 'id' | 'name'>) })>, featuredAsset: Maybe<({ __typename?: 'Asset' } & AssetFragment)>, assets: Array<({ __typename?: 'Asset' } & AssetFragment)>, translations: Array<({ __typename?: 'ProductVariantTranslation' } & Pick<ProductVariantTranslation, 'id' | 'languageCode' | 'name'>)> });
@@ -4185,6 +4192,12 @@ export namespace GetOrder {
   export type Order = OrderWithLinesFragment;
 }
 
+export namespace SettlePayment {
+  export type Variables = SettlePaymentMutationVariables;
+  export type Mutation = SettlePaymentMutation;
+  export type SettlePayment = (NonNullable<SettlePaymentMutation['settlePayment']>);
+}
+
 export namespace Asset {
   export type Fragment = AssetFragment;
 }

+ 13 - 0
admin-ui/src/app/data/definitions/order-definitions.ts

@@ -125,3 +125,16 @@ export const GET_ORDER = gql`
     }
     ${ORDER_WITH_LINES_FRAGMENT}
 `;
+
+export const SETTLE_PAYMENT = gql`
+    mutation SettlePayment($id: ID!) {
+        settlePayment(id: $id) {
+            id
+            transactionId
+            amount
+            method
+            state
+            metadata
+        }
+    }
+`;

+ 8 - 2
admin-ui/src/app/data/providers/order-data.service.ts

@@ -1,5 +1,5 @@
-import { GetOrder, GetOrderList } from '../../common/generated-types';
-import { GET_ORDER, GET_ORDERS_LIST } from '../definitions/order-definitions';
+import { GetOrder, GetOrderList, SettlePayment } from '../../common/generated-types';
+import { GET_ORDER, GET_ORDERS_LIST, SETTLE_PAYMENT } from '../definitions/order-definitions';
 
 import { BaseDataService } from './base-data.service';
 
@@ -18,4 +18,10 @@ export class OrderDataService {
     getOrder(id: string) {
         return this.baseDataService.query<GetOrder.Query, GetOrder.Variables>(GET_ORDER, { id });
     }
+
+    settlePayment(id: string) {
+        return this.baseDataService.mutate<SettlePayment.Mutation, SettlePayment.Variables>(SETTLE_PAYMENT, {
+            id,
+        });
+    }
 }

+ 24 - 1
admin-ui/src/app/order/components/order-detail/order-detail.component.html

@@ -4,7 +4,7 @@
     <vdr-ab-right></vdr-ab-right>
 </vdr-action-bar>
 
-<div *ngIf="(entity$ | async) as order">
+<div *ngIf="entity$ | async as order">
     <div class="clr-row">
         <div class="clr-col-md-4">
             <table class="table table-vertical">
@@ -53,6 +53,29 @@
             <table class="table table-vertical">
                 <tbody>
                     <ng-container *ngFor="let payment of order.payments">
+                        <tr>
+                            <th>{{ 'order.payment-state' | translate }}</th>
+                            <td>
+                                {{ payment.state }}
+                                <ng-container *ngIf="payment.state === 'Authorized'">
+                                    <vdr-dropdown>
+                                        <button class="icon-button" vdrDropdownTrigger>
+                                            <clr-icon shape="ellipsis-vertical"></clr-icon>
+                                        </button>
+                                        <vdr-dropdown-menu vdrPosition="bottom-right">
+                                            <button
+                                                type="button"
+                                                vdrDropdownItem
+                                                [disabled]="i === 0"
+                                                (click)="settlePayment(payment)"
+                                            >
+                                                {{ 'order.settle-payment' | translate }}
+                                            </button>
+                                        </vdr-dropdown-menu>
+                                    </vdr-dropdown>
+                                </ng-container>
+                            </td>
+                        </tr>
                         <tr>
                             <th>{{ 'order.payment-method' | translate }}</th>
                             <td>{{ payment.method }}</td>

+ 26 - 2
admin-ui/src/app/order/components/order-detail/order-detail.component.ts

@@ -1,9 +1,12 @@
-import { ChangeDetectionStrategy, Component, OnDestroy, OnInit } from '@angular/core';
+import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnDestroy, OnInit } from '@angular/core';
 import { FormGroup } from '@angular/forms';
 import { ActivatedRoute, Router } from '@angular/router';
+import { _ } from 'src/app/core/providers/i18n/mark-for-extraction';
 
 import { BaseDetailComponent } from '../../../common/base-detail.component';
 import { Order, OrderWithLines } from '../../../common/generated-types';
+import { NotificationService } from '../../../core/providers/notification/notification.service';
+import { DataService } from '../../../data/providers/data.service';
 import { ServerConfigService } from '../../../data/server-config';
 
 @Component({
@@ -15,7 +18,14 @@ import { ServerConfigService } from '../../../data/server-config';
 export class OrderDetailComponent extends BaseDetailComponent<OrderWithLines.Fragment>
     implements OnInit, OnDestroy {
     detailForm = new FormGroup({});
-    constructor(router: Router, route: ActivatedRoute, serverConfigService: ServerConfigService) {
+    constructor(
+        router: Router,
+        route: ActivatedRoute,
+        serverConfigService: ServerConfigService,
+        private changeDetector: ChangeDetectorRef,
+        private dataService: DataService,
+        private notificationService: NotificationService,
+    ) {
         super(route, router, serverConfigService);
     }
 
@@ -38,6 +48,20 @@ export class OrderDetailComponent extends BaseDetailComponent<OrderWithLines.Fra
         return Object.entries(payment.metadata);
     }
 
+    settlePayment(payment: OrderWithLines.Payments) {
+        this.dataService.order.settlePayment(payment.id).subscribe(({ settlePayment }) => {
+            if (settlePayment) {
+                if (settlePayment.state === 'Settled') {
+                    this.notificationService.success(_('order.settle-payment-success'));
+                } else {
+                    this.notificationService.error(_('order.settle-payment-error'));
+                }
+                payment.state = settlePayment.state;
+                this.changeDetector.markForCheck();
+            }
+        });
+    }
+
     protected setFormValues(entity: Order.Fragment): void {
         // empty
     }

+ 1 - 4
admin-ui/src/app/settings/components/payment-method-detail/payment-method-detail.component.html

@@ -46,10 +46,7 @@
                     [for]="arg.name"
                     *ngIf="arg.type === ConfigArgType.BOOLEAN"
                 >
-                    <div class="toggle-switch" *ngIf="arg.type === 'boolean'">
-                        <input type="checkbox" [id]="arg.name" [formControlName]="arg.name" />
-                        <label [for]="arg.name"></label>
-                    </div>
+                    <input type="checkbox" [id]="arg.name" [formControlName]="arg.name" clrCheckbox />
                 </vdr-form-field>
             </section>
         </div>

+ 4 - 0
admin-ui/src/i18n-messages/en.json

@@ -411,9 +411,13 @@
     "order-code": "Order code",
     "payment-metadata": "Payment metadata",
     "payment-method": "Payment method",
+    "payment-state": "State",
     "product-name": "Product name",
     "product-sku": "SKU",
     "quantity": "Quantity",
+    "settle-payment": "Settle payment",
+    "settle-payment-error": "Could not settle payment",
+    "settle-payment-success": "Sucessfully settled payment",
     "shipping": "Shipping",
     "shipping-address": "Shipping address",
     "state": "State",