mv-order-process.ts 3.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. import { OrderType } from '@vendure/common/lib/generated-types';
  2. import { ID } from '@vendure/common/lib/shared-types';
  3. import {
  4. CustomOrderProcess,
  5. idsAreEqual,
  6. Order,
  7. orderItemsAreDelivered,
  8. orderItemsArePartiallyDelivered,
  9. orderItemsArePartiallyShipped,
  10. orderItemsAreShipped,
  11. OrderService,
  12. RequestContext,
  13. TransactionalConnection,
  14. } from '@vendure/core';
  15. let connection: TransactionalConnection;
  16. let orderService: OrderService;
  17. export const multivendorOrderProcess: CustomOrderProcess<any> = {
  18. init(injector) {
  19. connection = injector.get(TransactionalConnection);
  20. orderService = injector.get(OrderService);
  21. },
  22. async onTransitionStart(fromState, toState, data) {
  23. const { ctx, order } = data;
  24. if (fromState === 'AddingItems' && toState === 'ArrangingPayment') {
  25. for (const line of data.order.lines) {
  26. if (!line.shippingLineId) {
  27. return 'not all lines have shipping';
  28. }
  29. }
  30. }
  31. if (order.type !== OrderType.Aggregate) {
  32. if (toState === 'PartiallyShipped') {
  33. const orderWithFulfillments = await findOrderWithFulfillments(ctx, order.id);
  34. if (!orderItemsArePartiallyShipped(orderWithFulfillments)) {
  35. return `message.cannot-transition-unless-some-order-items-shipped`;
  36. }
  37. }
  38. if (toState === 'Shipped') {
  39. const orderWithFulfillments = await findOrderWithFulfillments(ctx, order.id);
  40. if (!orderItemsAreShipped(orderWithFulfillments)) {
  41. return `message.cannot-transition-unless-all-order-items-shipped`;
  42. }
  43. }
  44. if (toState === 'PartiallyDelivered') {
  45. const orderWithFulfillments = await findOrderWithFulfillments(ctx, order.id);
  46. if (!orderItemsArePartiallyDelivered(orderWithFulfillments)) {
  47. return `message.cannot-transition-unless-some-order-items-delivered`;
  48. }
  49. }
  50. if (toState === 'Delivered') {
  51. const orderWithFulfillments = await findOrderWithFulfillments(ctx, order.id);
  52. if (!orderItemsAreDelivered(orderWithFulfillments)) {
  53. return `message.cannot-transition-unless-all-order-items-delivered`;
  54. }
  55. }
  56. }
  57. },
  58. async onTransitionEnd(fromState, toState, data) {
  59. const { ctx, order } = data;
  60. if (order.type === OrderType.Seller) {
  61. const aggregateOrder = await orderService.getAggregateOrder(ctx, order);
  62. if (aggregateOrder) {
  63. const otherSellerOrders = (await orderService.getSellerOrders(ctx, aggregateOrder)).filter(
  64. so => !idsAreEqual(so.id, order.id),
  65. );
  66. const sellerOrderStates = [...otherSellerOrders.map(so => so.state), toState];
  67. if (sellerOrderStates.every(state => state === 'Shipped')) {
  68. await orderService.transitionToState(data.ctx, aggregateOrder.id, 'Shipped');
  69. } else if (sellerOrderStates.every(state => state === 'Delivered')) {
  70. await orderService.transitionToState(data.ctx, aggregateOrder.id, 'Delivered');
  71. } else if (sellerOrderStates.some(state => state === 'Delivered')) {
  72. await orderService.transitionToState(data.ctx, aggregateOrder.id, 'PartiallyDelivered');
  73. } else if (sellerOrderStates.some(state => state === 'Shipped')) {
  74. await orderService.transitionToState(data.ctx, aggregateOrder.id, 'PartiallyShipped');
  75. }
  76. }
  77. }
  78. },
  79. };
  80. async function findOrderWithFulfillments(ctx: RequestContext, id: ID): Promise<Order> {
  81. return await connection.getEntityOrThrow(ctx, Order, id, {
  82. relations: ['lines', 'lines.items', 'lines.items.fulfillments'],
  83. });
  84. }