Browse Source

feat(admin-ui): Allow OrderLine customFields to be modified

Relates to #314
Michael Bromley 5 years ago
parent
commit
e89845ec77

+ 4 - 0
packages/admin-ui/src/lib/core/src/shared/components/product-selector/product-selector.component.scss

@@ -1,5 +1,9 @@
 @import "variables";
 
+:host {
+    display: block;
+}
+
 .sku {
     margin-left: 12px;
     color: $color-grey-500;

+ 2 - 0
packages/admin-ui/src/lib/order/src/components/order-detail/order-detail.component.ts

@@ -55,6 +55,8 @@ export class OrderDetailComponent
         'ArrangingPayment',
         'PaymentAuthorized',
         'PaymentSettled',
+        'PartiallyShipped',
+        'Shipped',
         'PartiallyDelivered',
         'Delivered',
         'Cancelled',

+ 55 - 16
packages/admin-ui/src/lib/order/src/components/order-editor/order-editor.component.html

@@ -65,10 +65,11 @@
                         </td>
                         <td *ngIf="orderLineCustomFields.length" class="order-line-custom-field align-middle">
                             <ng-container *ngFor="let customField of orderLineCustomFields">
-                                <vdr-custom-field-control [customField]="customField"
-                                                          [customFieldsFormGroup]="orderLineCustomFieldsForm.get([i])"
-                                                          entityName="OrderLine"
-                                                          [compact]="true"
+                                <vdr-custom-field-control
+                                    [customField]="customField"
+                                    [customFieldsFormGroup]="orderLineCustomFieldsFormArray.get([i])"
+                                    entityName="OrderLine"
+                                    [compact]="true"
                                 ></vdr-custom-field-control>
                             </ng-container>
                         </td>
@@ -80,7 +81,7 @@
                         </td>
                     </tr>
                     <tr
-                        *ngFor="let addedLine of addedLines; trackBy: trackByProductVariantId"
+                        *ngFor="let addedLine of addedLines; trackBy: trackByProductVariantId; let i = index"
                         class="modified"
                     >
                         <td class="align-middle thumb">
@@ -105,16 +106,22 @@
                                 [value]="addedLine.quantity"
                                 (input)="updateAddedItemQuantity(addedLine, $event.target.value)"
                             />
-                            <button class="icon-button" (click)="removeAddedItem(addedLine.productVariantId)">
+                            <button class="icon-button" (click)="removeAddedItem(i)">
                                 <clr-icon shape="trash"></clr-icon>
                             </button>
                         </td>
-                        <td *ngIf="orderLineCustomFields.length" class="order-line-custom-field align-middle">
-                            <!--  <ng-container *ngFor="let customField of orderLineCustomFields">
-                        <vdr-labeled-data [label]="customField | customFieldLabel">{{
-                            line.customFields[customField.name] || '-'
-                        }}</vdr-labeled-data>
-                    </ng-container>-->
+                        <td
+                            *ngIf="orderLineCustomFields.length"
+                            class="order-line-custom-field align-middle"
+                        >
+                            <ng-container *ngFor="let customField of orderLineCustomFields">
+                                <vdr-custom-field-control
+                                    [customField]="customField"
+                                    [customFieldsFormGroup]="addItemCustomFieldsFormArray.get([i])"
+                                    entityName="OrderLine"
+                                    [compact]="true"
+                                ></vdr-custom-field-control>
+                            </ng-container>
                         </td>
                         <td class="align-middle total">
                             {{
@@ -185,8 +192,33 @@
                 <clr-accordion-panel>
                     <clr-accordion-title>{{ 'order.add-item-to-order' | translate }}</clr-accordion-title>
                     <clr-accordion-content *clrIfExpanded>
-                        <vdr-product-selector (productSelected)="addItemToOrder($event)">
+                        <vdr-product-selector class="mb4" (productSelected)="addItemSelectedVariant = $event">
                         </vdr-product-selector>
+                        <div *ngIf="addItemSelectedVariant" class="flex mb4">
+                            <img [src]="addItemSelectedVariant.productAsset | assetPreview: 'tiny'" class="mr4" />
+                            <div>
+                                <strong class="mr4">{{ addItemSelectedVariant.productVariantName }}</strong>
+                                <small>{{ addItemSelectedVariant.sku }}</small>
+                                <div>{{ (addItemSelectedVariant.priceWithTax.value / 100) | currency: order.currencyCode }}</div>
+                            </div>
+
+                        </div>
+                        <ng-container *ngFor="let customField of orderLineCustomFields">
+                            <vdr-custom-field-control
+                                [readonly]="!addItemSelectedVariant"
+                                [customField]="customField"
+                                [customFieldsFormGroup]="addItemCustomFieldsForm"
+                                entityName="OrderLine"
+                                [compact]="true"
+                            ></vdr-custom-field-control>
+                        </ng-container>
+                        <button
+                            class="btn btn-secondary"
+                            [disabled]="!addItemSelectedVariant || addItemCustomFieldsForm.invalid"
+                            (click)="addItemToOrder(addItemSelectedVariant)"
+                        >
+                            {{ 'order.add-item-to-order' | translate }}
+                        </button>
                     </clr-accordion-content>
                 </clr-accordion-panel>
 
@@ -212,7 +244,10 @@
                                 ></vdr-currency-input
                             ></vdr-form-field>
                             <vdr-form-field
-                                [label]="'catalog.price-includes-tax-at' | translate: { rate: surchargeForm.get('taxRate')?.value }"
+                                [label]="
+                                    'catalog.price-includes-tax-at'
+                                        | translate: { rate: surchargeForm.get('taxRate')?.value }
+                                "
                                 for="priceIncludesTax"
                                 ><input
                                     id="priceIncludesTax"
@@ -239,7 +274,7 @@
                             /></vdr-form-field>
                             <button
                                 class="btn btn-secondary"
-                                [disabled]="surchargeForm.invalid || surchargeForm.pristine"
+                                [disabled]="surchargeForm.invalid || surchargeForm.pristine || surchargeForm.get('price')?.value === 0"
                             >
                                 {{ 'order.add-surcharge' | translate }}
                             </button>
@@ -310,7 +345,11 @@
                     </clr-checkbox-wrapper>
                 </div>
                 <div class="card-footer">
-                    <button class="btn btn-primary" [disabled]="!canPreviewChanges()" (click)="previewAndModify(order)">
+                    <button
+                        class="btn btn-primary"
+                        [disabled]="!canPreviewChanges()"
+                        (click)="previewAndModify(order)"
+                    >
                         {{ 'order.preview-changes' | translate }}
                     </button>
                 </div>

+ 45 - 8
packages/admin-ui/src/lib/order/src/components/order-editor/order-editor.component.ts

@@ -57,7 +57,10 @@ export class OrderEditorComponent
     availableCountries$: Observable<GetAvailableCountries.Items[]>;
     addressCustomFields: CustomFieldConfig[];
     detailForm = new FormGroup({});
-    orderLineCustomFieldsForm: FormArray;
+    orderLineCustomFieldsFormArray: FormArray;
+    addItemCustomFieldsFormArray: FormArray;
+    addItemCustomFieldsForm: FormGroup;
+    addItemSelectedVariant: ProductSelectorSearch.Items | undefined;
     orderLineCustomFields: CustomFieldConfig[];
     modifyOrderInput: ModifyOrderData = {
         dryRun: true,
@@ -143,7 +146,7 @@ export class OrderEditorComponent
                 countryCode: new FormControl(order.billingAddress?.countryCode),
                 phoneNumber: new FormControl(order.billingAddress?.phoneNumber),
             });
-            this.orderLineCustomFieldsForm = new FormArray([]);
+            this.orderLineCustomFieldsFormArray = new FormArray([]);
             for (const line of order.lines) {
                 const formGroup = new FormGroup({});
                 for (const { name } of this.orderLineCustomFields) {
@@ -162,9 +165,14 @@ export class OrderEditorComponent
                     }
                     modifyRow.customFields = value;
                 });
-                this.orderLineCustomFieldsForm.push(formGroup);
+                this.orderLineCustomFieldsFormArray.push(formGroup);
             }
         });
+        this.addItemCustomFieldsFormArray = new FormArray([]);
+        this.addItemCustomFieldsForm = new FormGroup({});
+        for (const customField of this.orderLineCustomFields) {
+            this.addItemCustomFieldsForm.addControl(customField.name, new FormControl());
+        }
         this.availableCountries$ = this.dataService.settings
             .getAvailableCountries()
             .mapSingle(result => result.countries.items)
@@ -243,22 +251,51 @@ export class OrderEditorComponent
     }
 
     addItemToOrder(result: ProductSelectorSearch.Items) {
-        let row = this.modifyOrderInput.addItems?.find(l => l.productVariantId === result.productVariantId);
+        const customFields = this.addItemCustomFieldsForm.value;
+        let row = this.modifyOrderInput.addItems?.find(l =>
+            this.isMatchingAddItemRow(l, result, customFields),
+        );
         if (!row) {
-            row = { productVariantId: result.productVariantId, quantity: 1 };
+            row = { productVariantId: result.productVariantId, quantity: 1, customFields };
             this.modifyOrderInput.addItems?.push(row);
         } else {
             row.quantity++;
         }
+        if (customFields) {
+            const formGroup = new FormGroup({});
+            for (const [key, value] of Object.entries(customFields)) {
+                formGroup.addControl(key, new FormControl(value));
+            }
+            this.addItemCustomFieldsFormArray.push(formGroup);
+            formGroup.valueChanges.pipe(takeUntil(this.destroy$)).subscribe(value => {
+                if (row) {
+                    row.customFields = value;
+                }
+            });
+        }
+        this.addItemCustomFieldsForm.reset({});
+        this.addItemSelectedVariant = undefined;
         this.addedVariants.set(result.productVariantId, result);
     }
 
-    removeAddedItem(productVariantId: string) {
-        this.modifyOrderInput.addItems = this.modifyOrderInput.addItems?.filter(
-            l => l.productVariantId !== productVariantId,
+    private isMatchingAddItemRow(
+        row: ModifyOrderData['addItems'][number],
+        result: ProductSelectorSearch.Items,
+        customFields: any,
+    ): boolean {
+        return (
+            row.productVariantId === result.productVariantId &&
+            JSON.stringify(row.customFields) === JSON.stringify(customFields)
         );
     }
 
+    removeAddedItem(index: number) {
+        this.modifyOrderInput.addItems.splice(index, 1);
+        if (-1 < index) {
+            this.addItemCustomFieldsFormArray.removeAt(index);
+        }
+    }
+
     getSurchargePrices(surcharge: SurchargeInput) {
         const priceWithTax = surcharge.priceIncludesTax
             ? surcharge.price