From 2a8f162af94d645344af52b48bd05762c3d3f0eb Mon Sep 17 00:00:00 2001 From: Ghata Mehta Date: Mon, 28 Mar 2022 13:35:08 +1100 Subject: [PATCH] SFCC Cartridge v23.2.0-beta * Customers can place pre-orders/backorders without paying upfront --- .../scripts/checkout/afterpayUpdateOrder.js | 3 + .../logic/services/afterpayHttpService.js | 4 +- .../scripts/order/orderRequestBuilder.js | 62 +++++++++++++++++-- .../scripts/util/afterpayConstants.js | 1 + .../checkout/afterpayPreOrderHelpers.js | 19 ++++++ .../scripts/checkout/updatePaymentStatus.js | 2 +- .../checkout/afterpayPreOrderHelpers.js | 19 ++++++ .../scripts/checkout/updatePaymentStatus.js | 2 +- .../checkout/afterpayPreOrderHelpers.js | 7 +++ .../scripts/payment/processor/AFTERPAY.js | 2 +- .../scripts/payment/processor/CLEARPAY.js | 2 +- package.json | 2 +- 12 files changed, 112 insertions(+), 13 deletions(-) create mode 100644 cartridges/int_afterpay_sfra/cartridge/scripts/checkout/afterpayPreOrderHelpers.js create mode 100644 cartridges/int_afterpay_sfra_6/cartridge/scripts/checkout/afterpayPreOrderHelpers.js create mode 100644 cartridges/int_afterpay_sg/cartridge/scripts/checkout/afterpayPreOrderHelpers.js diff --git a/cartridges/int_afterpay_core/cartridge/scripts/checkout/afterpayUpdateOrder.js b/cartridges/int_afterpay_core/cartridge/scripts/checkout/afterpayUpdateOrder.js index ea98249..6fe4614 100644 --- a/cartridges/int_afterpay_core/cartridge/scripts/checkout/afterpayUpdateOrder.js +++ b/cartridges/int_afterpay_core/cartridge/scripts/checkout/afterpayUpdateOrder.js @@ -57,6 +57,9 @@ var afterpayUpdateOrder = { amount = empty(paymentResult.openToCaptureAmount) ? null : new Money(parseFloat(paymentResult.openToCaptureAmount.amount), paymentResult.openToCaptureAmount.currency); } + if(paymentResult.status === afterpayConstants.PAYMENT_STATUS.ACTIVE && amount === null ){ + amount = empty(paymentResult.amount) ? null : new Money(parseFloat(paymentResult.amount.amount), paymentResult.amount.currency); + } payTrans.setAmount(amount); }); diff --git a/cartridges/int_afterpay_core/cartridge/scripts/logic/services/afterpayHttpService.js b/cartridges/int_afterpay_core/cartridge/scripts/logic/services/afterpayHttpService.js index 53dbc26..b9211be 100644 --- a/cartridges/int_afterpay_core/cartridge/scripts/logic/services/afterpayHttpService.js +++ b/cartridges/int_afterpay_core/cartridge/scripts/logic/services/afterpayHttpService.js @@ -42,7 +42,7 @@ function getAfterpayHttpService() { service.setRequestMethod(requestBody.requestMethod); service.addHeader('Content-Type', 'application/json'); - const afterpayCartridge = 'AfterpayCartridge/23.1.0'; + const afterpayCartridge = 'AfterpayCartridge/23.2.0-beta'; const merchantID = 'Merchant/' + service.configuration.credential.user; const siteURL = URLUtils.httpsHome().toString(); const storeFront = Site.getCurrent().getID(); @@ -67,7 +67,7 @@ function getAfterpayHttpService() { }, parseResponse: function (service, httpClient) { - if (httpClient.statusCode === 200 || httpClient.statusCode === 201) { + if (httpClient.statusCode === 200 || httpClient.statusCode === 201 || httpClient.statusCode === 202) { var parseResponse = httpClient.text; var filterResponse = parseResponse; Logger.debug('Parsed Response : ' + afterpayUtils.filterLogData(filterResponse)); diff --git a/cartridges/int_afterpay_core/cartridge/scripts/order/orderRequestBuilder.js b/cartridges/int_afterpay_core/cartridge/scripts/order/orderRequestBuilder.js index a73b672..762050a 100644 --- a/cartridges/int_afterpay_core/cartridge/scripts/order/orderRequestBuilder.js +++ b/cartridges/int_afterpay_core/cartridge/scripts/order/orderRequestBuilder.js @@ -2,7 +2,6 @@ var Resource = require('dw/web/Resource'); var TaxMgr = require('dw/order/TaxMgr'); - var Builder = require('../util/builder'); var { checkoutUtilities, brandUtilities, sitePreferencesUtilities } = require('*/cartridge/scripts/util/afterpayUtilities'); var Order = require('*/cartridge/scripts/order/order'); @@ -105,6 +104,7 @@ OrderRequestBuilder.prototype.buildRequest = function (params) { .buildItems(basket) .applyDiscounts(basket) .buildTotalAmount(basket) + .buildInitialOrderAmount(basket) .buildShippingAmount(basket) .buildTotalTax(basket) .buildMerchantInformation(url) @@ -234,7 +234,7 @@ OrderRequestBuilder.prototype.buildItems = function (basket) { var lineItems = basket.getAllProductLineItems().toArray(); this.context.items = lineItems.map(function (li) { - var item = new LineItem(); + var item = new LineItem(); var product = li.product; // Some lineitems may not be products @@ -246,11 +246,11 @@ OrderRequestBuilder.prototype.buildItems = function (basket) { item.price.amount = li.adjustedNetPrice.value; item.price.currency = li.adjustedNetPrice.currencyCode; } else { - item.name = product.name; - item.sku = product.ID; + item.name = product.name; + item.sku = product.ID; item.quantity = li.getQuantity().value; item.price.amount = product.getPriceModel().getPrice().value; - item.price.currency = product.getPriceModel().getPrice().currencyCode; + item.price.currency = product.getPriceModel().getPrice().currencyCode; } return item; }); @@ -300,6 +300,57 @@ OrderRequestBuilder.prototype.applyDiscounts = function (basket) { return this; }; +/** + * builds initial order amount details + * @param {dw.order.Basket} basket - basket + * @returns {Object} - this object + */ +// eslint-disable-next-line no-unused-vars +OrderRequestBuilder.prototype.buildInitialOrderAmount = function (basket) { + var paymentTransaction = this._getPaymentTransaction(basket); + var preOrderHelper = require('*/cartridge/scripts/checkout/afterpayPreOrderHelpers'); + var productAvailabilityModel = require('dw/catalog/ProductAvailabilityModel'); + var ProductMgr = require('dw/catalog/ProductMgr'); + var Amount = require('*/cartridge/scripts/order/amount'); + + if (!paymentTransaction) { + return this; + } + var productLineItems = basket.getAllProductLineItems().iterator(); + var preOrderAmount = 0.00; + + while (productLineItems.hasNext()) { + var productLineItem = productLineItems.next(); + var product = productLineItem.product; + + if (!product) { + var parentProductID = productLineItem.parent.productID; + product = ProductMgr.getProduct(parentProductID); + } + + if(product){ + var productAvailabiltyStatus = product.availabilityModel.getAvailabilityStatus(); + if(productAvailabiltyStatus == productAvailabilityModel.AVAILABILITY_STATUS_PREORDER || productAvailabiltyStatus == productAvailabilityModel.AVAILABILITY_STATUS_BACKORDER){ + var productPrice = productLineItem.proratedPrice.value; + preOrderAmount += productPrice; + } + } + } + + var orderSubTotal = preOrderHelper.getCartSubtotal(basket);; + + if(preOrderAmount > 0 && orderSubTotal){ + var initialOrderAmount = (paymentTransaction.amount.value - preOrderAmount).toFixed(2); + if((orderSubTotal - preOrderAmount).toFixed(2) == 0){ + initialOrderAmount = 0.00; + } + this.context.initialOrderAmount = new Amount(); + this.context.initialOrderAmount.amount = initialOrderAmount; + this.context.initialOrderAmount.currency = basket.getCurrencyCode(); + } + + return this; +}; /** * builds total amount details @@ -375,5 +426,4 @@ OrderRequestBuilder.prototype._buildShiptoStore = function(type, store) { this.context[type].phoneNumber = store.phone || ''; }; - module.exports = OrderRequestBuilder; diff --git a/cartridges/int_afterpay_core/cartridge/scripts/util/afterpayConstants.js b/cartridges/int_afterpay_core/cartridge/scripts/util/afterpayConstants.js index 4a9e3bb..fd1ea56 100644 --- a/cartridges/int_afterpay_core/cartridge/scripts/util/afterpayConstants.js +++ b/cartridges/int_afterpay_core/cartridge/scripts/util/afterpayConstants.js @@ -7,6 +7,7 @@ var PAYMENT_STATUS = { FAILED: 'FAILED', PENDING: 'PENDING', SUCCESS: 'SUCCESS', + ACTIVE: 'ACTIVE', UNKNOWN: 'Payment was Declined by Afterpay' }; diff --git a/cartridges/int_afterpay_sfra/cartridge/scripts/checkout/afterpayPreOrderHelpers.js b/cartridges/int_afterpay_sfra/cartridge/scripts/checkout/afterpayPreOrderHelpers.js new file mode 100644 index 0000000..04105cd --- /dev/null +++ b/cartridges/int_afterpay_sfra/cartridge/scripts/checkout/afterpayPreOrderHelpers.js @@ -0,0 +1,19 @@ +var afterpayPreOrderTools = { + getCartSubtotal: function (basket) { + var parsePrice = require('~/cartridge/scripts/util/parsePriceAfterpay.js'); + if(basket){ + var TotalsModel = require('*/cartridge/models/totals'); + var totalsModel = new TotalsModel(basket); + var orderSubTotal = parsePrice(totalsModel.subTotal); + var cartDiscount = totalsModel.orderLevelDiscountTotal.value; + if(cartDiscount !== 0){ + orderSubTotal = (orderSubTotal - cartDiscount).toFixed(2); + } + return orderSubTotal; + } else { + return false; + } + } +} + +module.exports = afterpayPreOrderTools; diff --git a/cartridges/int_afterpay_sfra/cartridge/scripts/checkout/updatePaymentStatus.js b/cartridges/int_afterpay_sfra/cartridge/scripts/checkout/updatePaymentStatus.js index b951092..15113ec 100644 --- a/cartridges/int_afterpay_sfra/cartridge/scripts/checkout/updatePaymentStatus.js +++ b/cartridges/int_afterpay_sfra/cartridge/scripts/checkout/updatePaymentStatus.js @@ -86,7 +86,7 @@ updatePaymentStatus.handlePaymentStatus = function (order) { Logger.debug('Afterpay final payment status :' + finalPaymentStatus); - if (finalPaymentStatus === 'APPROVED') { + if (finalPaymentStatus === 'APPROVED' || finalPaymentStatus === 'ACTIVE') { return { authorized: true }; } else if (finalPaymentStatus === 'PENDING') { return { diff --git a/cartridges/int_afterpay_sfra_6/cartridge/scripts/checkout/afterpayPreOrderHelpers.js b/cartridges/int_afterpay_sfra_6/cartridge/scripts/checkout/afterpayPreOrderHelpers.js new file mode 100644 index 0000000..04105cd --- /dev/null +++ b/cartridges/int_afterpay_sfra_6/cartridge/scripts/checkout/afterpayPreOrderHelpers.js @@ -0,0 +1,19 @@ +var afterpayPreOrderTools = { + getCartSubtotal: function (basket) { + var parsePrice = require('~/cartridge/scripts/util/parsePriceAfterpay.js'); + if(basket){ + var TotalsModel = require('*/cartridge/models/totals'); + var totalsModel = new TotalsModel(basket); + var orderSubTotal = parsePrice(totalsModel.subTotal); + var cartDiscount = totalsModel.orderLevelDiscountTotal.value; + if(cartDiscount !== 0){ + orderSubTotal = (orderSubTotal - cartDiscount).toFixed(2); + } + return orderSubTotal; + } else { + return false; + } + } +} + +module.exports = afterpayPreOrderTools; diff --git a/cartridges/int_afterpay_sfra_6/cartridge/scripts/checkout/updatePaymentStatus.js b/cartridges/int_afterpay_sfra_6/cartridge/scripts/checkout/updatePaymentStatus.js index b951092..15113ec 100644 --- a/cartridges/int_afterpay_sfra_6/cartridge/scripts/checkout/updatePaymentStatus.js +++ b/cartridges/int_afterpay_sfra_6/cartridge/scripts/checkout/updatePaymentStatus.js @@ -86,7 +86,7 @@ updatePaymentStatus.handlePaymentStatus = function (order) { Logger.debug('Afterpay final payment status :' + finalPaymentStatus); - if (finalPaymentStatus === 'APPROVED') { + if (finalPaymentStatus === 'APPROVED' || finalPaymentStatus === 'ACTIVE') { return { authorized: true }; } else if (finalPaymentStatus === 'PENDING') { return { diff --git a/cartridges/int_afterpay_sg/cartridge/scripts/checkout/afterpayPreOrderHelpers.js b/cartridges/int_afterpay_sg/cartridge/scripts/checkout/afterpayPreOrderHelpers.js new file mode 100644 index 0000000..e03a3be --- /dev/null +++ b/cartridges/int_afterpay_sg/cartridge/scripts/checkout/afterpayPreOrderHelpers.js @@ -0,0 +1,7 @@ +var afterpayPreOrderTools = { + getCartSubtotal: function (basket) { + return basket.getAdjustedMerchandizeTotalNetPrice(); + } +} + +module.exports = afterpayPreOrderTools; diff --git a/cartridges/int_afterpay_sg/cartridge/scripts/payment/processor/AFTERPAY.js b/cartridges/int_afterpay_sg/cartridge/scripts/payment/processor/AFTERPAY.js index a4d3e0c..dc28765 100644 --- a/cartridges/int_afterpay_sg/cartridge/scripts/payment/processor/AFTERPAY.js +++ b/cartridges/int_afterpay_sg/cartridge/scripts/payment/processor/AFTERPAY.js @@ -128,7 +128,7 @@ function Authorise(args) { Logger.debug('Afterpay final payment status :' + finalPaymentStatus); - if (finalPaymentStatus === 'APPROVED') { + if (finalPaymentStatus === 'APPROVED' || finalPaymentStatus === 'ACTIVE') { return { authorized: true }; } else if (finalPaymentStatus === 'PENDING') { return { diff --git a/cartridges/int_afterpay_sg/cartridge/scripts/payment/processor/CLEARPAY.js b/cartridges/int_afterpay_sg/cartridge/scripts/payment/processor/CLEARPAY.js index 040f5d9..d7679b5 100644 --- a/cartridges/int_afterpay_sg/cartridge/scripts/payment/processor/CLEARPAY.js +++ b/cartridges/int_afterpay_sg/cartridge/scripts/payment/processor/CLEARPAY.js @@ -129,7 +129,7 @@ function Authorise(args) { Logger.debug('Afterpay final payment status :' + finalPaymentStatus); - if (finalPaymentStatus === 'APPROVED') { + if (finalPaymentStatus === 'APPROVED' || finalPaymentStatus === 'ACTIVE') { return { authorized: true }; } else if (finalPaymentStatus === 'PENDING') { return { diff --git a/package.json b/package.json index 76d45cb..8a6afe1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Afterpay", - "version": "23.1.0", + "version": "23.2.0-beta", "description": "Afterpay cartridge", "main": "index.js", "engines": {