Browse Source

feat(admin-ui): Account for stockOnHand when creating Fulfillments

Relates to #319
Michael Bromley 5 years ago
parent
commit
540d2c6752

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

@@ -1276,7 +1276,7 @@ export type UpdateGlobalSettingsResult = GlobalSettings | ChannelDefaultLanguage
 /**
  * @description
  * The state of a Job in the JobQueue
- * 
+ *
  * @docsCategory common
  */
 export enum JobState {
@@ -2181,7 +2181,7 @@ export type EmailAddressConflictError = ErrorResult & {
 /**
  * @description
  * ISO 4217 currency code
- * 
+ *
  * @docsCategory common
  */
 export enum CurrencyCode {
@@ -2615,7 +2615,7 @@ export type CustomFieldConfig = StringCustomFieldConfig | LocaleStringCustomFiel
  * region or script modifier (e.g. de_AT). The selection available is based
  * on the [Unicode CLDR summary list](https://unicode-org.github.io/cldr-staging/charts/37/summary/root.html)
  * and includes the major spoken languages of the world and any widely-used variants.
- * 
+ *
  * @docsCategory common
  */
 export enum LanguageCode {
@@ -2940,7 +2940,7 @@ export enum LanguageCode {
  * @description
  * Permissions for administrators and customers. Used to control access to
  * GraphQL resolvers via the {@link Allow} decorator.
- * 
+ *
  * @docsCategory common
  */
 export enum Permission {
@@ -5012,7 +5012,7 @@ export type OrderLineFragment = (
     & Pick<Asset, 'preview'>
   )>, productVariant: (
     { __typename?: 'ProductVariant' }
-    & Pick<ProductVariant, 'id' | 'name' | 'sku'>
+    & Pick<ProductVariant, 'id' | 'name' | 'sku' | 'trackInventory' | 'stockOnHand'>
   ), adjustments: Array<(
     { __typename?: 'Adjustment' }
     & AdjustmentFragment

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

@@ -77,6 +77,8 @@ export const ORDER_LINE_FRAGMENT = gql`
             id
             name
             sku
+            trackInventory
+            stockOnHand
         }
         adjustments {
             ...Adjustment

+ 5 - 2
packages/admin-ui/src/lib/order/src/components/fulfill-order-dialog/fulfill-order-dialog.component.html

@@ -9,6 +9,7 @@
                     <th>{{ 'order.product-name' | translate }}</th>
                     <th>{{ 'order.product-sku' | translate }}</th>
                     <th>{{ 'order.unfulfilled' | translate }}</th>
+                    <th>{{ 'catalog.stock-on-hand' | translate }}</th>
                     <th>{{ 'order.fulfill' | translate }}</th>
                 </tr>
             </thead>
@@ -23,12 +24,14 @@
                 <td class="align-middle name">{{ line.productVariant.name }}</td>
                 <td class="align-middle sku">{{ line.productVariant.sku }}</td>
                 <td class="align-middle quantity">{{ getUnfulfilledCount(line) }}</td>
+                <td class="align-middle quantity">{{ line.productVariant.stockOnHand }}</td>
                 <td class="align-middle fulfil">
                     <input
+                        *ngIf="fulfillmentQuantities[line.id]"
                         [disabled]="getUnfulfilledCount(line) === 0"
-                        [(ngModel)]="fulfillmentQuantities[line.id]"
+                        [(ngModel)]="fulfillmentQuantities[line.id].fulfillCount"
                         type="number"
-                        [max]="line.quantity"
+                        [max]="fulfillmentQuantities[line.id].max"
                         min="0"
                     />
                 </td>

+ 36 - 13
packages/admin-ui/src/lib/order/src/components/fulfill-order-dialog/fulfill-order-dialog.component.ts

@@ -1,7 +1,14 @@
-import { ChangeDetectionStrategy, Component, OnInit } from '@angular/core';
-
-import { FulfillOrderInput, OrderDetail, OrderDetailFragment } from '@vendure/admin-ui/core';
-import { Dialog } from '@vendure/admin-ui/core';
+import { ChangeDetectionStrategy, ChangeDetectorRef, Component, OnInit } from '@angular/core';
+import {
+    DataService,
+    Dialog,
+    FulfillOrderInput,
+    GlobalFlag,
+    OrderDetail,
+    OrderDetailFragment,
+} from '@vendure/admin-ui/core';
+import { Observable } from 'rxjs';
+import { map } from 'rxjs/operators';
 
 @Component({
     selector: 'vdr-fulfill-order-dialog',
@@ -14,29 +21,45 @@ export class FulfillOrderDialogComponent implements Dialog<FulfillOrderInput>, O
     resolveWith: (result?: FulfillOrderInput) => void;
     method = '';
     trackingCode = '';
-    fulfillmentQuantities: { [lineId: string]: number } = {};
+    fulfillmentQuantities: { [lineId: string]: { fulfillCount: number; max: number } } = {};
+
+    constructor(private dataService: DataService, private changeDetector: ChangeDetectorRef) {}
 
     ngOnInit(): void {
-        this.fulfillmentQuantities = this.order.lines.reduce((result, line) => {
-            return {
-                ...result,
-                [line.id]: this.getUnfulfilledCount(line),
-            };
-        }, {});
+        this.dataService.settings.getGlobalSettings().single$.subscribe(({ globalSettings }) => {
+            this.fulfillmentQuantities = this.order.lines.reduce((result, line) => {
+                const fulfillCount = this.getFulfillableCount(line, globalSettings.trackInventory);
+                return {
+                    ...result,
+                    [line.id]: { fulfillCount, max: fulfillCount },
+                };
+            }, {});
+            this.changeDetector.markForCheck();
+        });
+
         if (this.order.shippingMethod) {
             this.method = this.order.shippingMethod.description;
         }
     }
 
+    getFulfillableCount(line: OrderDetail.Lines, globalTrackInventory: boolean): number {
+        const { trackInventory, stockOnHand } = line.productVariant;
+        const effectiveTracInventory =
+            trackInventory === GlobalFlag.INHERIT ? globalTrackInventory : trackInventory === GlobalFlag.TRUE;
+
+        const unfulfilledCount = this.getUnfulfilledCount(line);
+        return effectiveTracInventory ? Math.min(unfulfilledCount, stockOnHand) : unfulfilledCount;
+    }
+
     getUnfulfilledCount(line: OrderDetail.Lines): number {
         const fulfilled = line.items.reduce((sum, item) => sum + (item.fulfillment ? 1 : 0), 0);
         return line.quantity - fulfilled;
     }
 
     select() {
-        const lines = Object.entries(this.fulfillmentQuantities).map(([orderLineId, quantity]) => ({
+        const lines = Object.entries(this.fulfillmentQuantities).map(([orderLineId, { fulfillCount }]) => ({
             orderLineId,
-            quantity,
+            quantity: fulfillCount,
         }));
         this.resolveWith({
             lines,