Contents
問題の概要
B2B Commerce and B2B2C Commerce Developer GuideのUpdate a Checkout Flow to Handle Promotionsに記載がある通り、Winter ’22以前に作成されたカスタムのチェックアウトフローはpromotion capableではないため、こちらに記載の一連の手順に従ってpromotionを利用可能にする必要がある。
しかし、当該の手順に従ってcheckout flowをpromotion capableにした場合でも、Cart To OrderサブフローをB2BCartToOrderDraftを用いてApex化している場合、チェックアウト後のOrderにPromotionによる割引は適用されない。
問題の原因
上記の挙動の原因はB2BCartToOrderDraftのコードをそのまま用いると、Promotionに関するOrderItemAdjustmentLineItemレコードが生成されないという点にある。
そもそもチェックアウトでOrderに対してPromotionを適用するにあたって必要なのは以下の二つである。
- Checkout Summaryサブフローよりも早い段階でCartItemPriceAdjustmentレコードを生成する
- Cart To Orderサブフロー内でOrderItemAdjustmentLineItemレコードを生成する
Update a Checkout Flow to Handle Promotionsにおけるcheckoutのpromotion capable化はまさにこの一点目(すなわち、CartItemPriceAdjustmentが生成されるようにすること)に相当している。
二点目のOrderItemAdjustmentLineItem生成に関して言えば、標準のCartToOderアクションにはデフォルトでCartItemPriceAdjustmentをベースにOrderItemAdjustmentLineItemレコードを作成する機能が備わっているが、B2BCartToOrderDraftのデフォルトコードは価格調整スケジュール(いわゆる数量ディスカウント)についてのみOrderItemAdjustmentLineItemレコードが作成される仕様となっており、CartItemPriceAdjustmentをベースにOrderItemAdjustmentLineItemを作成する仕様とはなっていない。
具体的にどうコードを修正すれば良いのか
B2BCartToOrderDraftのコードを次のように書き換えるとよい。
◼️ASIS
private static Decimal getAdjustmentAmount(CartItem cartItem) {
if (cartItem.AdjustmentAmount == null) {
return 0;
}
return cartItem.AdjustmentAmount;
}
◼️TOBE
private static Decimal getAdjustmentAmount(CartItem cartItem) {
if (cartItem.TotalAdjustmentAmount == null) {
return 0;
}
return cartItem.TotalAdjustmentAmount;
}
価格調整スケジュールとプロモーション
上記の修正の正当性を理解するには、①CartItemのAdjustmentAmountとTotalAdjustmentAmountにどのような相違があるのか②価格調整スケジュールの適用とプロモーションの適用には内部的にどのような違いがあるのか、の二点に関して正確な理解を持っておく必要がある。
割引に関連するオブジェクトについて、価格調整スケジュールとプロモーションを比較してみると、以下の結果が得られる。
◼️CartItem
価格調整 | Promotion | |
Adjustment Amount | -2000 | 0 |
TotalPromoAdjustmentAmount | 0 | -19000 |
TotalAdjustmentAmount | -2000 | -19000 |
◼️CartItemPriceAdjustment
価格調整:レコードなし
Promotion:レコードあり
◼️OrderItem
価格調整 | Promotion | |
TotalLineAmount | 30000 | 30000 |
TotalPrice | 28000 | 11000 |
◼️OrderItemSummary
価格調整 | Promotion | |
TotalLineAmount | 30000 | 30000 |
TotalPrice | 28000 | 11000 |
TotalAdjustmentAmount | -2000 | -19000 |
TotalLineAdjustmentAmount | -2000 | -19000 |
◼️OrderItemAdjustmentLineItem
価格調整:レコードあり
Promotion:レコードあり
価格調整スケジュールとプロモーションの内部的な相違
上記の比較から明らかな通り、(注文生成の前段階での)価格調整スケジュールとプロモーションの主な違いとして、以下を指摘することができる。
- 割引金額が入るCartItemの項目
- 価格調整スケジュール:Adjustment Amount
- プロモーション:TotalPromoAdjustmentAmount
- CartItemPriceAdjustmentレコードの生成有無
- 格調整スケジュール:レコードが作成されない
- プロモーション:レコードが作成される
実装にあたって重大な考慮事項
ここまで、CartToOrderをApex化している場合のPromotionへの対応方法について記述してきたが、実際のところ本件への推奨アプローチはCartToOrderの標準サブフローの利用である。
というのも、Spring’23 UpdateでB2B CommerceのCartToOrderコアアクションがカスタム項目のCartからOrderへの(API参照名ベースでの)自動マッピングに対応したことで、CartToOrderをApex化する必然性が失われてしまったからである。
現在、多くのユースケースはCartToOrderコアアクションとそれより手前の段階でのビジネスロジックの実行によって解決可能なものとなっている。