Ver código fonte

feat(admin-ui): Display surcharges in OrderDetail

Relates to #583
Michael Bromley 5 anos atrás
pai
commit
bbcc6d8b2e

+ 17 - 13
packages/admin-ui/src/lib/core/src/common/generated-types.ts

@@ -1287,6 +1287,19 @@ export type UpdateFacetValueInput = {
   customFields?: Maybe<Scalars['JSON']>;
 };
 
+export type Fulfillment = Node & {
+  __typename?: 'Fulfillment';
+  nextStates: Array<Scalars['String']>;
+  id: Scalars['ID'];
+  createdAt: Scalars['DateTime'];
+  updatedAt: Scalars['DateTime'];
+  orderItems: Array<OrderItem>;
+  state: Scalars['String'];
+  method: Scalars['String'];
+  trackingCode?: Maybe<Scalars['String']>;
+  customFields?: Maybe<Scalars['JSON']>;
+};
+
 export type UpdateGlobalSettingsInput = {
   availableLanguages?: Maybe<Array<LanguageCode>>;
   trackInventory?: Maybe<Scalars['Boolean']>;
@@ -1469,19 +1482,6 @@ export type OrderHistoryArgs = {
   options?: Maybe<HistoryEntryListOptions>;
 };
 
-export type Fulfillment = Node & {
-  __typename?: 'Fulfillment';
-  nextStates: Array<Scalars['String']>;
-  id: Scalars['ID'];
-  createdAt: Scalars['DateTime'];
-  updatedAt: Scalars['DateTime'];
-  orderItems: Array<OrderItem>;
-  state: Scalars['String'];
-  method: Scalars['String'];
-  trackingCode?: Maybe<Scalars['String']>;
-  customFields?: Maybe<Scalars['JSON']>;
-};
-
 export type UpdateOrderInput = {
   id: Scalars['ID'];
   customFields?: Maybe<Scalars['JSON']>;
@@ -5346,6 +5346,9 @@ export type OrderDetailFragment = (
   )>, lines: Array<(
     { __typename?: 'OrderLine' }
     & OrderLineFragment
+  )>, surcharges: Array<(
+    { __typename?: 'Surcharge' }
+    & Pick<Surcharge, 'id' | 'sku' | 'description' | 'price' | 'priceWithTax' | 'taxRate'>
   )>, discounts: Array<(
     { __typename?: 'Adjustment' }
     & AdjustmentFragment
@@ -7911,6 +7914,7 @@ export namespace OrderDetail {
   export type Fragment = OrderDetailFragment;
   export type Customer = (NonNullable<OrderDetailFragment['customer']>);
   export type Lines = NonNullable<(NonNullable<OrderDetailFragment['lines']>)[number]>;
+  export type Surcharges = NonNullable<(NonNullable<OrderDetailFragment['surcharges']>)[number]>;
   export type Discounts = NonNullable<(NonNullable<OrderDetailFragment['discounts']>)[number]>;
   export type Promotions = NonNullable<(NonNullable<OrderDetailFragment['promotions']>)[number]>;
   export type ShippingLines = NonNullable<(NonNullable<OrderDetailFragment['shippingLines']>)[number]>;

+ 1 - 1
packages/admin-ui/src/lib/core/src/common/introspection-result.ts

@@ -81,10 +81,10 @@ const result: PossibleTypesResultData = {
             'Collection',
             'Customer',
             'Facet',
+            'Fulfillment',
             'HistoryEntry',
             'Job',
             'Order',
-            'Fulfillment',
             'PaymentMethod',
             'Product',
             'ProductVariant',

+ 8 - 0
packages/admin-ui/src/lib/core/src/data/definitions/order-definitions.ts

@@ -128,6 +128,14 @@ export const ORDER_DETAIL_FRAGMENT = gql`
         lines {
             ...OrderLine
         }
+        surcharges {
+            id
+            sku
+            description
+            price
+            priceWithTax
+            taxRate
+        }
         discounts {
             ...Adjustment
         }

+ 155 - 139
packages/admin-ui/src/lib/order/src/components/order-detail/order-detail.component.html

@@ -94,157 +94,173 @@
                     </tr>
                 </thead>
                 <tbody>
-                <tr
-                    *ngFor="let line of order.lines"
-                    class="order-line"
-                    [class.is-cancelled]="line.quantity === 0"
-                >
-                    <td class="align-middle thumb">
-                        <img *ngIf="line.featuredAsset" [src]="line.featuredAsset | assetPreview: 'tiny'" />
-                    </td>
-                    <td class="align-middle name">{{ line.productVariant.name }}</td>
-                    <td class="align-middle sku">{{ line.productVariant.sku }}</td>
-                    <td class="align-middle unit-price">
-                        {{ line.unitPriceWithTax / 100 | currency: order.currencyCode }}
-                        <div class="net-price" [title]="'order.net-price' | translate">
-                            {{ line.unitPrice / 100 | currency: order.currencyCode }}
-                        </div>
-                    </td>
-                    <td class="align-middle quantity">
-                        {{ line.quantity }}
-                        <vdr-line-refunds [line]="line"></vdr-line-refunds>
-                        <vdr-line-fulfillment [line]="line" [orderState]="order.state"></vdr-line-fulfillment>
-                    </td>
-                    <ng-container *ngFor="let customField of visibleOrderLineCustomFields">
-                        <td class="order-line-custom-field align-middle">
-                            <ng-container [ngSwitch]="customField.type">
-                                <ng-template [ngSwitchCase]="'datetime'">
-                                    <span [title]="line.customFields[customField.name]">{{
-                                        line.customFields[customField.name] | date: 'short'
-                                    }}</span>
-                                </ng-template>
-                                <ng-template [ngSwitchCase]="'boolean'">
-                                    <ng-template [ngIf]="line.customFields[customField.name] === true">
-                                        <clr-icon shape="check"></clr-icon>
+                    <tr
+                        *ngFor="let line of order.lines"
+                        class="order-line"
+                        [class.is-cancelled]="line.quantity === 0"
+                    >
+                        <td class="align-middle thumb">
+                            <img
+                                *ngIf="line.featuredAsset"
+                                [src]="line.featuredAsset | assetPreview: 'tiny'"
+                            />
+                        </td>
+                        <td class="align-middle name">{{ line.productVariant.name }}</td>
+                        <td class="align-middle sku">{{ line.productVariant.sku }}</td>
+                        <td class="align-middle unit-price">
+                            {{ line.unitPriceWithTax / 100 | currency: order.currencyCode }}
+                            <div class="net-price" [title]="'order.net-price' | translate">
+                                {{ line.unitPrice / 100 | currency: order.currencyCode }}
+                            </div>
+                        </td>
+                        <td class="align-middle quantity">
+                            {{ line.quantity }}
+                            <vdr-line-refunds [line]="line"></vdr-line-refunds>
+                            <vdr-line-fulfillment
+                                [line]="line"
+                                [orderState]="order.state"
+                            ></vdr-line-fulfillment>
+                        </td>
+                        <ng-container *ngFor="let customField of visibleOrderLineCustomFields">
+                            <td class="order-line-custom-field align-middle">
+                                <ng-container [ngSwitch]="customField.type">
+                                    <ng-template [ngSwitchCase]="'datetime'">
+                                        <span [title]="line.customFields[customField.name]">{{
+                                            line.customFields[customField.name] | date: 'short'
+                                        }}</span>
                                     </ng-template>
-                                    <ng-template [ngIf]="line.customFields[customField.name] === false">
-                                        <clr-icon shape="times"></clr-icon>
+                                    <ng-template [ngSwitchCase]="'boolean'">
+                                        <ng-template [ngIf]="line.customFields[customField.name] === true">
+                                            <clr-icon shape="check"></clr-icon>
+                                        </ng-template>
+                                        <ng-template [ngIf]="line.customFields[customField.name] === false">
+                                            <clr-icon shape="times"></clr-icon>
+                                        </ng-template>
                                     </ng-template>
-                                </ng-template>
-                                <ng-template ngSwitchDefault>
-                                    {{ line.customFields[customField.name] }}
-                                </ng-template>
-                            </ng-container>
-                        </td>
-                    </ng-container>
-                    <ng-container *ngIf="showElided"
-                        ><td class="order-line-custom-field align-middle">
-                            <clr-icon
-                                shape="ellipsis-horizontal"
-                                class="custom-field-ellipsis"
-                            ></clr-icon></td
-                    ></ng-container>
-                    <td class="align-middle total">
-                        {{ line.linePriceWithTax / 100 | currency: order.currencyCode }}
-                        <div class="net-price" [title]="'order.net-price' | translate">
-                            {{ line.linePrice / 100 | currency: order.currencyCode }}
-                        </div>
+                                    <ng-template ngSwitchDefault>
+                                        {{ line.customFields[customField.name] }}
+                                    </ng-template>
+                                </ng-container>
+                            </td>
+                        </ng-container>
+                        <ng-container *ngIf="showElided"
+                            ><td class="order-line-custom-field align-middle">
+                                <clr-icon
+                                    shape="ellipsis-horizontal"
+                                    class="custom-field-ellipsis"
+                                ></clr-icon></td
+                        ></ng-container>
+                        <td class="align-middle total">
+                            {{ line.linePriceWithTax / 100 | currency: order.currencyCode }}
+                            <div class="net-price" [title]="'order.net-price' | translate">
+                                {{ line.linePrice / 100 | currency: order.currencyCode }}
+                            </div>
 
-                        <ng-container *ngIf="getLineDiscounts(line) as discounts">
-                            <vdr-dropdown *ngIf="discounts.length">
-                                <div class="promotions-label" vdrDropdownTrigger>
-                                    {{ 'order.promotions-applied' | translate }}
-                                </div>
-                                <vdr-dropdown-menu>
-                                    <div
-                                        class="line-promotion"
-                                        *ngFor="let discount of discounts"
-                                    >
-                                        <a
-                                            class="promotion-name"
-                                            [routerLink]="getPromotionLink(discount)"
-                                            >{{ discount.description }}</a
-                                        >
-                                        <div class="promotion-amount">
-                                            {{ discount.amount / 100 | currency: order.currencyCode }}
-                                        </div>
+                            <ng-container *ngIf="getLineDiscounts(line) as discounts">
+                                <vdr-dropdown *ngIf="discounts.length">
+                                    <div class="promotions-label" vdrDropdownTrigger>
+                                        {{ 'order.promotions-applied' | translate }}
                                     </div>
-                                </vdr-dropdown-menu>
-                            </vdr-dropdown>
-                        </ng-container>
-                    </td>
-                </tr>
-                <tr class="order-ajustment" *ngFor="let discount of order.discounts">
-                    <td
-                        [attr.colspan]="5 + visibleOrderLineCustomFields.length"
-                        class="left clr-align-middle"
-                    >
-                        <a [routerLink]="getPromotionLink(discount)">{{ discount.description }}</a>
-                        <vdr-chip *ngIf="getCouponCodeForAdjustment(order, discount) as couponCode">{{
-                            couponCode
-                        }}</vdr-chip>
-                    </td>
-                    <ng-container *ngIf="showElided"><td></td></ng-container>
-                    <td class="clr-align-middle">
-                        {{ discount.amount / 100 | currency: order.currencyCode }}
-                    </td>
-                </tr>
-                <tr class="sub-total">
-                    <td class="left clr-align-middle">{{ 'order.sub-total' | translate }}</td>
-                    <td></td>
-                    <td [attr.colspan]="3 + visibleOrderLineCustomFields.length"></td>
-                    <ng-container *ngIf="showElided"><td></td></ng-container>
-                    <td class="clr-align-middle">
-                        {{ order.subTotalWithTax / 100 | currency: order.currencyCode }}
-                        <div class="net-price" [title]="'order.net-price' | translate">
-                            {{ order.subTotal / 100 | currency: order.currencyCode }}
-                        </div>
-                    </td>
-                </tr>
-                <tr class="shipping">
-                    <td class="left clr-align-middle">{{ 'order.shipping' | translate }}</td>
-                    <td class="clr-align-middle">{{ order.shippingLines[0]?.shippingMethod?.name }}</td>
-                    <td [attr.colspan]="3 + visibleOrderLineCustomFields.length"></td>
-                    <ng-container *ngIf="showElided"><td></td></ng-container>
-                    <td class="clr-align-middle">
-                        {{ order.shippingWithTax / 100 | currency: order.currencyCode }}
-                        <div class="net-price" [title]="'order.net-price' | translate">
-                            {{ order.shipping / 100 | currency: order.currencyCode }}
-                        </div>
-                    </td>
-                </tr>
-                <tr class="total">
-                    <td class="left clr-align-middle">{{ 'order.total' | translate }}</td>
-                    <td></td>
-                    <td [attr.colspan]="3 + visibleOrderLineCustomFields.length"></td>
-                    <ng-container *ngIf="showElided"><td></td></ng-container>
-                    <td class="clr-align-middle">
-                        {{ order.totalWithTax / 100 | currency: order.currencyCode }}
-                        <div class="net-price" [title]="'order.net-price' | translate">
-                            {{ order.total / 100 | currency: order.currencyCode }}
-                        </div>
-                    </td>
-                </tr>
+                                    <vdr-dropdown-menu>
+                                        <div class="line-promotion" *ngFor="let discount of discounts">
+                                            <a
+                                                class="promotion-name"
+                                                [routerLink]="getPromotionLink(discount)"
+                                                >{{ discount.description }}</a
+                                            >
+                                            <div class="promotion-amount">
+                                                {{ discount.amount / 100 | currency: order.currencyCode }}
+                                            </div>
+                                        </div>
+                                    </vdr-dropdown-menu>
+                                </vdr-dropdown>
+                            </ng-container>
+                        </td>
+                    </tr>
+                    <tr class="surcharge" *ngFor="let surcharge of order.surcharges">
+                        <td class="align-middle name left" colspan="2">{{ surcharge.description }}</td>
+                        <td class="align-middle sku">{{ surcharge.sku }}</td>
+                        <td class="align-middle"></td>
+                        <td [attr.colspan]="1 + visibleOrderLineCustomFields.length"></td>
+                        <ng-container *ngIf="showElided"><td></td></ng-container>
+                        <td class="align-middle total">
+                            {{ surcharge.priceWithTax / 100 | currency: order.currencyCode }}
+                            <div class="net-price" [title]="'order.net-price' | translate">
+                                {{ surcharge.price / 100 | currency: order.currencyCode }}
+                            </div>
+                        </td>
+                    </tr>
+                    <tr class="order-adjustment" *ngFor="let discount of order.discounts">
+                        <td
+                            [attr.colspan]="5 + visibleOrderLineCustomFields.length"
+                            class="left clr-align-middle"
+                        >
+                            <a [routerLink]="getPromotionLink(discount)">{{ discount.description }}</a>
+                            <vdr-chip *ngIf="getCouponCodeForAdjustment(order, discount) as couponCode">{{
+                                couponCode
+                            }}</vdr-chip>
+                        </td>
+                        <ng-container *ngIf="showElided"><td></td></ng-container>
+                        <td class="clr-align-middle">
+                            {{ discount.amount / 100 | currency: order.currencyCode }}
+                        </td>
+                    </tr>
+                    <tr class="sub-total">
+                        <td class="left clr-align-middle">{{ 'order.sub-total' | translate }}</td>
+                        <td></td>
+                        <td [attr.colspan]="3 + visibleOrderLineCustomFields.length"></td>
+                        <ng-container *ngIf="showElided"><td></td></ng-container>
+                        <td class="clr-align-middle">
+                            {{ order.subTotalWithTax / 100 | currency: order.currencyCode }}
+                            <div class="net-price" [title]="'order.net-price' | translate">
+                                {{ order.subTotal / 100 | currency: order.currencyCode }}
+                            </div>
+                        </td>
+                    </tr>
+                    <tr class="shipping">
+                        <td class="left clr-align-middle">{{ 'order.shipping' | translate }}</td>
+                        <td class="clr-align-middle">{{ order.shippingLines[0]?.shippingMethod?.name }}</td>
+                        <td [attr.colspan]="3 + visibleOrderLineCustomFields.length"></td>
+                        <ng-container *ngIf="showElided"><td></td></ng-container>
+                        <td class="clr-align-middle">
+                            {{ order.shippingWithTax / 100 | currency: order.currencyCode }}
+                            <div class="net-price" [title]="'order.net-price' | translate">
+                                {{ order.shipping / 100 | currency: order.currencyCode }}
+                            </div>
+                        </td>
+                    </tr>
+                    <tr class="total">
+                        <td class="left clr-align-middle">{{ 'order.total' | translate }}</td>
+                        <td></td>
+                        <td [attr.colspan]="3 + visibleOrderLineCustomFields.length"></td>
+                        <ng-container *ngIf="showElided"><td></td></ng-container>
+                        <td class="clr-align-middle">
+                            {{ order.totalWithTax / 100 | currency: order.currencyCode }}
+                            <div class="net-price" [title]="'order.net-price' | translate">
+                                {{ order.total / 100 | currency: order.currencyCode }}
+                            </div>
+                        </td>
+                    </tr>
                 </tbody>
             </table>
 
             <h4>{{ 'order.tax-summary' | translate }}</h4>
             <table class="table">
                 <thead>
-                <tr>
-                    <th>{{ 'common.description' | translate }}</th>
-                    <th>{{ 'order.tax-rate' | translate }}</th>
-                    <th>{{ 'order.tax-base' | translate }}</th>
-                    <th>{{ 'order.tax-total' | translate }}</th>
-                </tr>
+                    <tr>
+                        <th>{{ 'common.description' | translate }}</th>
+                        <th>{{ 'order.tax-rate' | translate }}</th>
+                        <th>{{ 'order.tax-base' | translate }}</th>
+                        <th>{{ 'order.tax-total' | translate }}</th>
+                    </tr>
                 </thead>
                 <tbody>
-                <tr *ngFor="let row of order.taxSummary">
-                    <td>{{ row.description }}</td>
-                    <td>{{ row.taxRate / 100 | percent }}</td>
-                    <td>{{ row.taxBase / 100 | currency: order.currencyCode }}</td>
-                    <td>{{ row.taxTotal / 100 | currency: order.currencyCode }}</td>
-                </tr>
+                    <tr *ngFor="let row of order.taxSummary">
+                        <td>{{ row.description }}</td>
+                        <td>{{ row.taxRate / 100 | percent }}</td>
+                        <td>{{ row.taxBase / 100 | currency: order.currencyCode }}</td>
+                        <td>{{ row.taxTotal / 100 | currency: order.currencyCode }}</td>
+                    </tr>
                 </tbody>
             </table>
 

+ 12 - 12
packages/asset-server-plugin/e2e/graphql/generated-e2e-asset-server-plugin-types.ts

@@ -1111,6 +1111,18 @@ export type UpdateFacetValueInput = {
     customFields?: Maybe<Scalars['JSON']>;
 };
 
+export type Fulfillment = Node & {
+    nextStates: Array<Scalars['String']>;
+    id: Scalars['ID'];
+    createdAt: Scalars['DateTime'];
+    updatedAt: Scalars['DateTime'];
+    orderItems: Array<OrderItem>;
+    state: Scalars['String'];
+    method: Scalars['String'];
+    trackingCode?: Maybe<Scalars['String']>;
+    customFields?: Maybe<Scalars['JSON']>;
+};
+
 export type UpdateGlobalSettingsInput = {
     availableLanguages?: Maybe<Array<LanguageCode>>;
     trackInventory?: Maybe<Scalars['Boolean']>;
@@ -1281,18 +1293,6 @@ export type OrderHistoryArgs = {
     options?: Maybe<HistoryEntryListOptions>;
 };
 
-export type Fulfillment = Node & {
-    nextStates: Array<Scalars['String']>;
-    id: Scalars['ID'];
-    createdAt: Scalars['DateTime'];
-    updatedAt: Scalars['DateTime'];
-    orderItems: Array<OrderItem>;
-    state: Scalars['String'];
-    method: Scalars['String'];
-    trackingCode?: Maybe<Scalars['String']>;
-    customFields?: Maybe<Scalars['JSON']>;
-};
-
 export type UpdateOrderInput = {
     id: Scalars['ID'];
     customFields?: Maybe<Scalars['JSON']>;

+ 13 - 13
packages/common/src/generated-types.ts

@@ -1256,6 +1256,19 @@ export type UpdateFacetValueInput = {
   customFields?: Maybe<Scalars['JSON']>;
 };
 
+export type Fulfillment = Node & {
+  __typename?: 'Fulfillment';
+  nextStates: Array<Scalars['String']>;
+  id: Scalars['ID'];
+  createdAt: Scalars['DateTime'];
+  updatedAt: Scalars['DateTime'];
+  orderItems: Array<OrderItem>;
+  state: Scalars['String'];
+  method: Scalars['String'];
+  trackingCode?: Maybe<Scalars['String']>;
+  customFields?: Maybe<Scalars['JSON']>;
+};
+
 export type UpdateGlobalSettingsInput = {
   availableLanguages?: Maybe<Array<LanguageCode>>;
   trackInventory?: Maybe<Scalars['Boolean']>;
@@ -1438,19 +1451,6 @@ export type OrderHistoryArgs = {
   options?: Maybe<HistoryEntryListOptions>;
 };
 
-export type Fulfillment = Node & {
-  __typename?: 'Fulfillment';
-  nextStates: Array<Scalars['String']>;
-  id: Scalars['ID'];
-  createdAt: Scalars['DateTime'];
-  updatedAt: Scalars['DateTime'];
-  orderItems: Array<OrderItem>;
-  state: Scalars['String'];
-  method: Scalars['String'];
-  trackingCode?: Maybe<Scalars['String']>;
-  customFields?: Maybe<Scalars['JSON']>;
-};
-
 export type UpdateOrderInput = {
   id: Scalars['ID'];
   customFields?: Maybe<Scalars['JSON']>;

+ 12 - 12
packages/core/e2e/graphql/generated-e2e-admin-types.ts

@@ -1111,6 +1111,18 @@ export type UpdateFacetValueInput = {
     customFields?: Maybe<Scalars['JSON']>;
 };
 
+export type Fulfillment = Node & {
+    nextStates: Array<Scalars['String']>;
+    id: Scalars['ID'];
+    createdAt: Scalars['DateTime'];
+    updatedAt: Scalars['DateTime'];
+    orderItems: Array<OrderItem>;
+    state: Scalars['String'];
+    method: Scalars['String'];
+    trackingCode?: Maybe<Scalars['String']>;
+    customFields?: Maybe<Scalars['JSON']>;
+};
+
 export type UpdateGlobalSettingsInput = {
     availableLanguages?: Maybe<Array<LanguageCode>>;
     trackInventory?: Maybe<Scalars['Boolean']>;
@@ -1281,18 +1293,6 @@ export type OrderHistoryArgs = {
     options?: Maybe<HistoryEntryListOptions>;
 };
 
-export type Fulfillment = Node & {
-    nextStates: Array<Scalars['String']>;
-    id: Scalars['ID'];
-    createdAt: Scalars['DateTime'];
-    updatedAt: Scalars['DateTime'];
-    orderItems: Array<OrderItem>;
-    state: Scalars['String'];
-    method: Scalars['String'];
-    trackingCode?: Maybe<Scalars['String']>;
-    customFields?: Maybe<Scalars['JSON']>;
-};
-
 export type UpdateOrderInput = {
     id: Scalars['ID'];
     customFields?: Maybe<Scalars['JSON']>;

+ 33 - 42
packages/dev-server/dev-config.ts

@@ -2,7 +2,9 @@
 import { AdminUiPlugin } from '@vendure/admin-ui-plugin';
 import { AssetServerPlugin } from '@vendure/asset-server-plugin';
 import { ADMIN_API_PATH, API_PORT, SHOP_API_PATH } from '@vendure/common/lib/shared-constants';
+import { Order, OrderService, OrderState, TransactionalConnection } from '@vendure/core';
 import {
+    CustomOrderProcess,
     DefaultJobQueuePlugin,
     DefaultLogger,
     DefaultSearchPlugin,
@@ -13,6 +15,7 @@ import {
     LogLevel,
     manualFulfillmentHandler,
     PermissionDefinition,
+    Surcharge,
     VendureConfig,
 } from '@vendure/core';
 import { ElasticsearchPlugin } from '@vendure/elasticsearch-plugin';
@@ -20,49 +23,29 @@ import { defaultEmailHandlers, EmailPlugin } from '@vendure/email-plugin';
 import path from 'path';
 import { ConnectionOptions } from 'typeorm';
 
-const customFulfillmentHandler = new FulfillmentHandler({
-    code: 'ship-o-matic',
-    description: [
-        {
-            languageCode: LanguageCode.en,
-            value: 'Generate tracking codes via the Ship-o-matic API',
-        },
-    ],
-    args: {
-        preferredService: {
-            type: 'string',
-            ui: {
-                component: 'select-form-input',
-                options: [{ value: 'first_class' }, { value: 'priority' }, { value: 'standard' }],
-            },
-        },
-    },
-    createFulfillment: async (ctx, orders, orderItems, args) => {
-        return {
-            method: `Ship-o-matic ${args.preferredService}`,
-            trackingCode: 'SHIP-' + Math.random().toString(36).substr(3),
-        };
-    },
-    onFulfillmentTransition: async (fromState, toState, { fulfillment }) => {
-        Logger.info(`Transitioned Fulfillment ${fulfillment.trackingCode} to state ${toState}`);
+let connection: TransactionalConnection;
+let orderService: OrderService;
+const customerValidationProcess: CustomOrderProcess<OrderState> = {
+    // The init method allows us to inject services
+    // and other providers
+    init(injector) {
+        connection = injector.get(TransactionalConnection);
+        orderService = injector.get(OrderService);
     },
-});
 
-const pickupFulfillmentHandler = new FulfillmentHandler({
-    code: 'customer-collect',
-    description: [
-        {
-            languageCode: LanguageCode.en,
-            value: 'Customer collect fulfillment',
-        },
-    ],
-    args: {},
-    createFulfillment: async (ctx, orders, orderItems, args) => {
-        return {
-            method: `Customer collect`,
-        };
+    // The logic for enforcing our validation goes here
+    async onTransitionStart(fromState, toState, data) {
+        if (fromState === 'AddingItems' && toState === 'ArrangingPayment') {
+            const { ctx, order } = data;
+            await orderService.addSurchargeToOrder(ctx, order.id, {
+                description: '3% payment surcharge',
+                sku: 'PAYMENT_SURCHARGE',
+                listPrice: Math.round(order.subTotal * 0.03),
+                listPriceIncludesTax: ctx.channel.pricesIncludeTax,
+            });
+        }
     },
-});
+};
 
 /**
  * Config settings used during development
@@ -92,6 +75,9 @@ export const devConfig: VendureConfig = {
         requireVerification: true,
         customPermissions: [],
     },
+    orderOptions: {
+        process: [customerValidationProcess],
+    },
     dbConnectionOptions: {
         synchronize: false,
         logging: false,
@@ -101,13 +87,18 @@ export const devConfig: VendureConfig = {
     paymentOptions: {
         paymentMethodHandlers: [examplePaymentHandler],
     },
-    customFields: {},
+    customFields: {
+        OrderLine: [
+            { name: 'test', type: 'string', nullable: true },
+            { name: 'test2', type: 'string', nullable: true },
+        ],
+    },
     logger: new DefaultLogger({ level: LogLevel.Info }),
     importExportOptions: {
         importAssetsDir: path.join(__dirname, 'import-assets'),
     },
     shippingOptions: {
-        fulfillmentHandlers: [manualFulfillmentHandler, customFulfillmentHandler, pickupFulfillmentHandler],
+        fulfillmentHandlers: [manualFulfillmentHandler],
     },
     plugins: [
         AssetServerPlugin.init({

+ 12 - 12
packages/elasticsearch-plugin/e2e/graphql/generated-e2e-elasticsearch-plugin-types.ts

@@ -1111,6 +1111,18 @@ export type UpdateFacetValueInput = {
     customFields?: Maybe<Scalars['JSON']>;
 };
 
+export type Fulfillment = Node & {
+    nextStates: Array<Scalars['String']>;
+    id: Scalars['ID'];
+    createdAt: Scalars['DateTime'];
+    updatedAt: Scalars['DateTime'];
+    orderItems: Array<OrderItem>;
+    state: Scalars['String'];
+    method: Scalars['String'];
+    trackingCode?: Maybe<Scalars['String']>;
+    customFields?: Maybe<Scalars['JSON']>;
+};
+
 export type UpdateGlobalSettingsInput = {
     availableLanguages?: Maybe<Array<LanguageCode>>;
     trackInventory?: Maybe<Scalars['Boolean']>;
@@ -1281,18 +1293,6 @@ export type OrderHistoryArgs = {
     options?: Maybe<HistoryEntryListOptions>;
 };
 
-export type Fulfillment = Node & {
-    nextStates: Array<Scalars['String']>;
-    id: Scalars['ID'];
-    createdAt: Scalars['DateTime'];
-    updatedAt: Scalars['DateTime'];
-    orderItems: Array<OrderItem>;
-    state: Scalars['String'];
-    method: Scalars['String'];
-    trackingCode?: Maybe<Scalars['String']>;
-    customFields?: Maybe<Scalars['JSON']>;
-};
-
 export type UpdateOrderInput = {
     id: Scalars['ID'];
     customFields?: Maybe<Scalars['JSON']>;

Diferenças do arquivo suprimidas por serem muito extensas
+ 0 - 0
schema-admin.json


Alguns arquivos não foram mostrados porque muitos arquivos mudaram nesse diff