multi-location-stock-plugin.ts 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import {
  2. AvailableStock,
  3. DefaultStockLocationStrategy,
  4. ID,
  5. idsAreEqual,
  6. Injector,
  7. LocationWithQuantity,
  8. OrderLine,
  9. PluginCommonModule,
  10. ProductVariant,
  11. RequestContext,
  12. StockDisplayStrategy,
  13. StockLevel,
  14. StockLocation,
  15. TransactionalConnection,
  16. VendurePlugin,
  17. } from '@vendure/core';
  18. declare module '@vendure/core/dist/entity/custom-entity-fields' {
  19. interface CustomOrderLineFields {
  20. stockLocationId?: string;
  21. }
  22. }
  23. export class TestStockLocationStrategy extends DefaultStockLocationStrategy {
  24. forAllocation(
  25. ctx: RequestContext,
  26. stockLocations: StockLocation[],
  27. orderLine: OrderLine,
  28. quantity: number,
  29. ): LocationWithQuantity[] | Promise<LocationWithQuantity[]> {
  30. const selectedLocation = stockLocations.find(location =>
  31. idsAreEqual(location.id, orderLine.customFields.stockLocationId),
  32. );
  33. return [{ location: selectedLocation ?? stockLocations[0], quantity }];
  34. }
  35. getAvailableStock(ctx: RequestContext, productVariantId: ID, stockLevels: StockLevel[]): AvailableStock {
  36. const locationId = ctx.req?.query.fromLocation;
  37. const locationStock =
  38. locationId &&
  39. stockLevels.find(level => idsAreEqual(level.stockLocationId, locationId.toString()));
  40. if (locationStock) {
  41. return {
  42. stockOnHand: locationStock.stockOnHand,
  43. stockAllocated: locationStock.stockAllocated,
  44. };
  45. }
  46. return stockLevels.reduce(
  47. (all, level) => ({
  48. stockOnHand: all.stockOnHand + level.stockOnHand,
  49. stockAllocated: all.stockAllocated + level.stockAllocated,
  50. }),
  51. { stockOnHand: 0, stockAllocated: 0 },
  52. );
  53. }
  54. }
  55. export class TestStockDisplayStrategy implements StockDisplayStrategy {
  56. getStockLevel(ctx: RequestContext, productVariant: ProductVariant, saleableStockLevel: number) {
  57. return saleableStockLevel.toString();
  58. }
  59. }
  60. @VendurePlugin({
  61. imports: [PluginCommonModule],
  62. configuration: config => {
  63. config.catalogOptions.stockLocationStrategy = new TestStockLocationStrategy();
  64. config.catalogOptions.stockDisplayStrategy = new TestStockDisplayStrategy();
  65. config.customFields.OrderLine.push({ name: 'stockLocationId', type: 'string', nullable: true });
  66. return config;
  67. },
  68. })
  69. export class TestMultiLocationStockPlugin {}