From 97ef2ae448fca4bccd4d14a3e8758c79d818850e Mon Sep 17 00:00:00 2001
From: Bello Babakolo <fleetbeekay@gmail.com>
Date: Thu, 29 Aug 2024 16:58:24 +0100
Subject: [PATCH] feat: implement add new item order on the server

---
 packages/modules/order/src/index.ts           |   1 +
 .../lib/components/order-edit.component.ts    | 135 +-----------------
 .../lib/components/order-view.component.ts    |   8 +-
 .../order-item/order-item-form.component.ts   |  43 +++++-
 packages/modules/order/src/lib/utils/index.ts |   1 +
 .../order/src/lib/utils/order.utils.ts        | 133 +++++++++++++++++
 6 files changed, 181 insertions(+), 140 deletions(-)
 create mode 100644 packages/modules/order/src/lib/utils/index.ts
 create mode 100644 packages/modules/order/src/lib/utils/order.utils.ts

diff --git a/packages/modules/order/src/index.ts b/packages/modules/order/src/index.ts
index a1fc86ab..876f1043 100644
--- a/packages/modules/order/src/index.ts
+++ b/packages/modules/order/src/index.ts
@@ -1,2 +1,3 @@
 export * from './lib/modules-order.module';
 export * from './lib/lib.routes';
+export * from './lib/utils';
diff --git a/packages/modules/order/src/lib/components/order-edit.component.ts b/packages/modules/order/src/lib/components/order-edit.component.ts
index 4b1b485a..1fedb2cd 100644
--- a/packages/modules/order/src/lib/components/order-edit.component.ts
+++ b/packages/modules/order/src/lib/components/order-edit.component.ts
@@ -11,13 +11,7 @@ import { map, tap } from 'rxjs/operators';
 import { VCLFormFieldSchemaRoot } from '@vcl/ng-vcl';
 
 import { ROUTER } from '@console-core/config';
-import {
-  IIoRestorecommerceOrderItem,
-  IIoRestorecommerceOrderOrder,
-  IoRestorecommerceAmountAmount,
-  IoRestorecommerceOrderItem,
-  ModeType,
-} from '@console-core/graphql';
+import { ModeType } from '@console-core/graphql';
 import {
   OrderFacade,
   RouterFacade,
@@ -26,132 +20,7 @@ import {
 import { IOrder } from '@console-core/types';
 
 import { buildOrderSchema } from '../jss-forms';
-
-export const transformOrderToInput = (
-  order: IOrder
-): IIoRestorecommerceOrderOrder => {
-  const inputItems: IIoRestorecommerceOrderItem[] = order.items
-    ? order.items.map(
-        (item: IoRestorecommerceOrderItem): IIoRestorecommerceOrderItem => {
-          return {
-            // id: item.id,
-            productId: item.productId,
-            variantId: item.variantId,
-            parentItemId: item.parentItemId,
-            quantity: item.quantity,
-            unitPrice: {
-              regularPrice: item.unitPrice?.regularPrice,
-              sale: item.unitPrice?.sale,
-              salePrice: item.unitPrice?.salePrice,
-              currencyId: item.unitPrice?.currencyId,
-            },
-          };
-        }
-      )
-    : [];
-
-  const totalAmounts = order.totalAmounts
-    ? order.totalAmounts.map((orderAmount): IoRestorecommerceAmountAmount => {
-        return {
-          gross: orderAmount.gross,
-          net: orderAmount.net,
-          currencyId: orderAmount.currencyId,
-        };
-      })
-    : [];
-
-  return {
-    id: order.id,
-    shopId: order.shopId,
-    notificationEmail: order.notificationEmail,
-    orderState: order.orderState,
-    customerType: order.customerType,
-    customerVatId: order.customerVatId,
-    paymentMethodId: order.paymentMethodId,
-    shippingAddress: {
-      address: {
-        // id: order.shippingAddress?.address?.id,
-        locality: order.shippingAddress?.address?.locality,
-        street: order.shippingAddress?.address?.street,
-        region: order.shippingAddress?.address?.region,
-        countryId: order.shippingAddress?.address?.countryId,
-        buildingNumber: order.shippingAddress?.address?.buildingNumber,
-        postcode: order.shippingAddress?.address?.postcode,
-        // altitude: null,
-        // addressAddition: {
-        //   field1: '',
-        //   field2: '',
-        // },
-        // businessAddress: {
-        //   name: order.shippingAddress?.address?.businessAddress?.name,
-        // },
-        // residentialAddress: {
-        //   title: null,
-        //   givenName: null,
-        //   midName: null,
-        //   familyName: null,
-        // },
-        // geoCoordinates: {
-        //   latitude: null,
-        //   longitude: null,
-        // },
-        // packStation: {
-        //   provider: null,
-        //   stationNumber: null,
-        //   postNumber: null,
-        // },
-      },
-      contact: {
-        name: null,
-        email: null,
-        phone: null,
-      },
-      // comments: null,
-    },
-    billingAddress: {
-      address: {
-        // id: order.billingAddress?.address?.id,
-        postcode: order.billingAddress?.address?.postcode,
-        countryId: order.billingAddress?.address?.countryId,
-        locality: order.billingAddress?.address?.locality,
-        street: order.billingAddress?.address?.street,
-        region: order.billingAddress?.address?.region,
-        // altitude: null,
-        buildingNumber: order.billingAddress?.address?.buildingNumber,
-        // geoCoordinates: {
-        //   latitude: null,
-        //   longitude: null,
-        // },
-        // addressAddition: {
-        //   field1: '',
-        //   field2: '',
-        // },
-        // businessAddress: {
-        //   name: order.billingAddress?.address?.businessAddress?.name,
-        // },
-        // residentialAddress: {
-        //   title: null,
-        //   givenName: null,
-        //   midName: null,
-        //   familyName: null,
-        // },
-        // packStation: {
-        //   provider: null,
-        //   stationNumber: null,
-        //   postNumber: null,
-        // },
-      },
-      contact: {
-        name: null,
-        email: null,
-        phone: null,
-      },
-      // comments: null,
-    },
-    totalAmounts: [...totalAmounts],
-    items: [...inputItems],
-  };
-};
+import { transformOrderToInput } from '../utils';
 
 @Component({
   selector: 'app-module-order-edit',
diff --git a/packages/modules/order/src/lib/components/order-view.component.ts b/packages/modules/order/src/lib/components/order-view.component.ts
index 8acaf6f1..b2e949ab 100644
--- a/packages/modules/order/src/lib/components/order-view.component.ts
+++ b/packages/modules/order/src/lib/components/order-view.component.ts
@@ -17,6 +17,7 @@ import {
   RouterFacade,
   filterEmptyAndNullishAndUndefined,
 } from '@console-core/state';
+import { IOrder, IProduct } from '@console-core/types';
 
 import { OrderItemFormComponent } from '../modals/order-item/order-item-form.component';
 
@@ -26,7 +27,7 @@ import { OrderItemFormComponent } from '../modals/order-item/order-item-form.com
     <ng-container *ngIf="vm$ | async as vm">
       <rc-order-view
         [order]="vm.order"
-        (openAddItemModal)="onAddOrder()"
+        (openAddItemModal)="onAddOrder(vm.order, vm.products)"
       />
     </ng-container>
   `,
@@ -77,11 +78,12 @@ export class OrderViewComponent implements OnInit, OnDestroy {
     this.addItemLayer?.destroy();
   }
 
-  onAddOrder() {
+  onAddOrder(order: IOrder, products: IProduct[]) {
     this.addItemLayer
       .open({
         data: {
-          products: [], //this.products,
+          order,
+          products,
         },
       })
       .subscribe((result) => {
diff --git a/packages/modules/order/src/lib/modals/order-item/order-item-form.component.ts b/packages/modules/order/src/lib/modals/order-item/order-item-form.component.ts
index 5f5e6b5e..048a9e57 100644
--- a/packages/modules/order/src/lib/modals/order-item/order-item-form.component.ts
+++ b/packages/modules/order/src/lib/modals/order-item/order-item-form.component.ts
@@ -9,8 +9,15 @@ import { SubSink } from 'subsink';
 
 import { ComponentLayerRef } from '@vcl/ng-vcl';
 
-import { IoRestorecommerceProductPhysicalVariant } from '@console-core/graphql';
-import { IProduct } from '@console-core/types';
+import {
+  IIoRestorecommerceOrderOrder,
+  IoRestorecommerceProductPhysicalVariant,
+  ModeType,
+} from '@console-core/graphql';
+import { OrderFacade } from '@console-core/state';
+import { IOrder, IProduct } from '@console-core/types';
+
+import { transformOrderToInput } from '../../utils';
 
 @Component({
   selector: 'app-order-item-form',
@@ -33,7 +40,10 @@ export class OrderItemFormComponent implements OnInit, OnDestroy {
     }),
   });
 
-  constructor(private layer: ComponentLayerRef) {}
+  constructor(
+    private layer: ComponentLayerRef,
+    private readonly orderFacade: OrderFacade
+  ) {}
 
   ngOnInit(): void {
     this.subscriptions.add(
@@ -71,13 +81,38 @@ export class OrderItemFormComponent implements OnInit, OnDestroy {
     this.subscriptions.unsubscribe();
   }
 
+  get order(): IOrder {
+    return this.layer.data.order;
+  }
+
   get products(): IProduct[] {
     return this.layer.data.products;
   }
 
   onSubmit(): void {
     if (this.formGroup.valid) {
-      console.log(this.formGroup.value);
+      const currentOrderInput = transformOrderToInput(this.order);
+      const updatedOrderInput: IIoRestorecommerceOrderOrder = {
+        ...currentOrderInput,
+        items: [
+          ...(currentOrderInput.items || []),
+          {
+            ...this.formGroup.value,
+            quantity: +(this.formGroup.value.quantity || 0),
+            unitPrice: {
+              salePrice: +(this.formGroup.value.unitPrice?.salePrice || 0),
+              regularPrice: +(
+                this.formGroup.value.unitPrice?.regularPrice || 0
+              ),
+            },
+          },
+        ],
+      };
+
+      this.orderFacade.update({
+        items: [updatedOrderInput],
+        mode: ModeType.Update,
+      });
     }
   }
 
diff --git a/packages/modules/order/src/lib/utils/index.ts b/packages/modules/order/src/lib/utils/index.ts
new file mode 100644
index 00000000..8b0de8e3
--- /dev/null
+++ b/packages/modules/order/src/lib/utils/index.ts
@@ -0,0 +1 @@
+export * from './order.utils';
diff --git a/packages/modules/order/src/lib/utils/order.utils.ts b/packages/modules/order/src/lib/utils/order.utils.ts
new file mode 100644
index 00000000..70a539c5
--- /dev/null
+++ b/packages/modules/order/src/lib/utils/order.utils.ts
@@ -0,0 +1,133 @@
+import {
+  IIoRestorecommerceOrderItem,
+  IIoRestorecommerceOrderOrder,
+  IoRestorecommerceAmountAmount,
+  IoRestorecommerceOrderItem,
+} from '@console-core/graphql';
+import { IOrder } from '@console-core/types';
+
+export const transformOrderToInput = (
+  order: IOrder
+): IIoRestorecommerceOrderOrder => {
+  const inputItems: IIoRestorecommerceOrderItem[] = order.items
+    ? order.items.map(
+        (item: IoRestorecommerceOrderItem): IIoRestorecommerceOrderItem => {
+          return {
+            // id: item.id,
+            productId: item.productId,
+            variantId: item.variantId,
+            parentItemId: item.parentItemId,
+            quantity: item.quantity,
+            unitPrice: {
+              regularPrice: item.unitPrice?.regularPrice,
+              sale: item.unitPrice?.sale,
+              salePrice: item.unitPrice?.salePrice,
+              currencyId: item.unitPrice?.currencyId,
+            },
+          };
+        }
+      )
+    : [];
+
+  const totalAmounts = order.totalAmounts
+    ? order.totalAmounts.map((orderAmount): IoRestorecommerceAmountAmount => {
+        return {
+          gross: orderAmount.gross,
+          net: orderAmount.net,
+          currencyId: orderAmount.currencyId,
+        };
+      })
+    : [];
+
+  return {
+    id: order.id,
+    shopId: order.shopId,
+    notificationEmail: order.notificationEmail,
+    orderState: order.orderState,
+    customerType: order.customerType,
+    customerVatId: order.customerVatId,
+    paymentMethodId: order.paymentMethodId,
+    shippingAddress: {
+      address: {
+        // id: order.shippingAddress?.address?.id,
+        locality: order.shippingAddress?.address?.locality,
+        street: order.shippingAddress?.address?.street,
+        region: order.shippingAddress?.address?.region,
+        countryId: order.shippingAddress?.address?.countryId,
+        buildingNumber: order.shippingAddress?.address?.buildingNumber,
+        postcode: order.shippingAddress?.address?.postcode,
+        // altitude: null,
+        // addressAddition: {
+        //   field1: '',
+        //   field2: '',
+        // },
+        // businessAddress: {
+        //   name: order.shippingAddress?.address?.businessAddress?.name,
+        // },
+        // residentialAddress: {
+        //   title: null,
+        //   givenName: null,
+        //   midName: null,
+        //   familyName: null,
+        // },
+        // geoCoordinates: {
+        //   latitude: null,
+        //   longitude: null,
+        // },
+        // packStation: {
+        //   provider: null,
+        //   stationNumber: null,
+        //   postNumber: null,
+        // },
+      },
+      contact: {
+        name: null,
+        email: null,
+        phone: null,
+      },
+      // comments: null,
+    },
+    billingAddress: {
+      address: {
+        // id: order.billingAddress?.address?.id,
+        postcode: order.billingAddress?.address?.postcode,
+        countryId: order.billingAddress?.address?.countryId,
+        locality: order.billingAddress?.address?.locality,
+        street: order.billingAddress?.address?.street,
+        region: order.billingAddress?.address?.region,
+        // altitude: null,
+        buildingNumber: order.billingAddress?.address?.buildingNumber,
+        // geoCoordinates: {
+        //   latitude: null,
+        //   longitude: null,
+        // },
+        // addressAddition: {
+        //   field1: '',
+        //   field2: '',
+        // },
+        // businessAddress: {
+        //   name: order.billingAddress?.address?.businessAddress?.name,
+        // },
+        // residentialAddress: {
+        //   title: null,
+        //   givenName: null,
+        //   midName: null,
+        //   familyName: null,
+        // },
+        // packStation: {
+        //   provider: null,
+        //   stationNumber: null,
+        //   postNumber: null,
+        // },
+      },
+      contact: {
+        name: null,
+        email: null,
+        phone: null,
+      },
+      // comments: null,
+    },
+    totalAmounts: [...totalAmounts],
+    items: [...inputItems],
+  };
+};