Browse Source

fix(admin-ui): Improved handling of failed cancellations

If the cancellation fails, the refund step is not also run, which was leading
to the Order getting into a bad state.
Michael Bromley 3 years ago
parent
commit
2c79cf06d6

+ 31 - 23
packages/admin-ui/src/lib/order/src/components/order-detail/order-detail.component.ts

@@ -526,32 +526,45 @@ export class OrderDetailComponent
                         return of(undefined);
                     }
 
-                    const operations: Array<Observable<RefundOrder.RefundOrder | CancelOrder.CancelOrder>> =
-                        [];
-                    if (input.refund.lines.length) {
-                        operations.push(
-                            this.dataService.order
-                                .refundOrder(input.refund)
-                                .pipe(map(res => res.refundOrder)),
-                        );
-                    }
                     if (input.cancel.lines?.length) {
-                        operations.push(
-                            this.dataService.order
-                                .cancelOrder(input.cancel)
-                                .pipe(map(res => res.cancelOrder)),
+                        return this.dataService.order.cancelOrder(input.cancel).pipe(
+                            map(res => {
+                                const result = res.cancelOrder;
+                                switch (result.__typename) {
+                                    case 'Order':
+                                        this.refetchOrder(result).subscribe();
+                                        this.notificationService.success(_('order.cancelled-order-success'));
+                                        return input;
+                                    case 'CancelActiveOrderError':
+                                    case 'QuantityTooGreatError':
+                                    case 'MultipleOrderError':
+                                    case 'OrderStateTransitionError':
+                                    case 'EmptyOrderLineSelectionError':
+                                        this.notificationService.error(result.message);
+                                        return undefined;
+                                }
+                            }),
                         );
+                    } else {
+                        return [input];
+                    }
+                }),
+                switchMap(input => {
+                    if (!input) {
+                        return of(undefined);
+                    }
+                    if (input.refund.lines.length) {
+                        return this.dataService.order
+                            .refundOrder(input.refund)
+                            .pipe(map(res => res.refundOrder));
+                    } else {
+                        return [undefined];
                     }
-                    return merge(...operations);
                 }),
             )
             .subscribe(result => {
                 if (result) {
                     switch (result.__typename) {
-                        case 'Order':
-                            this.refetchOrder(result).subscribe();
-                            this.notificationService.success(_('order.cancelled-order-success'));
-                            break;
                         case 'Refund':
                             this.refetchOrder(result).subscribe();
                             if (result.state === 'Failed') {
@@ -560,11 +573,6 @@ export class OrderDetailComponent
                                 this.notificationService.success(_('order.refund-order-success'));
                             }
                             break;
-                        case 'QuantityTooGreatError':
-                        case 'MultipleOrderError':
-                        case 'OrderStateTransitionError':
-                        case 'CancelActiveOrderError':
-                        case 'EmptyOrderLineSelectionError':
                         case 'AlreadyRefundedError':
                         case 'NothingToRefundError':
                         case 'PaymentOrderMismatchError':