@@ -7,9 +7,8 @@ public protocol POSOrderServiceProtocol {
77 /// Syncs order based on the cart.
88 /// - Parameters:
99 /// - cart: Cart with different types of items and quantities.
10- /// - order: Optional latest remotely synced order. Nil when syncing order for the first time.
1110 /// - Returns: Order from the remote sync.
12- func syncOrder( cart: POSCart , order : Order ? , currency: CurrencyCode ) async throws -> Order
11+ func syncOrder( cart: POSCart , currency: CurrencyCode ) async throws -> Order
1312 func updatePOSOrder( order: Order , recipientEmail: String ) async throws
1413}
1514
@@ -36,19 +35,14 @@ public final class POSOrderService: POSOrderServiceProtocol {
3635 // MARK: - Protocol conformance
3736
3837 public func syncOrder( cart: POSCart ,
39- order posOrder: Order ? ,
4038 currency: CurrencyCode ) async throws -> Order {
41- let initialOrder : Order = posOrder ?? OrderFactory . newOrder ( currency: currency)
42- . copy ( siteID: siteID,
43- status: . autoDraft)
44- let order = updateOrder ( initialOrder, cart: cart) . sanitizingLocalItems ( )
45- let syncedOrder : Order
46- if posOrder != nil {
47- syncedOrder = try await ordersRemote. updatePOSOrder ( siteID: siteID, order: order, fields: [ . items, . couponLines] )
48- } else {
49- syncedOrder = try await ordersRemote. createPOSOrder ( siteID: siteID, order: order, fields: [ . items, . status, . currency, . couponLines] )
50- }
51- return syncedOrder
39+ let order = OrderFactory
40+ . newOrder ( currency: currency)
41+ . copy ( siteID: siteID, status: . autoDraft)
42+ . addItems ( cart. items)
43+ . addCoupons ( cart. coupons)
44+
45+ return try await ordersRemote. createPOSOrder ( siteID: siteID, order: order, fields: [ . items, . status, . currency, . couponLines] )
5246 }
5347
5448 public func updatePOSOrder( order: Order , recipientEmail: String ) async throws {
@@ -66,73 +60,19 @@ public final class POSOrderService: POSOrderServiceProtocol {
6660 }
6761}
6862
69- private struct POSOrderSyncProductType : OrderSyncProductTypeProtocol , Hashable {
70- let productID : Int64
71- let price : String
72- // Not used in POS but have to be included for the app usage.
73- let productType : ProductType
74- let bundledItems : [ ProductBundleItem ]
75-
76- init ( productID: Int64 , price: String , productType: ProductType , bundledItems: [ ProductBundleItem ] = [ ] ) {
77- self . productID = productID
78- self . price = price
79- self . productType = productType
80- self . bundledItems = bundledItems
81- }
82- }
83-
84- private extension POSOrderService {
85- func updateOrder( _ order: Order , cart: POSCart ) -> Order {
86- // Removes all existing items by setting quantity to 0.
87- let itemsToRemove = order. items. compactMap {
88- Self . removalProductInput ( item: $0)
89- }
90-
91- // Adds items from the latest cart grouping by item.
92- let itemsToAdd = cart. items. createGroupedOrderSyncProductInputs ( ) . values
93- let itemsToSync = itemsToRemove + itemsToAdd
94-
95- var order = ProductInputTransformer . updateMultipleItems ( with: itemsToSync, on: order, shouldUpdateOrDeleteZeroQuantities: . update)
96- order = updateCoupons ( cart. coupons, on: order)
97-
98- return order
63+ private extension Order {
64+ func addItems( _ cartItems: [ POSCartItem ] ) -> Order {
65+ let itemsToAdd = Array ( cartItems. createGroupedOrderSyncProductInputs ( ) . values)
66+ return ProductInputTransformer
67+ . updateMultipleItems ( with: itemsToAdd, on: self , shouldUpdateOrDeleteZeroQuantities: . update)
68+ . sanitizingLocalItems ( )
9969 }
10070
101- func updateCoupons( _ coupons: [ POSCoupon ] , on order: Order ) -> Order {
102- // Get coupon codes from cart
103- let cartCouponCodes = Set ( coupons. map { $0. code } )
104-
105- // Keep existing coupons that are still in the cart
106- let remainingCoupons = order. coupons. filter { orderCoupon in
107- cartCouponCodes. contains ( orderCoupon. code)
108- }
109-
110- // Find new coupons that need to be added (in cart but not in order)
111- let existingCouponCodes = Set ( order. coupons. map { $0. code } )
71+ func addCoupons( _ coupons: [ POSCoupon ] ) -> Order {
11272 let newCoupons = coupons
113- . filter { !existingCouponCodes. contains ( $0. code) }
11473 . map { OrderFactory . newOrderCouponLine ( code: $0. code) }
11574
116- // Update order with remaining + new coupons
117- return order. copy ( coupons: remainingCoupons + newCoupons)
118- }
119-
120- /// Creates a new `OrderSyncProductInput` type meant to remove an existing item from `OrderSynchronizer`
121- ///
122- static func removalProductInput( item: OrderItem ) -> OrderSyncProductInput ? {
123- let productForRemoval = POSProductForRemoval ( productID: item. productID)
124- // Return a new input with the new quantity but with the same item id to properly reference the update.
125- return OrderSyncProductInput ( id: item. itemID,
126- product: . product( productForRemoval) ,
127- quantity: 0 )
128- }
129-
130- /// A simplified product struct, intended to contain only the `productID`
131- struct POSProductForRemoval : OrderSyncProductTypeProtocol {
132- var price : String = " "
133- var productID : Int64
134- var productType : ProductType = . simple
135- var bundledItems : [ ProductBundleItem ] = [ ]
75+ return self . copy ( coupons: newCoupons)
13676 }
13777}
13878
0 commit comments