Ver Fonte

docs(core): Add documentation for new multivendor APIs

Michael Bromley há 3 anos atrás
pai
commit
b39dbb5b37

+ 6 - 1
packages/core/src/api/schema/shop-api/shop.api.graphql

@@ -68,7 +68,12 @@ type Mutation {
     setOrderBillingAddress(input: CreateAddressInput!): ActiveOrderResult!
     "Allows any custom fields to be set for the active order"
     setOrderCustomFields(input: UpdateOrderInput!): ActiveOrderResult!
-    "Sets the shipping method by id, which can be obtained with the `eligibleShippingMethods` query"
+    """
+    Sets the shipping method by id, which can be obtained with the `eligibleShippingMethods` query.
+    An Order can have multiple shipping methods, in which case you can pass an array of ids. In this case,
+    you should configure a custom ShippingLineAssignmentStrategy in order to know which OrderLines each
+    shipping method will apply to.
+    """
     setOrderShippingMethod(shippingMethodId: [ID!]!): SetOrderShippingMethodResult!
     "Add a Payment to the Order"
     addPaymentToOrder(input: PaymentInput!): AddPaymentToOrderResult!

+ 8 - 0
packages/core/src/config/order/default-order-seller-strategy.ts

@@ -1,5 +1,13 @@
 import { OrderSellerStrategy } from './order-seller-strategy';
 
+/**
+ * @description
+ * The DefaultOrderSellerStrategy treats the Order as single-vendor.
+ *
+ * @since 2.0.0
+ * @docsCategory orders
+ * @docsPage OrderSellerStrategy
+ */
 export class DefaultOrderSellerStrategy implements OrderSellerStrategy {
     // By default, Orders will not get split.
 }

+ 39 - 2
packages/core/src/config/order/order-seller-strategy.ts

@@ -5,21 +5,58 @@ import { InjectableStrategy } from '../../common/index';
 import { Channel, Order, OrderLine, Payment, ShippingLine, Surcharge } from '../../entity/index';
 import { OrderState } from '../../service/index';
 
+/**
+ * @description
+ * The contents of the aggregate Order which make up a single seller Order.
+ *
+ * @since 2.0.0
+ * @docsCategory orders
+ * @docsPage OrderSellerStrategy
+ */
 export interface SplitOrderContents {
     channelId: ID;
     state: OrderState;
     lines: OrderLine[];
-    surcharges: Surcharge[];
     shippingLines: ShippingLine[];
 }
 
+/**
+ * @description
+ * This strategy defines how an Order can be split into multiple sub-orders for the use-case of
+ * a multivendor application.
+ *
+ * @since 2.0.0
+ * @docsCategory orders
+ * @docsPage OrderSellerStrategy
+ * @docsWeight 0
+ */
 export interface OrderSellerStrategy extends InjectableStrategy {
+    /**
+     * @description
+     * This method is called whenever a new OrderLine is added to the Order via the `addItemToOrder` mutation or the
+     * underlying `addItemToOrder()` method of the {@link OrderService}.
+     *
+     * It should return the ID of the Channel to which this OrderLine will be assigned, which will be used to set the
+     * {@link OrderLine} `sellerChannel` property.
+     */
     setOrderLineSellerChannel?(
         ctx: RequestContext,
         orderLine: OrderLine,
     ): Channel | undefined | Promise<Channel | undefined>;
+
+    /**
+     * @description
+     * Upon checkout (by default, when the Order moves from "active" to "inactive" according to the {@link OrderPlacedStrategy}),
+     * this method will be called in order to split the Order into multiple Orders, one for each Seller.
+     */
     splitOrder?(ctx: RequestContext, order: Order): SplitOrderContents[] | Promise<SplitOrderContents[]>;
-    createSurcharges?(ctx: RequestContext, sellerOrder: Order): Surcharge[] | Promise<Surcharge[]>;
+
+    /**
+     * @description
+     * This method is called after splitting the orders, including calculating the totals for each of the seller Orders.
+     * This method can be used to set platform fee surcharges on the seller Orders as well as perform any payment processing
+     * needed.
+     */
     afterSellerOrdersCreated?(
         ctx: RequestContext,
         aggregateOrder: Order,

+ 1 - 1
packages/core/src/config/shipping-method/default-shipping-calculator.ts

@@ -4,7 +4,7 @@ import { RequestContext } from '../../api/common/request-context';
 
 import { ShippingCalculator } from './shipping-calculator';
 
-enum TaxSetting {
+export enum TaxSetting {
     include = 'include',
     exclude = 'exclude',
     auto = 'auto',

+ 12 - 0
packages/core/src/config/shipping-method/shipping-line-assignment-strategy.ts

@@ -2,6 +2,18 @@ import { RequestContext } from '../../api/index';
 import { InjectableStrategy } from '../../common/index';
 import { Order, OrderLine, ShippingLine } from '../../entity/index';
 
+/**
+ * @description
+ * This strategy is used to assign a given {@link ShippingLine} to one or more {@link OrderLine}s of the Order.
+ * This allows you to set multiple shipping methods for a single order, each assigned a different subset of
+ * OrderLines.
+ *
+ * The {@link DefaultShippingLineAssignmentStrategy} simply assigns _all_ OrderLines, so is suitable for the
+ * most common scenario of a single shipping method per Order.
+ *
+ * @since 2.0.0
+ * @docsCategory shipping
+ */
 export interface ShippingLineAssignmentStrategy extends InjectableStrategy {
     assignShippingLineToOrderLines(
         ctx: RequestContext,

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

@@ -572,6 +572,13 @@ export interface OrderOptions {
      * @default DefaultActiveOrderStrategy
      */
     activeOrderStrategy?: ActiveOrderStrategy<any> | Array<ActiveOrderStrategy<any>>;
+    /**
+     * @description
+     * Defines how Orders will be split amongst multiple Channels in a multivendor scenario.
+     *
+     * @since 2.0.0
+     * @default DefaultOrderSellerStrategy
+     */
     orderSellerStrategy?: OrderSellerStrategy;
 }
 
@@ -690,6 +697,14 @@ export interface ShippingOptions {
      * An array of available ShippingCalculators for use in configuring ShippingMethods
      */
     shippingCalculators?: Array<ShippingCalculator<any>>;
+    /**
+     * @description
+     * This strategy is used to assign a given {@link ShippingLine} to one or more {@link OrderLine}s of the Order.
+     * This allows you to set multiple shipping methods for a single order, each assigned a different subset of
+     * OrderLines.
+     *
+     * @since 2.0.0
+     */
     shippingLineAssignmentStrategy?: ShippingLineAssignmentStrategy;
     /**
      * @description

+ 1 - 1
packages/core/src/entity/address/address.entity.ts

@@ -9,7 +9,7 @@ import { Customer } from '../customer/customer.entity';
 
 /**
  * @description
- * Represent's a {@link Customer}'s address.
+ * Represents a {@link Customer}'s address.
  *
  * @docsCategory entities
  */

+ 12 - 26
packages/core/src/service/helpers/order-splitter/order-splitter.ts

@@ -28,7 +28,7 @@ export class OrderSplitter {
         const defaultChannel = await this.channelService.getDefaultChannel(ctx);
 
         order.type = OrderType.Aggregate;
-        order.sellerOrders = [];
+        const sellerOrders: Order[] = [];
         for (const partialOrder of partialOrders) {
             const lines: OrderLine[] = [];
             for (const line of partialOrder.lines) {
@@ -38,14 +38,10 @@ export class OrderSplitter {
             for (const shippingLine of partialOrder.shippingLines) {
                 shippingLines.push(await this.duplicateShippingLine(ctx, shippingLine));
             }
-            const surcharges: Surcharge[] = [];
-            for (const surcharge of partialOrder.surcharges) {
-                surcharges.push(await this.duplicateSurcharge(ctx, surcharge));
-            }
             const sellerOrder = await this.connection.getRepository(ctx, Order).save(
                 new Order({
                     type: OrderType.Seller,
-                    aggregateOrder: order,
+                    aggregateOrderId: order.id,
                     code: await this.configService.orderOptions.orderCodeStrategy.generate(ctx),
                     active: false,
                     orderPlacedAt: new Date(),
@@ -53,7 +49,7 @@ export class OrderSplitter {
                     channels: [new Channel({ id: partialOrder.channelId }), defaultChannel],
                     state: partialOrder.state,
                     lines,
-                    surcharges,
+                    surcharges: [],
                     shippingLines,
                     couponCodes: order.couponCodes,
                     modifications: [],
@@ -65,10 +61,16 @@ export class OrderSplitter {
                 }),
             );
 
-            order.sellerOrders.push(sellerOrder);
+            await this.connection
+                .getRepository(ctx, Order)
+                .createQueryBuilder()
+                .relation('sellerOrders')
+                .of(order)
+                .add(sellerOrder);
             await this.orderService.applyPriceAdjustments(ctx, sellerOrder);
+            sellerOrders.push(sellerOrder);
         }
-        await orderSellerStrategy.afterSellerOrdersCreated?.(ctx, order, order.sellerOrders);
+        await orderSellerStrategy.afterSellerOrdersCreated?.(ctx, order, sellerOrders);
         return order.sellerOrders;
     }
 
@@ -96,7 +98,7 @@ export class OrderSplitter {
                         'taxLines',
                         'cancelled',
                     ]),
-                    line: newLine,
+                    lineId: newLine.id,
                 }),
         );
         await this.connection.getRepository(ctx, OrderItem).save(newLine.items);
@@ -120,20 +122,4 @@ export class OrderSplitter {
             }),
         );
     }
-
-    private async duplicateSurcharge(ctx: RequestContext, surcharge: Surcharge): Promise<Surcharge> {
-        return await this.connection.getRepository(ctx, Surcharge).save(
-            new Surcharge({
-                ...pick(surcharge, [
-                    'description',
-                    'listPrice',
-                    'listPriceIncludesTax',
-                    'sku',
-                    'taxLines',
-                    'order',
-                    'orderModification',
-                ]),
-            }),
-        );
-    }
 }