Просмотр исходного кода

feat(core): Add order line limit to Vendure configuration

Thomas Blommaert 4 лет назад
Родитель
Сommit
6755329ba7

+ 1 - 0
packages/core/src/config/default-config.ts

@@ -111,6 +111,7 @@ export const defaultConfig: RuntimeVendureConfig = {
     },
     orderOptions: {
         orderItemsLimit: 999,
+        orderLineItemsLimit: 999,
         orderItemPriceCalculationStrategy: new DefaultOrderItemPriceCalculationStrategy(),
         mergeStrategy: new MergeOrdersStrategy(),
         checkoutMergeStrategy: new UseGuestStrategy(),

+ 11 - 0
packages/core/src/config/vendure-config.ts

@@ -385,6 +385,17 @@ export interface OrderOptions {
      * @default 999
      */
     orderItemsLimit?: number;
+    /**
+     * @description
+     * The maximum number of items allowed per order line. This option is an addition
+     * on the `orderItemsLimit` for more granular control. Note `orderItemsLimit` is still
+     * important in order to prevent excessive resource usage.
+     *
+     * Attempting to exceed this limit will cause Vendure to throw a {@link OrderItemsLimitError}.
+     *
+     * @default 999
+     */
+    orderLineItemsLimit?: number;
     /**
      * @description
      * Defines the logic used to calculate the unit price of an OrderItem when adding an

+ 22 - 8
packages/core/src/service/services/order.service.ts

@@ -363,20 +363,21 @@ export class OrderService {
         customFields?: { [key: string]: any },
     ): Promise<ErrorResultUnion<UpdateOrderItemsResult, Order>> {
         const order = await this.getOrderOrThrow(ctx, orderId);
+        const existingOrderLine = this.orderModifier.getExistingOrderLine(
+            ctx,
+            order,
+            productVariantId,
+            customFields,
+        );
         const validationError =
             this.assertQuantityIsPositive(quantity) ||
             this.assertAddingItemsState(order) ||
-            this.assertNotOverOrderItemsLimit(order, quantity);
+            this.assertNotOverOrderItemsLimit(order, quantity) ||
+            this.assertNotOverOrderLineItemsLimit(existingOrderLine, quantity);
         if (validationError) {
             return validationError;
         }
         const variant = await this.connection.getEntityOrThrow(ctx, ProductVariant, productVariantId);
-        const existingOrderLine = this.orderModifier.getExistingOrderLine(
-            ctx,
-            order,
-            productVariantId,
-            customFields,
-        );
         const correctedQuantity = await this.orderModifier.constrainQuantityToSaleable(
             ctx,
             variant,
@@ -417,7 +418,8 @@ export class OrderService {
         const validationError =
             this.assertAddingItemsState(order) ||
             this.assertQuantityIsPositive(quantity) ||
-            this.assertNotOverOrderItemsLimit(order, quantity - orderLine.quantity);
+            this.assertNotOverOrderItemsLimit(order, quantity - orderLine.quantity) ||
+            this.assertNotOverOrderLineItemsLimit(orderLine, quantity - orderLine.quantity);
         if (validationError) {
             return validationError;
         }
@@ -1291,6 +1293,18 @@ export class OrderService {
         }
     }
 
+    /**
+     * Throws if adding the given quantity would exceed the maximum allowed
+     * quantity for one order line.
+     */
+    private assertNotOverOrderLineItemsLimit(orderLine: OrderLine | undefined, quantityToAdd: number) {
+        const currentQuantity = orderLine?.quantity || 0;
+        const { orderLineItemsLimit } = this.configService.orderOptions;
+        if (orderLineItemsLimit < currentQuantity + quantityToAdd) {
+            return new OrderLimitError(orderLineItemsLimit);
+        }
+    }
+
     /**
      * Applies promotions, taxes and shipping to the Order.
      */