Browse Source

fix(core): Fix multiple refunds on the same OrderLine

Fixes #868
Michael Bromley 4 years ago
parent
commit
7316d31ccb

+ 47 - 2
packages/core/e2e/order.e2e-spec.ts

@@ -1567,8 +1567,10 @@ describe('Orders resolver', () => {
             );
             refundGuard.assertErrorResult(refundOrder);
 
-            expect(refundOrder.message).toBe('Cannot refund an OrderItem which has already been refunded');
-            expect(refundOrder.errorCode).toBe(ErrorCode.ALREADY_REFUNDED_ERROR);
+            expect(refundOrder.message).toBe(
+                'The specified quantity is greater than the available OrderItems',
+            );
+            expect(refundOrder.errorCode).toBe(ErrorCode.QUANTITY_TOO_GREAT_ERROR);
         });
 
         it('manually settle a Refund', async () => {
@@ -2071,6 +2073,49 @@ describe('Orders resolver', () => {
                 shippingMethod: pick(shippingMethod, ['id', 'name', 'code', 'description']),
             });
         });
+
+        // https://github.com/vendure-ecommerce/vendure/issues/868
+        it('allows multiple refunds of same OrderLine', 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);
+
+            const { refundOrder: refund1 } = await adminClient.query<
+                RefundOrder.Mutation,
+                RefundOrder.Variables
+            >(REFUND_ORDER, {
+                input: {
+                    lines: order!.lines.map(l => ({ orderLineId: l.id, quantity: 1 })),
+                    shipping: 0,
+                    adjustment: 0,
+                    reason: 'foo',
+                    paymentId: order.payments![0].id,
+                },
+            });
+            refundGuard.assertSuccess(refund1);
+
+            const { refundOrder: refund2 } = await adminClient.query<
+                RefundOrder.Mutation,
+                RefundOrder.Variables
+            >(REFUND_ORDER, {
+                input: {
+                    lines: order!.lines.map(l => ({ orderLineId: l.id, quantity: 1 })),
+                    shipping: 0,
+                    adjustment: 0,
+                    reason: 'foo',
+                    paymentId: order.payments![0].id,
+                },
+            });
+            refundGuard.assertSuccess(refund2);
+        });
     });
 });
 

+ 2 - 2
packages/core/src/service/services/order.service.ts

@@ -1078,7 +1078,7 @@ export class OrderService {
         ) {
             return new NothingToRefundError();
         }
-        const ordersAndItems = await this.getOrdersAndItemsFromLines(ctx, input.lines, i => !i.cancelled);
+        const ordersAndItems = await this.getOrdersAndItemsFromLines(ctx, input.lines, i => !i.refund);
         if (!ordersAndItems) {
             return new QuantityTooGreatError();
         }
@@ -1406,7 +1406,7 @@ export class OrderService {
         const lines = await this.connection.getRepository(ctx, OrderLine).findByIds(
             orderLinesInput.map(l => l.orderLineId),
             {
-                relations: ['order', 'items', 'items.fulfillments', 'order.channels'],
+                relations: ['order', 'items', 'items.fulfillments', 'order.channels', 'items.refund'],
                 order: { id: 'ASC' },
             },
         );