Quellcode durchsuchen

fix(core): Fix issue with cancellation of fulfilled OrderItems

Fixes #1558
Michael Bromley vor 3 Jahren
Ursprung
Commit
13b0cf97ba

+ 55 - 0
packages/core/e2e/order.e2e-spec.ts

@@ -2342,6 +2342,61 @@ describe('Orders resolver', () => {
                     .price,
             ).toBe(108720);
         });
+
+        // https://github.com/vendure-ecommerce/vendure/issues/1558
+        it('cancelling OrderItem avoids items that have been fulfilled', async () => {
+            await shopClient.asUserWithCredentials(customers[0].emailAddress, password);
+            const { addItemToOrder } = await shopClient.query<
+                AddItemToOrder.Mutation,
+                AddItemToOrder.Variables
+            >(ADD_ITEM_TO_ORDER, {
+                productVariantId: 'T_1',
+                quantity: 2,
+            });
+
+            await proceedToArrangingPayment(shopClient);
+            const order = await addPaymentToOrder(shopClient, singleStageRefundablePaymentMethod);
+            orderGuard.assertSuccess(order);
+
+            await adminClient.query<CreateFulfillment.Mutation, CreateFulfillment.Variables>(
+                CREATE_FULFILLMENT,
+                {
+                    input: {
+                        lines: [
+                            {
+                                orderLineId: order.lines[0].id,
+                                quantity: 1,
+                            },
+                        ],
+                        handler: {
+                            code: manualFulfillmentHandler.code,
+                            arguments: [{ name: 'method', value: 'Test' }],
+                        },
+                    },
+                },
+            );
+
+            const { cancelOrder } = await adminClient.query<CancelOrder.Mutation, CancelOrder.Variables>(
+                CANCEL_ORDER,
+                {
+                    input: {
+                        orderId: order.id,
+                        lines: [{ orderLineId: order.lines[0].id, quantity: 1 }],
+                    },
+                },
+            );
+            orderGuard.assertSuccess(cancelOrder);
+
+            const { order: order2 } = await adminClient.query<GetOrder.Query, GetOrder.Variables>(GET_ORDER, {
+                id: order.id,
+            });
+
+            const items = order2!.lines[0].items;
+            const itemWhichIsCancelledAndFulfilled = items.find(
+                i => i.cancelled === true && i.fulfillment != null,
+            );
+            expect(itemWhichIsCancelledAndFulfilled).toBeUndefined();
+        });
     });
 });
 

+ 11 - 3
packages/core/src/service/services/order.service.ts

@@ -1797,9 +1797,17 @@ export class OrderService {
             if (matchingItems.length < inputLine.quantity) {
                 return false;
             }
-            matchingItems.slice(0, inputLine.quantity).forEach(item => {
-                items.set(item.id, item);
-            });
+            matchingItems
+                .slice(0)
+                .sort((a, b) =>
+                    // sort the OrderItems so that those without Fulfillments come first, as
+                    // it makes sense to cancel these prior to cancelling fulfilled items.
+                    !a.fulfillment && b.fulfillment ? -1 : a.fulfillment && !b.fulfillment ? 1 : 0,
+                )
+                .slice(0, inputLine.quantity)
+                .forEach(item => {
+                    items.set(item.id, item);
+                });
         }
         return {
             orders: Array.from(orders.values()),