order-quantity-limits.plugin.ts 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. import {
  2. EntityHydrator,
  3. Injector,
  4. LanguageCode,
  5. Order,
  6. OrderInterceptor,
  7. ProductVariant,
  8. RequestContext,
  9. TranslatorService,
  10. VendurePlugin,
  11. WillAddItemToOrderInput,
  12. WillAdjustOrderLineInput,
  13. } from '@vendure/core';
  14. declare module '@vendure/core/dist/entity/custom-entity-fields' {
  15. interface CustomProductVariantFields {
  16. minOrderQuantity?: number;
  17. maxOrderQuantity?: number;
  18. }
  19. }
  20. /**
  21. * This OrderInterceptor enforces minimum and maximum order quantities on ProductVariants.
  22. */
  23. export class MinMaxOrderInterceptor implements OrderInterceptor {
  24. private entityHydrator: EntityHydrator;
  25. private translatorService: TranslatorService;
  26. init(injector: Injector) {
  27. this.entityHydrator = injector.get(EntityHydrator);
  28. this.translatorService = injector.get(TranslatorService);
  29. }
  30. willAddItemToOrder(
  31. ctx: RequestContext,
  32. order: Order,
  33. input: WillAddItemToOrderInput,
  34. ): Promise<void | string> | void | string {
  35. const { productVariant, quantity } = input;
  36. const min = productVariant.customFields?.minOrderQuantity;
  37. const max = productVariant.customFields?.maxOrderQuantity;
  38. if (min && quantity < min) {
  39. return this.minErrorMessage(ctx, productVariant, min);
  40. }
  41. if (max && quantity > max) {
  42. return this.maxErrorMessage(ctx, productVariant, max);
  43. }
  44. }
  45. willAdjustOrderLine(
  46. ctx: RequestContext,
  47. order: Order,
  48. input: WillAdjustOrderLineInput,
  49. ): Promise<void | string> | void | string {
  50. const { orderLine, quantity } = input;
  51. const min = orderLine.productVariant.customFields?.minOrderQuantity;
  52. const max = orderLine.productVariant.customFields?.maxOrderQuantity;
  53. if (min && quantity < min) {
  54. return this.minErrorMessage(ctx, orderLine.productVariant, min);
  55. }
  56. if (max && quantity > max) {
  57. return this.maxErrorMessage(ctx, orderLine.productVariant, max);
  58. }
  59. }
  60. private async minErrorMessage(ctx: RequestContext, variant: ProductVariant, min: number) {
  61. const variantName = await this.getTranslatedVariantName(ctx, variant);
  62. return `Minimum order quantity for "${variantName}" is ${min}`;
  63. }
  64. private async maxErrorMessage(ctx: RequestContext, variant: ProductVariant, max: number) {
  65. const variantName = await this.getTranslatedVariantName(ctx, variant);
  66. return `Maximum order quantity for "${variantName}" is ${max}`;
  67. }
  68. private async getTranslatedVariantName(ctx: RequestContext, variant: ProductVariant) {
  69. await this.entityHydrator.hydrate(ctx, variant, { relations: ['translations'] });
  70. const translated = this.translatorService.translate(variant, ctx);
  71. return translated.name;
  72. }
  73. }
  74. /**
  75. * This plugin enforces minimum and maximum order quantities on ProductVariants.
  76. * It adds two new custom fields to ProductVariant:
  77. * - minOrderQuantity
  78. * - maxOrderQuantity
  79. *
  80. * It also adds an OrderInterceptor which enforces these limits.
  81. */
  82. @VendurePlugin({
  83. configuration: config => {
  84. config.customFields.ProductVariant.push({
  85. type: 'int',
  86. min: 0,
  87. name: 'minOrderQuantity',
  88. label: [{ languageCode: LanguageCode.en, value: 'Minimum order quantity' }],
  89. nullable: true,
  90. });
  91. config.customFields.ProductVariant.push({
  92. type: 'int',
  93. min: 0,
  94. name: 'maxOrderQuantity',
  95. label: [{ languageCode: LanguageCode.en, value: 'Maximum order quantity' }],
  96. nullable: true,
  97. });
  98. config.orderOptions.orderInterceptors.push(new MinMaxOrderInterceptor());
  99. return config;
  100. },
  101. })
  102. export class OrderQuantityLimitsPlugin {}