| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111 |
- import {
- EntityHydrator,
- Injector,
- LanguageCode,
- Order,
- OrderInterceptor,
- ProductVariant,
- RequestContext,
- TranslatorService,
- VendurePlugin,
- WillAddItemToOrderInput,
- WillAdjustOrderLineInput,
- } from '@vendure/core';
- declare module '@vendure/core/dist/entity/custom-entity-fields' {
- interface CustomProductVariantFields {
- minOrderQuantity?: number;
- maxOrderQuantity?: number;
- }
- }
- /**
- * This OrderInterceptor enforces minimum and maximum order quantities on ProductVariants.
- */
- export class MinMaxOrderInterceptor implements OrderInterceptor {
- private entityHydrator: EntityHydrator;
- private translatorService: TranslatorService;
- init(injector: Injector) {
- this.entityHydrator = injector.get(EntityHydrator);
- this.translatorService = injector.get(TranslatorService);
- }
- willAddItemToOrder(
- ctx: RequestContext,
- order: Order,
- input: WillAddItemToOrderInput,
- ): Promise<void | string> | void | string {
- const { productVariant, quantity } = input;
- const min = productVariant.customFields?.minOrderQuantity;
- const max = productVariant.customFields?.maxOrderQuantity;
- if (min && quantity < min) {
- return this.minErrorMessage(ctx, productVariant, min);
- }
- if (max && quantity > max) {
- return this.maxErrorMessage(ctx, productVariant, max);
- }
- }
- willAdjustOrderLine(
- ctx: RequestContext,
- order: Order,
- input: WillAdjustOrderLineInput,
- ): Promise<void | string> | void | string {
- const { orderLine, quantity } = input;
- const min = orderLine.productVariant.customFields?.minOrderQuantity;
- const max = orderLine.productVariant.customFields?.maxOrderQuantity;
- if (min && quantity < min) {
- return this.minErrorMessage(ctx, orderLine.productVariant, min);
- }
- if (max && quantity > max) {
- return this.maxErrorMessage(ctx, orderLine.productVariant, max);
- }
- }
- private async minErrorMessage(ctx: RequestContext, variant: ProductVariant, min: number) {
- const variantName = await this.getTranslatedVariantName(ctx, variant);
- return `Minimum order quantity for "${variantName}" is ${min}`;
- }
- private async maxErrorMessage(ctx: RequestContext, variant: ProductVariant, max: number) {
- const variantName = await this.getTranslatedVariantName(ctx, variant);
- return `Maximum order quantity for "${variantName}" is ${max}`;
- }
- private async getTranslatedVariantName(ctx: RequestContext, variant: ProductVariant) {
- await this.entityHydrator.hydrate(ctx, variant, { relations: ['translations'] });
- const translated = this.translatorService.translate(variant, ctx);
- return translated.name;
- }
- }
- /**
- * This plugin enforces minimum and maximum order quantities on ProductVariants.
- * It adds two new custom fields to ProductVariant:
- * - minOrderQuantity
- * - maxOrderQuantity
- *
- * It also adds an OrderInterceptor which enforces these limits.
- */
- @VendurePlugin({
- configuration: config => {
- config.customFields.ProductVariant.push({
- type: 'int',
- min: 0,
- name: 'minOrderQuantity',
- label: [{ languageCode: LanguageCode.en, value: 'Minimum order quantity' }],
- nullable: true,
- });
- config.customFields.ProductVariant.push({
- type: 'int',
- min: 0,
- name: 'maxOrderQuantity',
- label: [{ languageCode: LanguageCode.en, value: 'Maximum order quantity' }],
- nullable: true,
- });
- config.orderOptions.orderInterceptors.push(new MinMaxOrderInterceptor());
- return config;
- },
- })
- export class OrderQuantityLimitsPlugin {}
|