• checkoutSessionIdとcartIdをそれぞれ受け取る。
  • cartToOrderメソッド発動
    • カートに紐づくcartDeliveryGroupのidを取得
    • mapAndInsertCartToOrderメソッド発動
      • cartの情報を元にorderレコードをinsert
      • 生成したorderレコードのidを返す
    • mapAndInsertCartDeliveryGroupToOrderDeliveryGroupメソッド発動
      • cartDeliveryGroupの情報を元にorderDeliveryGroupレコードをinsert
      • 生成したorderDeliveryGroupレコードのidを返す
    • mapAndInsertCartItemsメソッド発動
      • cartItemを取得
      • OderItem型のリスト変数orderItemsを生成
      • cartitemごとにループさせ、cartItemの情報を元に生成したorderItemレコードのidをorderItems変数にadd
      • orderItemsをinsert
      • OrderItemAdjustmentLineItem型のリスト変数OrderItemAdjustmentsを生成
      • cartItemごとにループ
        • mapOrderItemAdjustmentLineItemToメソッド発動
          • getAdjustmentAmountメソッドを発動
            • cartItemのAdjustmentAmountを返す
        • 上記AdjustmentAmountの値を元にOrderItemAdjustmentLineItemのインスタンスを生成
        • OrderItemAdjustmentLineItemを返す
      • OrderItemAdjustmentLineItemをinsert
    • ID型のリスト変数orderIDsを生成
    • 先ほど返されたorderレコードのIdをOrderIdsにadd
    • orderIdsを返す


public class B2BCartToOrderDraft {

    public class B2BCartToOrderDraftRequest {
        public ID checkoutSessionId;
        public ID cartId;
     * @description Maps a cart to an order. Activates it, and closes the cart. Returns the resulting order summary id.
     * @param request The checkout session and cart id.
     * @return The OrderId that resulted from this class.
    @InvocableMethod(label='Map Cart to Order Draft' description='Maps the cart and related data to an order' category='B2B Commerce')
    public static List<ID> cartToOrder(List<B2BCartToOrderDraftRequest> request) {
        // screen flows do not run in bulk
        Id cartId = request[0].cartId;
        Id checkoutSessionId = request[0].checkoutSessionId;
        // load the primary delivery group (only one supported at this time)
        Id cartDeliveryGroupId = [SELECT Id FROM CartDeliveryGroup WHERE CartId = :cartId][0].Id;

        Id orderId = mapAndInsertCartToOrder(cartId);
        updateCheckoutSession(checkoutSessionId, orderId);
        Id orderDeliveryGroupId = mapAndInsertCartDeliveryGroupToOrderDeliveryGroup(cartDeliveryGroupId, orderId);
        mapAndInsertCartItems(cartDeliveryGroupId, orderId, orderDeliveryGroupId);
        List<ID> orderIds = new List<ID>();
        return orderIds;
     * @description Satisfy the preconditions required to use the following call to Activate the Order
    private static void updateCheckoutSession(Id checkoutSessionId, Id orderId) {
        try {
            CartCheckoutSession checkoutSession = [SELECT OrderId, NextState FROM CartCheckoutSession WHERE Id = :checkoutSessionId LIMIT 1];
            checkoutSession.OrderId = orderId;
            update checkoutSession;
        } catch (Exception e) {
            System.debug('An error occurred updating checkout session with the draft order Id');
     * @description Maps the cart entity to an order entity and returns the id of the order entity that was created.
     * @param cartId The cart id to map to an order.
     * @return The id of the order that was created.
    private static Id mapAndInsertCartToOrder(Id cartId) {
        // Get the cart data needed to populate the order
        List<WebCart> carts = [SELECT Id,
                               FROM WebCart WHERE Id = :cartId];
        WebCart cart = carts[0];
        // Create the order
        Date now = Date.today();    
        Order order = new Order(
            AccountId = cart.AccountId,
            OwnerId = cart.OwnerId,
            SalesStoreId = cart.WebStoreId,
            PoNumber = cart.PoNumber,
            BillingStreet = cart.BillingStreet,
            BillingCity = cart.BillingCity,
            BillingState = cart.BillingState,
            BillingPostalCode = cart.BillingPostalCode,
            BillingCountry = cart.BillingCountry,
            BillingLatitude = cart.BillingLatitude,
            BillingLongitude = cart.BillingLongitude,
            EffectiveDate = now,
            OrderedDate = now,
            Status = 'Draft'
        return order.Id;
     * @description Maps the cart delivery group entity to an order delivery group entity and returns the id of the
     *              order delivery group entity that was created.
     * @param cartDeliveryGroupId The cartDeliveryGroup id to map.
     * @param orderId The orderDeliveryGroup is linked to the original order.
     * @return The id of the order delivery group that was created.
    private static Id mapAndInsertCartDeliveryGroupToOrderDeliveryGroup(Id cartDeliveryGroupId, Id orderId) {
        // Get the cart delivery group data needed to populate the order delivery group
        List<CartDeliveryGroup> cartDeliveryGroups = [SELECT
                                                      FROM CartDeliveryGroup WHERE Id = :cartDeliveryGroupId];
        CartDeliveryGroup cartDeliveryGroup = cartDeliveryGroups[0];
        // Create the order delivery group
        Date desiredDeliveryDate = toDate(cartDeliveryGroup.DesiredDeliveryDate);
        OrderDeliveryGroup orderDeliveryGroup = new OrderDeliveryGroup(
            //Description = cartDeliveryGroup.ShippingRequests__c,
            DesiredDeliveryDate = desiredDeliveryDate,
            DeliverToName = cartDeliveryGroup.DeliverToName,
            DeliveryInstructions = cartDeliveryGroup.ShippingInstructions,
            DeliverToStreet = cartDeliveryGroup.DeliverToStreet,
            DeliverToCity = cartDeliveryGroup.DeliverToCity,
            DeliverToState = cartDeliveryGroup.DeliverToState,
            DeliverToPostalCode = cartDeliveryGroup.DeliverToPostalCode,
            DeliverToCountry = cartDeliveryGroup.DeliverToCountry,
            DeliverToLatitude = cartDeliveryGroup.DeliverToLatitude,
            DeliverToLongitude = cartDeliveryGroup.DeliverToLongitude,
            OrderDeliveryMethodId = cartDeliveryGroup.DeliveryMethodId,
            OrderId = orderId

        return orderDeliveryGroup.Id;
     * @description Maps the cart items to a set of order items. This also creates order item adjustments.
     *              Tax adjustments could probably also be done here, but are not part of the example.
     * @param cartDeliveryGroupId the cartDeliveryGroup id for this set of cart items.
     * @param orderId The items are linked to the original order.
     * @param orderDeliveryGroupId The items are linked to the order delivery group.
    private static void mapAndInsertCartItems(Id cartDeliveryGroupId, Id orderId, Id orderDeliveryGroupId) {
        // Get the cart items needed to populate the order items and adjustments
        List<CartItem> cartItems = [SELECT
                                    FROM CartItem WHERE CartDeliveryGroupId = :cartDeliveryGroupId];
        List<OrderItem> orderItems = new List<OrderItem>();
        // For each item, map it to an order, then add adjustments
        for (CartItem cartItem : cartItems) {
            orderItems.add(mapCartItemToOrderItem(cartItem, orderId, orderDeliveryGroupId));
        // If there are no items to insert, we can't do anything
        if (orderItems.size() == 0 || cartItems.size() != orderItems.size()) {

        List<OrderItemAdjustmentLineItem> lineItemAdjustments = new List<OrderItemAdjustmentLineItem>();
        for (Integer index = 0; index < cartItems.size(); index++) {
            OrderItemAdjustmentLineItem lineItemAdjustment = mapOrderItemAdjustmentLineItemTo(cartItems.get(index), orderItems.get(index).Id);
            if (lineItemAdjustment != null) {
        if (lineItemAdjustments.size() > 0) {
     * @description Maps the cart item to an order item.
     * @param cartItem The cartItem to map to an order item.
     * @param orderId The item is linked to the original order.
     * @param orderDeliveryGroupId The item is linked to the order delivery group.
     * @return The order item to be inserted.
    private static OrderItem mapCartItemToOrderItem(CartItem cartItem, Id orderId, Id orderDeliveryGroupId) {
        String orderItemType = getOrderItemType(cartItem.Type);
        Decimal unitPrice = getUnitPrice(cartItem);
        OrderItem orderItem = new OrderItem(
            Product2Id = cartItem.Product2Id,
            Type = orderItemType,
            Quantity = cartItem.Quantity,
            ListPrice = cartItem.ListPrice,
            UnitPrice = unitPrice,
            OrderId = orderId,
            OrderDeliveryGroupId = orderDeliveryGroupId,
            TotalLineAmount = cartItem.TotalLineAmount
        return orderItem;

     * @description Maps the cart item to create an adjustment line item. If the item would normally cost
     *              $100, but costs $80, this is where that adjustment is recorded.
     * @param cartItem The cartItem to map to an order adjustment line item.
     * @param orderItemId The adjustment is mapped to an order item.
     * @return The order item adjustment to be inserted.
    private static OrderItemAdjustmentLineItem mapOrderItemAdjustmentLineItemTo(CartItem cartItem, Id orderItemId) {
        Decimal adjustmentAmount = getAdjustmentAmount(cartItem);
        if (adjustmentAmount == null || adjustmentAmount == 0.0) {
            return null;
        OrderItemAdjustmentLineItem orderItemAdjustmentLineItem = new OrderItemAdjustmentLineItem(
            Amount = adjustmentAmount,
            OrderItemId = orderItemId,
            Name = 'Price Adjustment'
        return orderItemAdjustmentLineItem;

     * @description Gets the adjustment amount from the cart item. If none exists, returns zero.
     * @param cartItem Where to get the adjustment amount from.
     * @return The adjustment amount (0, if there is no adjustment).
    private static Decimal getAdjustmentAmount(CartItem cartItem) {
        if (cartItem.AdjustmentAmount == null) {
            return 0;
        return cartItem.AdjustmentAmount;
     * @description Gets the order item type from the sales item type. This maps the cart item type to the order item type.
     * @param salesItemType The cart item's type.
     * @return The order Item Type or null if the type doesn't map.
    private static String getOrderItemType(String cartItemType) {
        if (cartItemType == 'Product') {
            return 'Order Product';
        if (cartItemType == 'Charge') {
            return 'Delivery Charge';
        return null;

     * @description Gets the unit price from the cart item. This tries to use the sales price but will default to the list price
     *              if there is no sales price.
     * @param cartItem The item that has the prices.
     * @return The unit price.
    private static Decimal getUnitPrice(CartItem cartItem) {
        if (cartItem.SalesPrice != null) {
            return cartItem.SalesPrice;

        return cartItem.ListPrice;
     * @description Converts a DateTime object to a Date object.
     * @param dt The datetime to convert.
     * @return The new Date.
    private static Date toDate(DateTime dt) {
        if (dt != null) {
            return Date.newinstance(dt.year(), dt.month(), dt.day());
        return null;


Posted by regardie