addio-admin-sdk 1.7.103 → 1.7.104
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/Interfaces/Attribute/index.d.ts +1 -0
- package/dist/Interfaces/CMS/index.d.ts +3 -0
- package/dist/Interfaces/CMS/index.js +3 -0
- package/dist/Interfaces/CMS/index.js.map +1 -1
- package/dist/Interfaces/Cart/index.js +6 -2
- package/dist/Interfaces/Cart/index.js.map +1 -1
- package/dist/Interfaces/CartReservedQuantities/index.d.ts +2 -0
- package/dist/Interfaces/Customer/IStoreCredit.d.ts +1 -0
- package/dist/Interfaces/Customer/index.d.ts +7 -0
- package/dist/Interfaces/Customer/index.js +7 -0
- package/dist/Interfaces/Customer/index.js.map +1 -1
- package/dist/Interfaces/Declination/index.js +8 -2
- package/dist/Interfaces/Declination/index.js.map +1 -1
- package/dist/Interfaces/Email/IEmail.js +7 -3
- package/dist/Interfaces/Email/IEmail.js.map +1 -1
- package/dist/Interfaces/G2/index.js +2 -0
- package/dist/Interfaces/G2/index.js.map +1 -1
- package/dist/Interfaces/Indexed/Product/index.d.ts +3 -0
- package/dist/Interfaces/Indexed/Product/index.js +43 -2
- package/dist/Interfaces/Indexed/Product/index.js.map +1 -1
- package/dist/Interfaces/Menu/index.d.ts +11 -0
- package/dist/Interfaces/Product/IImportProduct.js +94 -3
- package/dist/Interfaces/Product/IImportProduct.js.map +1 -1
- package/dist/Interfaces/Product/IInventoryItem.d.ts +11 -27
- package/dist/Interfaces/Product/IInventoryItem.js +13 -4
- package/dist/Interfaces/Product/IInventoryItem.js.map +1 -1
- package/dist/Interfaces/Product/IPricing.js +6 -0
- package/dist/Interfaces/Product/IPricing.js.map +1 -1
- package/dist/Interfaces/Product/index.d.ts +8 -0
- package/dist/Interfaces/Product/index.js +8 -0
- package/dist/Interfaces/Product/index.js.map +1 -1
- package/dist/Interfaces/PromiseToPurchase/IIndexedBankUsed.js +1 -1
- package/dist/Interfaces/PromiseToPurchase/IIndexedBankUsed.js.map +1 -1
- package/dist/Interfaces/Rules/IDiscountRule.d.ts +18 -0
- package/dist/Interfaces/Rules/IDiscountRule.js +19 -0
- package/dist/Interfaces/Rules/IDiscountRule.js.map +1 -1
- package/dist/Interfaces/Services/IService.d.ts +4 -0
- package/dist/Interfaces/Shipping/Shiptime/order.js +23 -0
- package/dist/Interfaces/Shipping/Shiptime/order.js.map +1 -1
- package/dist/Interfaces/Space/index.d.ts +8 -0
- package/dist/Interfaces/Space/index.js +9 -0
- package/dist/Interfaces/Space/index.js.map +1 -1
- package/dist/Interfaces/TCG/index.d.ts +12 -1
- package/dist/Interfaces/TCG/index.js +11 -0
- package/dist/Interfaces/TCG/index.js.map +1 -1
- package/dist/Interfaces/TransferRequest/index.js +3 -0
- package/dist/Interfaces/TransferRequest/index.js.map +1 -1
- package/dist/constants/services.js +1 -0
- package/dist/constants/services.js.map +1 -1
- package/dist/index.d.ts +18 -0
- package/dist/index.js +24 -0
- package/dist/index.js.map +1 -1
- package/dist/lib/Attribute/index.js +43 -0
- package/dist/lib/Attribute/index.js.map +1 -1
- package/dist/lib/BGJob/index.js +5 -1
- package/dist/lib/BGJob/index.js.map +1 -1
- package/dist/lib/Booking/index.d.ts +15 -0
- package/dist/lib/Booking/index.js +20 -0
- package/dist/lib/Booking/index.js.map +1 -1
- package/dist/lib/Brand/index.d.ts +9 -0
- package/dist/lib/Brand/index.js +18 -0
- package/dist/lib/Brand/index.js.map +1 -1
- package/dist/lib/Cart/index.d.ts +99 -0
- package/dist/lib/Cart/index.js +498 -9
- package/dist/lib/Cart/index.js.map +1 -1
- package/dist/lib/CartReservedQuantities/index.d.ts +29 -0
- package/dist/lib/CartReservedQuantities/index.js +41 -0
- package/dist/lib/CartReservedQuantities/index.js.map +1 -1
- package/dist/lib/Catalogue/index.d.ts +6 -0
- package/dist/lib/Catalogue/index.js +9 -0
- package/dist/lib/Catalogue/index.js.map +1 -1
- package/dist/lib/Category/index.d.ts +6 -0
- package/dist/lib/Category/index.js +15 -0
- package/dist/lib/Category/index.js.map +1 -1
- package/dist/lib/Class/index.d.ts +4 -0
- package/dist/lib/Class/index.js +8 -0
- package/dist/lib/Class/index.js.map +1 -1
- package/dist/lib/Customer/index.d.ts +12 -0
- package/dist/lib/Customer/index.js +13 -0
- package/dist/lib/Customer/index.js.map +1 -1
- package/dist/lib/Declination/index.js +2 -0
- package/dist/lib/Declination/index.js.map +1 -1
- package/dist/lib/Discount/index.d.ts +9 -0
- package/dist/lib/Discount/index.js +23 -0
- package/dist/lib/Discount/index.js.map +1 -1
- package/dist/lib/ElasticSearch/index.d.ts +5 -0
- package/dist/lib/ElasticSearch/index.js +5 -0
- package/dist/lib/ElasticSearch/index.js.map +1 -1
- package/dist/lib/Elavon/index.js +5 -0
- package/dist/lib/Elavon/index.js.map +1 -1
- package/dist/lib/Email/AbandonedCartEmail.d.ts +8 -0
- package/dist/lib/Email/AbandonedCartEmail.js +8 -0
- package/dist/lib/Email/AbandonedCartEmail.js.map +1 -1
- package/dist/lib/Email/AccountConfirmationEmail.d.ts +8 -0
- package/dist/lib/Email/AccountConfirmationEmail.js +8 -0
- package/dist/lib/Email/AccountConfirmationEmail.js.map +1 -1
- package/dist/lib/Email/AdminOrderConfirmationEmail.d.ts +8 -0
- package/dist/lib/Email/AdminOrderConfirmationEmail.js +8 -0
- package/dist/lib/Email/AdminOrderConfirmationEmail.js.map +1 -1
- package/dist/lib/Email/ApplicationEmail.d.ts +8 -0
- package/dist/lib/Email/ApplicationEmail.js +8 -0
- package/dist/lib/Email/ApplicationEmail.js.map +1 -1
- package/dist/lib/Email/BackInStockEmail.d.ts +8 -0
- package/dist/lib/Email/BackInStockEmail.js +8 -0
- package/dist/lib/Email/BackInStockEmail.js.map +1 -1
- package/dist/lib/Email/ContactEmail.d.ts +8 -0
- package/dist/lib/Email/ContactEmail.js +8 -0
- package/dist/lib/Email/ContactEmail.js.map +1 -1
- package/dist/lib/Email/CustomerBookingAdminEmail.d.ts +8 -0
- package/dist/lib/Email/CustomerBookingAdminEmail.js +8 -0
- package/dist/lib/Email/CustomerBookingAdminEmail.js.map +1 -1
- package/dist/lib/Email/CustomerBookingEmail.d.ts +8 -0
- package/dist/lib/Email/CustomerBookingEmail.js +8 -0
- package/dist/lib/Email/CustomerBookingEmail.js.map +1 -1
- package/dist/lib/Email/OrderConfirmationEmail.d.ts +8 -0
- package/dist/lib/Email/OrderConfirmationEmail.js +8 -0
- package/dist/lib/Email/OrderConfirmationEmail.js.map +1 -1
- package/dist/lib/Email/OrderDenounciationEmail.d.ts +8 -0
- package/dist/lib/Email/OrderDenounciationEmail.js +8 -0
- package/dist/lib/Email/OrderDenounciationEmail.js.map +1 -1
- package/dist/lib/Email/OrderSampleEmail.d.ts +8 -0
- package/dist/lib/Email/OrderSampleEmail.js +8 -0
- package/dist/lib/Email/OrderSampleEmail.js.map +1 -1
- package/dist/lib/Email/OtherTypeEmails.d.ts +8 -0
- package/dist/lib/Email/OtherTypeEmails.js +8 -0
- package/dist/lib/Email/OtherTypeEmails.js.map +1 -1
- package/dist/lib/Email/PasswordResetEmail.d.ts +8 -0
- package/dist/lib/Email/PasswordResetEmail.js +8 -0
- package/dist/lib/Email/PasswordResetEmail.js.map +1 -1
- package/dist/lib/Email/PhotoShootEmail.d.ts +8 -0
- package/dist/lib/Email/PhotoShootEmail.js +8 -0
- package/dist/lib/Email/PhotoShootEmail.js.map +1 -1
- package/dist/lib/Email/PickUpConfirmation.d.ts +8 -0
- package/dist/lib/Email/PickUpConfirmation.js +8 -0
- package/dist/lib/Email/PickUpConfirmation.js.map +1 -1
- package/dist/lib/Email/ShippingConfirmation.d.ts +8 -0
- package/dist/lib/Email/ShippingConfirmation.js +8 -0
- package/dist/lib/Email/ShippingConfirmation.js.map +1 -1
- package/dist/lib/Email/WelcomeEmail.d.ts +8 -0
- package/dist/lib/Email/WelcomeEmail.js +8 -0
- package/dist/lib/Email/WelcomeEmail.js.map +1 -1
- package/dist/lib/Email/index.d.ts +8 -0
- package/dist/lib/Email/index.js +8 -0
- package/dist/lib/Email/index.js.map +1 -1
- package/dist/lib/ExternalService/Ebay.d.ts +12 -0
- package/dist/lib/ExternalService/Ebay.js +22 -0
- package/dist/lib/ExternalService/Ebay.js.map +1 -1
- package/dist/lib/Indexed/IndexedCart.js +5 -0
- package/dist/lib/Indexed/IndexedCart.js.map +1 -1
- package/dist/lib/Indexed/Product.js +50 -0
- package/dist/lib/Indexed/Product.js.map +1 -1
- package/dist/lib/Inventory/index.d.ts +59 -0
- package/dist/lib/Inventory/index.js +157 -9
- package/dist/lib/Inventory/index.js.map +1 -1
- package/dist/lib/Invoice/index.d.ts +11 -0
- package/dist/lib/Invoice/index.js +11 -0
- package/dist/lib/Invoice/index.js.map +1 -1
- package/dist/lib/MarketplacePublication/index.js +308 -0
- package/dist/lib/MarketplacePublication/index.js.map +1 -1
- package/dist/lib/Menu/index.js +2 -0
- package/dist/lib/Menu/index.js.map +1 -1
- package/dist/lib/Order/index.d.ts +20 -0
- package/dist/lib/Order/index.js +23 -0
- package/dist/lib/Order/index.js.map +1 -1
- package/dist/lib/Org/index.d.ts +41 -0
- package/dist/lib/Org/index.js +41 -0
- package/dist/lib/Org/index.js.map +1 -1
- package/dist/lib/PandaPay/index.js +6 -0
- package/dist/lib/PandaPay/index.js.map +1 -1
- package/dist/lib/Paysafe/index.js +1 -0
- package/dist/lib/Paysafe/index.js.map +1 -1
- package/dist/lib/Product/index.d.ts +25 -0
- package/dist/lib/Product/index.js +55 -1
- package/dist/lib/Product/index.js.map +1 -1
- package/dist/lib/PromiseToPurchase/index.d.ts +72 -0
- package/dist/lib/PromiseToPurchase/index.js +79 -0
- package/dist/lib/PromiseToPurchase/index.js.map +1 -1
- package/dist/lib/PurchaseOrder/index.d.ts +11 -0
- package/dist/lib/PurchaseOrder/index.js +12 -0
- package/dist/lib/PurchaseOrder/index.js.map +1 -1
- package/dist/lib/Service/index.d.ts +8 -0
- package/dist/lib/Service/index.js +8 -0
- package/dist/lib/Service/index.js.map +1 -1
- package/dist/lib/Shipment/index.js +13 -0
- package/dist/lib/Shipment/index.js.map +1 -1
- package/dist/lib/Slider/index.d.ts +6 -0
- package/dist/lib/Slider/index.js +6 -0
- package/dist/lib/Slider/index.js.map +1 -1
- package/dist/lib/Space/index.d.ts +178 -0
- package/dist/lib/Space/index.js +495 -6
- package/dist/lib/Space/index.js.map +1 -1
- package/dist/lib/Supplier/index.js +5 -0
- package/dist/lib/Supplier/index.js.map +1 -1
- package/dist/lib/Tags/index.js +5 -0
- package/dist/lib/Tags/index.js.map +1 -1
- package/dist/lib/TransferRequest/index.d.ts +178 -0
- package/dist/lib/TransferRequest/index.js +236 -4
- package/dist/lib/TransferRequest/index.js.map +1 -1
- package/dist/lib/User/index.d.ts +54 -0
- package/dist/lib/User/index.js +101 -21
- package/dist/lib/User/index.js.map +1 -1
- package/dist/lib/baseService.js +26 -0
- package/dist/lib/baseService.js.map +1 -1
- package/dist/rules/GR/constants/data.js +22 -0
- package/dist/rules/GR/constants/data.js.map +1 -1
- package/dist/rules/GR/constants/products.d.ts +3 -0
- package/dist/rules/GR/constants/products.js +16 -0
- package/dist/rules/GR/constants/products.js.map +1 -1
- package/dist/rules/GR/interfaces/data.js +7 -1
- package/dist/rules/GR/interfaces/data.js.map +1 -1
- package/dist/rules/GR/utils/cart.d.ts +41 -0
- package/dist/rules/GR/utils/cart.js +107 -1
- package/dist/rules/GR/utils/cart.js.map +1 -1
- package/dist/rules/GR/utils/data.js +4 -1
- package/dist/rules/GR/utils/data.js.map +1 -1
- package/dist/rules/GR/utils/expedition.d.ts +69 -0
- package/dist/rules/GR/utils/expedition.js +399 -11
- package/dist/rules/GR/utils/expedition.js.map +1 -1
- package/dist/rules/GR/utils/g2.d.ts +33 -0
- package/dist/rules/GR/utils/g2.js +135 -3
- package/dist/rules/GR/utils/g2.js.map +1 -1
- package/dist/rules/GR/utils/invoices.d.ts +27 -0
- package/dist/rules/GR/utils/invoices.js +41 -0
- package/dist/rules/GR/utils/invoices.js.map +1 -1
- package/dist/rules/GR/utils/products.d.ts +161 -0
- package/dist/rules/GR/utils/products.js +272 -1
- package/dist/rules/GR/utils/products.js.map +1 -1
- package/dist/rules/GR/utils/upsells.d.ts +32 -0
- package/dist/rules/GR/utils/upsells.js +32 -0
- package/dist/rules/GR/utils/upsells.js.map +1 -1
- package/dist/services/database/DatabaseService.d.ts +84 -0
- package/dist/services/database/DatabaseService.js +85 -0
- package/dist/services/database/DatabaseService.js.map +1 -1
- package/dist/services/database/FirebaseProvider.js +17 -0
- package/dist/services/database/FirebaseProvider.js.map +1 -1
- package/dist/services/database/NotFirebaseProvider.d.ts +14 -0
- package/dist/services/database/NotFirebaseProvider.js +19 -0
- package/dist/services/database/NotFirebaseProvider.js.map +1 -1
- package/dist/services/g2/G2OrderSlip.d.ts +7 -0
- package/dist/services/g2/G2OrderSlip.js +18 -0
- package/dist/services/g2/G2OrderSlip.js.map +1 -1
- package/dist/services/g2/utils.d.ts +10 -0
- package/dist/services/g2/utils.js +189 -3
- package/dist/services/g2/utils.js.map +1 -1
- package/dist/services/logs/index.d.ts +3 -0
- package/dist/services/logs/index.js +6 -1
- package/dist/services/logs/index.js.map +1 -1
- package/dist/services/products/BaseClass.js +2 -0
- package/dist/services/products/BaseClass.js.map +1 -1
- package/dist/services/products/TCGService.js +17 -1
- package/dist/services/products/TCGService.js.map +1 -1
- package/dist/services/products/utils.d.ts +22 -0
- package/dist/services/products/utils.js +50 -0
- package/dist/services/products/utils.js.map +1 -1
- package/dist/utils/anonymisation.d.ts +24 -0
- package/dist/utils/anonymisation.js +30 -0
- package/dist/utils/anonymisation.js.map +1 -1
- package/dist/utils/aws.d.ts +22 -0
- package/dist/utils/aws.js +28 -0
- package/dist/utils/aws.js.map +1 -1
- package/dist/utils/booking.d.ts +8 -0
- package/dist/utils/booking.js +9 -0
- package/dist/utils/booking.js.map +1 -1
- package/dist/utils/cart.d.ts +81 -0
- package/dist/utils/cart.js +172 -9
- package/dist/utils/cart.js.map +1 -1
- package/dist/utils/context.js +2 -2
- package/dist/utils/context.js.map +1 -1
- package/dist/utils/currency.js +31 -1
- package/dist/utils/currency.js.map +1 -1
- package/dist/utils/data.js +2 -0
- package/dist/utils/data.js.map +1 -1
- package/dist/utils/discount.d.ts +118 -0
- package/dist/utils/discount.js +178 -1
- package/dist/utils/discount.js.map +1 -1
- package/dist/utils/file-admin.js +1 -0
- package/dist/utils/file-admin.js.map +1 -1
- package/dist/utils/file.js +9 -1
- package/dist/utils/file.js.map +1 -1
- package/dist/utils/firebase-admin.d.ts +9 -0
- package/dist/utils/firebase-admin.js +12 -0
- package/dist/utils/firebase-admin.js.map +1 -1
- package/dist/utils/firebase.d.ts +17 -0
- package/dist/utils/firebase.js +17 -0
- package/dist/utils/firebase.js.map +1 -1
- package/dist/utils/inventories.d.ts +52 -0
- package/dist/utils/inventories.js +77 -2
- package/dist/utils/inventories.js.map +1 -1
- package/dist/utils/locale.d.ts +9 -0
- package/dist/utils/locale.js +9 -0
- package/dist/utils/locale.js.map +1 -1
- package/dist/utils/mailchimp.js +36 -0
- package/dist/utils/mailchimp.js.map +1 -1
- package/dist/utils/mathUtils.js +9 -0
- package/dist/utils/mathUtils.js.map +1 -1
- package/dist/utils/object.d.ts +19 -0
- package/dist/utils/object.js +21 -3
- package/dist/utils/object.js.map +1 -1
- package/dist/utils/products.d.ts +7 -0
- package/dist/utils/products.js +9 -0
- package/dist/utils/products.js.map +1 -1
- package/dist/utils/promiseToPurchase.d.ts +32 -0
- package/dist/utils/promiseToPurchase.js +34 -0
- package/dist/utils/promiseToPurchase.js.map +1 -1
- package/dist/utils/prosprsearch.d.ts +15 -0
- package/dist/utils/prosprsearch.js +15 -0
- package/dist/utils/prosprsearch.js.map +1 -1
- package/dist/utils/sdc.js +7 -0
- package/dist/utils/sdc.js.map +1 -1
- package/dist/utils/searchIndexes.d.ts +37 -0
- package/dist/utils/searchIndexes.js +37 -0
- package/dist/utils/searchIndexes.js.map +1 -1
- package/dist/utils/string.js +7 -6
- package/dist/utils/string.js.map +1 -1
- package/dist/utils/tools.d.ts +4 -0
- package/dist/utils/tools.js +4 -0
- package/dist/utils/tools.js.map +1 -1
- package/dist/utils/transferRequests.d.ts +24 -0
- package/dist/utils/transferRequests.js +24 -0
- package/dist/utils/transferRequests.js.map +1 -1
- package/dist/utils/update.js +12 -0
- package/dist/utils/update.js.map +1 -1
- package/package.json +1 -1
package/dist/lib/Cart/index.js
CHANGED
|
@@ -15,6 +15,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
15
15
|
};
|
|
16
16
|
var _a;
|
|
17
17
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
//#region IMPORTS
|
|
18
19
|
const find_1 = __importDefault(require("lodash/find"));
|
|
19
20
|
const indexOf_1 = __importDefault(require("lodash/indexOf"));
|
|
20
21
|
const isNumber_1 = __importDefault(require("lodash/isNumber"));
|
|
@@ -70,10 +71,14 @@ const TransferRequest_1 = require("../TransferRequest");
|
|
|
70
71
|
const TransferRequest_2 = require("../../Interfaces/TransferRequest");
|
|
71
72
|
const inventories_1 = require("../../utils/inventories");
|
|
72
73
|
const CartReservedQuantities_1 = __importDefault(require("../CartReservedQuantities"));
|
|
74
|
+
//#endregion
|
|
73
75
|
class Cart extends baseService_1.BaseServiceClass {
|
|
76
|
+
//#endregion
|
|
74
77
|
constructor(data, collection, user, resetErrors) {
|
|
75
78
|
super(data, collection, user);
|
|
79
|
+
//#region ATTRIBUTES
|
|
76
80
|
this._allTaxes = [];
|
|
81
|
+
//#region SETTERS
|
|
77
82
|
this.addError = (error) => {
|
|
78
83
|
this._data = Object.assign(Object.assign({}, this._data), { errors: (0, uniq_1.default)([...(!!this._data.errors && Array.isArray(this._data.errors) ? this._data.errors : []), error]) });
|
|
79
84
|
};
|
|
@@ -101,6 +106,12 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
101
106
|
}
|
|
102
107
|
return this._data;
|
|
103
108
|
};
|
|
109
|
+
/**
|
|
110
|
+
* Set cart as cancelled with external refund, and reset marketing props
|
|
111
|
+
* @param user - User that initiated the cancellation process
|
|
112
|
+
* @param associatedTransfers.all - Optionnal. Full list of TransferRequest obj associated to cart
|
|
113
|
+
* @param associatedTransfers.toCancel - Optionnal. Provided list of ITransferRequest data associated to cart that should be cancelled
|
|
114
|
+
*/
|
|
104
115
|
this.cancelCart = async (user, associatedTransfers) => {
|
|
105
116
|
let userInfo;
|
|
106
117
|
if (!!user) {
|
|
@@ -114,7 +125,9 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
114
125
|
};
|
|
115
126
|
}
|
|
116
127
|
const editedCart = Object.assign(Object.assign(Object.assign(Object.assign({ status: Cart_1.CartStatusEnum.EXT_REFUND }, (!!userInfo ? { canceled_by: userInfo } : {})), (!!this._data.check_marketing_emails ? { check_marketing_emails: false } : {})), (!!this._data.check_sms_to_send ? { check_sms_to_send: false } : {})), (!!this._data.check_retarget_marketing_emails ? { check_retarget_marketing_emails: false } : {}));
|
|
128
|
+
// Space will be set in following functions if needed
|
|
117
129
|
let space = undefined;
|
|
130
|
+
// Reset inventories for items
|
|
118
131
|
if (!!this._data.items && !!this._data.items.length) {
|
|
119
132
|
try {
|
|
120
133
|
if (!!!space)
|
|
@@ -131,6 +144,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
131
144
|
console.error(e);
|
|
132
145
|
}
|
|
133
146
|
}
|
|
147
|
+
// Cancel associated transfer requests
|
|
134
148
|
if (!!associatedTransfers && !!associatedTransfers.toCancel) {
|
|
135
149
|
try {
|
|
136
150
|
if (!!!space)
|
|
@@ -150,7 +164,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
150
164
|
}
|
|
151
165
|
}
|
|
152
166
|
try {
|
|
153
|
-
await this.save(editedCart, true);
|
|
167
|
+
await this.save(editedCart, undefined, true);
|
|
154
168
|
return true;
|
|
155
169
|
}
|
|
156
170
|
catch (error) {
|
|
@@ -158,10 +172,69 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
158
172
|
return false;
|
|
159
173
|
}
|
|
160
174
|
};
|
|
175
|
+
/**
|
|
176
|
+
* Set cart as cancelled for payment-pending carts
|
|
177
|
+
* @param user The data for the user who initiated the cancel operation
|
|
178
|
+
* @throws If cart contains any other saved payment type than PaymentTypeEnum.TOBERECEIVED
|
|
179
|
+
* @returns {Promise<ICart>}
|
|
180
|
+
*/
|
|
181
|
+
this.cancelCartWithoutPayments = async (user) => {
|
|
182
|
+
// If cart has a payment other than "to be received", throw an error
|
|
183
|
+
const cartPaidBy = this.getAllPaidBy();
|
|
184
|
+
if (cartPaidBy.some((p) => p != Cart_1.PaymentTypeEnum.TOBERECEIVED)) {
|
|
185
|
+
console.log("Can't cancel this cart if it has payments other than to be received! Should call function cancelCart instead.");
|
|
186
|
+
throw new Error('Could not cancel cart!');
|
|
187
|
+
}
|
|
188
|
+
// Generate user info based on who initiated the cancelation
|
|
189
|
+
let userInfo;
|
|
190
|
+
if (!!user) {
|
|
191
|
+
userInfo = {
|
|
192
|
+
user_name: `${user.firstname} ${user.lastname}`,
|
|
193
|
+
user_email: user.email,
|
|
194
|
+
user_id: user.id,
|
|
195
|
+
user_external_id: user.external_id,
|
|
196
|
+
date: new Date(),
|
|
197
|
+
is_active: true
|
|
198
|
+
};
|
|
199
|
+
}
|
|
200
|
+
const editedCart = Object.assign(Object.assign(Object.assign(Object.assign({ id: this._data.id, status: Cart_1.CartStatusEnum.CANCELLED }, (!!userInfo ? { canceled_by: userInfo } : {})), (!!this._data.check_marketing_emails ? { check_marketing_emails: false } : {})), (!!this._data.check_sms_to_send ? { check_sms_to_send: false } : {})), (!!this._data.check_retarget_marketing_emails ? { check_retarget_marketing_emails: false } : {}));
|
|
201
|
+
// Liberate inventories for items
|
|
202
|
+
const allItems = this._data.items;
|
|
203
|
+
if (!!allItems.length) {
|
|
204
|
+
try {
|
|
205
|
+
const space = await Space_2.default.getCurrentSpaceWithRef(this._collection.path, this._user);
|
|
206
|
+
const spaceReservedQuantitiesOnAddToCart = space.options.checkIfOptionIsSet('inventory.reserve_on_add_to_cart');
|
|
207
|
+
const someItemsWithReservedQuantities = allItems.some((i) => typeof i.qte_reserved == 'number');
|
|
208
|
+
if (!!!this._data.current_store_id &&
|
|
209
|
+
(this._data.status >= Cart_1.CartStatusEnum.CART_READY_TO_PROCESS ||
|
|
210
|
+
(spaceReservedQuantitiesOnAddToCart && someItemsWithReservedQuantities)))
|
|
211
|
+
throw new Error('No store associated to cart, cannot update inventory!');
|
|
212
|
+
await space.inventory.ajust(this._data.items, 'cancelled', this._data.cart_type, {
|
|
213
|
+
currentStoreId: this._data.current_store_id || '',
|
|
214
|
+
onlyWeb: spaceReservedQuantitiesOnAddToCart
|
|
215
|
+
? !someItemsWithReservedQuantities
|
|
216
|
+
: this._data.status < Cart_1.CartStatusEnum.CART_READY_TO_PROCESS
|
|
217
|
+
});
|
|
218
|
+
}
|
|
219
|
+
catch (e) {
|
|
220
|
+
console.error(e);
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
try {
|
|
224
|
+
await this.save(editedCart, undefined, true, true);
|
|
225
|
+
return this._data;
|
|
226
|
+
}
|
|
227
|
+
catch (error) {
|
|
228
|
+
console.log('error on saving cancelled cart', error);
|
|
229
|
+
return;
|
|
230
|
+
}
|
|
231
|
+
};
|
|
161
232
|
this.updateCartOnLoginFetch = async (customerData, space, orgID) => {
|
|
162
233
|
try {
|
|
234
|
+
// reset discount rules
|
|
163
235
|
await this.setDiscountRules();
|
|
164
236
|
let actionsDoneOnCart = [];
|
|
237
|
+
// check item prices
|
|
165
238
|
if (!!space && !!this._data.items.length) {
|
|
166
239
|
try {
|
|
167
240
|
actionsDoneOnCart = await this.verifyCartItems(space, orgID, false);
|
|
@@ -170,6 +243,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
170
243
|
console.log('error on verifyCartItems in /signin endpoint: ', e.toString());
|
|
171
244
|
}
|
|
172
245
|
}
|
|
246
|
+
// add/ajust customer info
|
|
173
247
|
let cartCustumerInfo = this.data().customer_info;
|
|
174
248
|
if (!!customerData.basic_info.customer_professionnal_info &&
|
|
175
249
|
!!customerData.basic_info.customer_professionnal_info.professionnal_title &&
|
|
@@ -182,6 +256,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
182
256
|
};
|
|
183
257
|
this._data = Object.assign(Object.assign({}, this._data), newInfo);
|
|
184
258
|
}
|
|
259
|
+
// If an old cart has promise_to_purchase info saved to database, remove it when logging in
|
|
185
260
|
if (!!this._data.promise_to_purchase) {
|
|
186
261
|
const _b = this._data, { promise_to_purchase, items } = _b, rest = __rest(_b, ["promise_to_purchase", "items"]);
|
|
187
262
|
this._data = Object.assign(Object.assign({}, rest), { promise_to_purchase: null, items: items.filter((i) => !!!(0, g2_1.isEscompteSuppItem)(i.sku)) });
|
|
@@ -201,6 +276,8 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
201
276
|
console.log('error on updating cart after fetch : ', e.toString());
|
|
202
277
|
}
|
|
203
278
|
};
|
|
279
|
+
//#endregion
|
|
280
|
+
//#region GETTERS
|
|
204
281
|
this.data = () => this._data;
|
|
205
282
|
this.save = async (partial, options, saveToDatabase, onlyPartial = false, noEvent) => {
|
|
206
283
|
var _b;
|
|
@@ -263,12 +340,17 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
263
340
|
this.checkIfAmountLeftToPayOnTotal = () => {
|
|
264
341
|
const currentPaidBy = this.data().paid_by;
|
|
265
342
|
if (!!currentPaidBy && currentPaidBy !== Cart_1.PaymentTypeEnum.MULTIPLE) {
|
|
343
|
+
// TODO - Check what we should do for carts created before POS was online, when currentPaidBy is TOBERECEIVED
|
|
266
344
|
return currentPaidBy === Cart_1.PaymentTypeEnum.TOBERECEIVED;
|
|
267
345
|
}
|
|
346
|
+
// If no payment details found, it means no payments were taken
|
|
268
347
|
const paymentDetails = this.data().payment_details;
|
|
269
348
|
if (!!!paymentDetails || !!!paymentDetails.length)
|
|
270
349
|
return false;
|
|
350
|
+
// Add all paymentDetails amounts and paymentDetails without toBeReceived amounts
|
|
351
|
+
// const paidAmount = sumBy(paymentDetails, 'amount')
|
|
271
352
|
const paidAmountWithoutToBeReceived = (0, sumBy_1.default)(paymentDetails.filter((p) => p.method !== Cart_1.PaymentTypeEnum.TOBERECEIVED), 'amount');
|
|
353
|
+
// No amount left to pay if paidAmountNoToBeReceived is equal to total cart amount or paidAmount === 0
|
|
272
354
|
return (0, round_1.default)(paidAmountWithoutToBeReceived, 2) !== (0, round_1.default)(this.data().total, 2);
|
|
273
355
|
};
|
|
274
356
|
this.getCustomerById = async () => {
|
|
@@ -324,6 +406,10 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
324
406
|
return undefined;
|
|
325
407
|
}
|
|
326
408
|
};
|
|
409
|
+
/**
|
|
410
|
+
* Get the exising or create a new reservation class object
|
|
411
|
+
* @returns The Object managing the reservation for this cart
|
|
412
|
+
*/
|
|
327
413
|
this.getReservedQuantities = async () => {
|
|
328
414
|
if (!this._data.id)
|
|
329
415
|
throw new Error(`Can't create reservation on unsaved cart`);
|
|
@@ -345,6 +431,8 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
345
431
|
path: docPath
|
|
346
432
|
}, this._user);
|
|
347
433
|
};
|
|
434
|
+
//#endregion
|
|
435
|
+
//#region BOXES + SHIPPING
|
|
348
436
|
this.canEnterPredefinedBox = (box, subtotalToRespect, weightToRespect, totalItemsToRespect, space) => {
|
|
349
437
|
if (!!subtotalToRespect) {
|
|
350
438
|
if (!!!this.data().subtotal && !!space) {
|
|
@@ -407,6 +495,10 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
407
495
|
: (0, dimensions_1.convertDimension)(item.shipping_info.width || 0, item.shipping_info.unit_measurments, unit) * item.qte).toFixed(2));
|
|
408
496
|
});
|
|
409
497
|
};
|
|
498
|
+
/**
|
|
499
|
+
* Get total cart weight by calculating each product's weigth times inventory-converted quantity
|
|
500
|
+
* @param unit The unit in which weight must be returned
|
|
501
|
+
*/
|
|
410
502
|
this.getTotalWeight = (unit = 'pounds') => {
|
|
411
503
|
return (0, sumBy_1.default)(this.data().items, (item) => {
|
|
412
504
|
if (!!item.shipping_info.is_not_shippable)
|
|
@@ -420,6 +512,8 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
420
512
|
convertedQuantities;
|
|
421
513
|
});
|
|
422
514
|
};
|
|
515
|
+
//#endregion
|
|
516
|
+
//#region ITEMS
|
|
423
517
|
this.addItemsToCart = async (items) => {
|
|
424
518
|
const itemsWithRestrictions = this.checkProductRestrictions(items);
|
|
425
519
|
this._data = Object.assign(Object.assign({}, this._data), { items: itemsWithRestrictions });
|
|
@@ -457,6 +551,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
457
551
|
console.log('proCustomerTitle: ', proCustomerTitle);
|
|
458
552
|
}
|
|
459
553
|
let customPriceList = undefined;
|
|
554
|
+
// If is GR and customer is pro customer, fetch customPriceList
|
|
460
555
|
if (!!isGR && !!!space.data().cms.hide_pro_prices && !!space.data().g2_price_fetch_active && !!proID && !!orgID) {
|
|
461
556
|
const token = (0, context_1.getSpaceToken)(space, orgID);
|
|
462
557
|
if (!!token) {
|
|
@@ -514,6 +609,8 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
514
609
|
]
|
|
515
610
|
});
|
|
516
611
|
}
|
|
612
|
+
// -------------------------------------------------------------------------------
|
|
613
|
+
// If the parent doesn't exist anymore
|
|
517
614
|
if (!!!parentProductsQuery.length) {
|
|
518
615
|
if (!!__1.isTestEnv)
|
|
519
616
|
console.log('parent prod does not exist for slug: ', cartItem.parent_slug);
|
|
@@ -528,12 +625,16 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
528
625
|
let parentProduct = parentProductsQuery[0];
|
|
529
626
|
if (!!__1.isTestEnv)
|
|
530
627
|
console.log('parentProduct: ', parentProduct.slug);
|
|
628
|
+
// -------------------------------------------------------------------------------
|
|
629
|
+
// If customer is pro, check to update product declinations with price_list
|
|
531
630
|
if (!!proID && !!proCustomerTitle) {
|
|
532
631
|
parentProduct = await (0, products_1.updateProductWithInfo)(parentProduct, '', space, space.data().id, proCustomerTitle);
|
|
533
632
|
}
|
|
534
633
|
if (cartItem.parent_slug === 'installation-gazon') {
|
|
535
634
|
installationParentProduct = parentProduct;
|
|
536
635
|
}
|
|
636
|
+
// -------------------------------------------------------------------------------
|
|
637
|
+
// If the declination doesn't exist anymore
|
|
537
638
|
let queryDeclination = parentProduct.declinations.find((decli) => decli.sku === cartItem.sku);
|
|
538
639
|
if (!!!queryDeclination) {
|
|
539
640
|
if (!!__1.isTestEnv)
|
|
@@ -546,11 +647,15 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
546
647
|
verifiedItems.push(Object.assign(Object.assign({}, cartItem), { state_after_verification: 'out_of_stock' }));
|
|
547
648
|
continue;
|
|
548
649
|
}
|
|
650
|
+
// -------------------------------------------------------------------------------
|
|
651
|
+
// If tier-pricing has changed
|
|
549
652
|
const queryDecliTierPricing = !!queryDeclination.tier_pricing && !!queryDeclination.tier_pricing.length
|
|
550
653
|
? queryDeclination.tier_pricing
|
|
551
654
|
: undefined;
|
|
552
655
|
const itemTierPricing = !!cartItem.tier_pricing && !!cartItem.tier_pricing.length ? cartItem.tier_pricing : undefined;
|
|
553
656
|
let didApplyTier = false;
|
|
657
|
+
// Check if tier-pricing does not exist on queryDeclination and exists in cartItem, remove from cartItem
|
|
658
|
+
// Also remove discount_price if tier_pricing applied
|
|
554
659
|
if (!!itemTierPricing && !!!queryDecliTierPricing) {
|
|
555
660
|
if (!!__1.isTestEnv)
|
|
556
661
|
console.log('tier_pricing should not be in product. Removing from cartItem');
|
|
@@ -558,6 +663,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
558
663
|
? { discount_price: null }
|
|
559
664
|
: {})), { tier_pricing: [] });
|
|
560
665
|
}
|
|
666
|
+
// Check to add tier-pricing to cartItem if necessary
|
|
561
667
|
if (!!!isGR || !!!proID) {
|
|
562
668
|
if (!!queryDecliTierPricing) {
|
|
563
669
|
const tierPricingToApply = (0, discount_1.getTierPricingToApply)(queryDecliTierPricing, cartItem.qte);
|
|
@@ -579,6 +685,8 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
579
685
|
if (!!__1.isTestEnv) {
|
|
580
686
|
console.log('appliedTier: ', !!didApplyTier);
|
|
581
687
|
}
|
|
688
|
+
// -------------------------------------------------------------------------------
|
|
689
|
+
// If is GR and customer is pro customer, check customPriceList to compare prices
|
|
582
690
|
if (!!customPriceList && !!customPriceList.length) {
|
|
583
691
|
if (!!__1.isTestEnv) {
|
|
584
692
|
console.log('is pro customer, checking with G2 prices then leaving');
|
|
@@ -590,12 +698,15 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
590
698
|
}
|
|
591
699
|
}
|
|
592
700
|
else {
|
|
701
|
+
// -------------------------------------------------------------------------------
|
|
702
|
+
// Check regular price
|
|
593
703
|
if (cartItem.regular_price.amount !== queryDeclination.regular_price.amount &&
|
|
594
704
|
!!!cartItem.regular_price.price_type) {
|
|
595
705
|
if (!!__1.isTestEnv) {
|
|
596
706
|
console.log('regPrice is different');
|
|
597
707
|
console.log('queryItem regPrice: ', queryDeclination.regular_price.amount, ' vs cartItem regPrice : ', cartItem.regular_price.amount);
|
|
598
708
|
}
|
|
709
|
+
// If the regular price changed
|
|
599
710
|
actionsDone.push({
|
|
600
711
|
sku: cartItem.sku,
|
|
601
712
|
itemName: cartItem.name,
|
|
@@ -605,11 +716,14 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
605
716
|
if (!!__1.isTestEnv)
|
|
606
717
|
console.log('new regPrice: ', cartItem.regular_price.amount);
|
|
607
718
|
}
|
|
719
|
+
// -------------------------------------------------------------------------------
|
|
720
|
+
// Check discount prices
|
|
608
721
|
if (!didApplyTier) {
|
|
609
722
|
if ((!!cartItem.discount_price && !!!cartItem.discount_price.price_type) ||
|
|
610
723
|
!!queryDeclination.discount_price) {
|
|
611
724
|
if (!!__1.isTestEnv)
|
|
612
725
|
console.log('checking discountPrice');
|
|
726
|
+
// If a discount price have been added
|
|
613
727
|
if (!!!cartItem.discount_price && !!queryDeclination.discount_price) {
|
|
614
728
|
if (!!__1.isTestEnv)
|
|
615
729
|
console.log('discountPrice was added');
|
|
@@ -622,6 +736,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
622
736
|
if (!!__1.isTestEnv)
|
|
623
737
|
console.log('new discountPrice: ', !!cartItem.discount_price ? cartItem.discount_price.amount : 'undefined');
|
|
624
738
|
}
|
|
739
|
+
// If a discount price have been removed
|
|
625
740
|
if (!!cartItem.discount_price && !!!queryDeclination.discount_price) {
|
|
626
741
|
if (!!__1.isTestEnv)
|
|
627
742
|
console.log('discountPrice was removed');
|
|
@@ -634,6 +749,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
634
749
|
if (!!__1.isTestEnv)
|
|
635
750
|
console.log('new discountPrice: ', !!cartItem.discount_price ? cartItem.discount_price.amount : 'undefined');
|
|
636
751
|
}
|
|
752
|
+
// If the cart item's discount price has been updated
|
|
637
753
|
if (!!cartItem.discount_price &&
|
|
638
754
|
!!queryDeclination.discount_price &&
|
|
639
755
|
cartItem.discount_price.amount !== queryDeclination.discount_price.amount &&
|
|
@@ -654,6 +770,8 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
654
770
|
}
|
|
655
771
|
}
|
|
656
772
|
}
|
|
773
|
+
// -------------------------------------------------------------------------------
|
|
774
|
+
// Check promo prices
|
|
657
775
|
if (!!__1.isTestEnv)
|
|
658
776
|
console.log('cartItem.promo_price: ', !!cartItem.promo_price);
|
|
659
777
|
if (!!__1.isTestEnv)
|
|
@@ -661,6 +779,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
661
779
|
if (!!cartItem.promo_price || !!queryDeclination.promo_price) {
|
|
662
780
|
if (!!__1.isTestEnv)
|
|
663
781
|
console.log('checking promoPrice');
|
|
782
|
+
// If a promo price has been added
|
|
664
783
|
if (!!!cartItem.promo_price && !!queryDeclination.promo_price) {
|
|
665
784
|
if (!!__1.isTestEnv)
|
|
666
785
|
console.log('promoPrice was added');
|
|
@@ -673,6 +792,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
673
792
|
if (!!__1.isTestEnv)
|
|
674
793
|
console.log('new promoPrice: ', !!cartItem.promo_price ? cartItem.promo_price.amount : 'undefined');
|
|
675
794
|
}
|
|
795
|
+
// If a promo price has been removed
|
|
676
796
|
if (!!cartItem.promo_price && !!!queryDeclination.promo_price) {
|
|
677
797
|
if (!!__1.isTestEnv)
|
|
678
798
|
console.log('promoPrice was removed');
|
|
@@ -685,6 +805,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
685
805
|
if (!!__1.isTestEnv)
|
|
686
806
|
console.log('new promoPrice: ', !!cartItem.promo_price ? cartItem.promo_price.amount : 'undefined');
|
|
687
807
|
}
|
|
808
|
+
// If the cart item's discount price has been updated
|
|
688
809
|
if (!!cartItem.promo_price &&
|
|
689
810
|
!!queryDeclination.promo_price &&
|
|
690
811
|
!!!Number.isNaN((0, toNumber_1.default)(queryDeclination.promo_price.amount)) &&
|
|
@@ -705,6 +826,8 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
705
826
|
}
|
|
706
827
|
}
|
|
707
828
|
}
|
|
829
|
+
// -------------------------------------------------------------------------------
|
|
830
|
+
// Check inventory
|
|
708
831
|
if (!!!isGR && !!!cartItem.is_service) {
|
|
709
832
|
if (!!__1.isTestEnv)
|
|
710
833
|
console.log('checking inventory');
|
|
@@ -741,9 +864,11 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
741
864
|
}
|
|
742
865
|
verifiedItems.push(cartItem);
|
|
743
866
|
}
|
|
867
|
+
// Apply installation tout inclus when pro has it but cart has ventilated installation (for web)
|
|
744
868
|
if (!!proID && !!proCustomerTitle && !!customPriceList && !!customPriceList.length) {
|
|
745
869
|
let installationParent = installationParentProduct;
|
|
746
870
|
if (!!!installationParent && verifiedItems.some((i) => i.parent_slug === 'installation-gazon')) {
|
|
871
|
+
// Fallback: fetch from indexed products when cartItem query failed in the main loop
|
|
747
872
|
const indexed = await space.indexedProducts.get({
|
|
748
873
|
query: [{ field: 'slug', operator: '==', value: 'installation-gazon' }]
|
|
749
874
|
});
|
|
@@ -775,6 +900,8 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
775
900
|
!!!item.restrict_shipping.restrict_values.length)) {
|
|
776
901
|
return item;
|
|
777
902
|
}
|
|
903
|
+
// GESTION DES RESTRICTIONS SELON TYPE D'UTILISATEUR
|
|
904
|
+
// --------------------------------------------------------------------------------------------------
|
|
778
905
|
if (!!item.restrict_sale &&
|
|
779
906
|
!!item.restrict_sale.restrict_values &&
|
|
780
907
|
!!item.restrict_sale.restrict_values.length &&
|
|
@@ -791,6 +918,8 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
791
918
|
item = Object.assign(Object.assign({}, item), { restrict_sale: Object.assign(Object.assign({}, item.restrict_sale), { restrict_message: '' }) });
|
|
792
919
|
}
|
|
793
920
|
}
|
|
921
|
+
// GESTION DES RESTRICTIONS SELON LA LIVRAISON
|
|
922
|
+
// --------------------------------------------------------------------------------------------------
|
|
794
923
|
if (!!item.restrict_shipping &&
|
|
795
924
|
!!item.restrict_shipping.restrict_values &&
|
|
796
925
|
!!item.restrict_shipping.restrict_values.length) {
|
|
@@ -848,6 +977,8 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
848
977
|
}
|
|
849
978
|
return baseMsg;
|
|
850
979
|
};
|
|
980
|
+
//#endregion
|
|
981
|
+
//#region TAXES
|
|
851
982
|
this.setAllTaxes = async () => {
|
|
852
983
|
this._allTaxes = await Tax_1.default.getAllTaxesGeneral();
|
|
853
984
|
return this._allTaxes;
|
|
@@ -855,8 +986,15 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
855
986
|
this.setCartTaxes = (defaultTax) => {
|
|
856
987
|
this._data = Object.assign(Object.assign({}, this._data), { taxes: [...this._data.taxes, defaultTax] });
|
|
857
988
|
};
|
|
989
|
+
/**
|
|
990
|
+
* Calcule la "sous taxe" (ex: TPS, TVQ) d'une "tax family" (ex: QC),
|
|
991
|
+
* en vérifiant si des produits ont une famille de taxe à eux, et en enlevant le montant le cas échéant.
|
|
992
|
+
* @param taxNameFr
|
|
993
|
+
* @param taxValue
|
|
994
|
+
*/
|
|
858
995
|
this.getATax = (taxNameFr, taxValue, _currency = 'CAD') => {
|
|
859
996
|
let taxAmount = 0;
|
|
997
|
+
// 0. On vérifie que l'adresse de livraison est bien au Canada (si au US, pas de taxes à charger)
|
|
860
998
|
if ((!!this._data.shipping_address &&
|
|
861
999
|
!!this._data.shipping_address.address &&
|
|
862
1000
|
['ca', 'canada'].includes(this._data.shipping_address.address.country.toLowerCase())) ||
|
|
@@ -866,23 +1004,33 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
866
1004
|
: this.data().subtotal;
|
|
867
1005
|
const subtotal = this.data().subtotal;
|
|
868
1006
|
const subtotalWithShipping = (0, round_1.default)(this.data().subtotal + this._checkShippingAmount(), 2);
|
|
869
|
-
|
|
1007
|
+
// 1. On vérifie le nombre d'items au panier qui redéfinissent le tax_family_id
|
|
1008
|
+
let customTaxableItems = this.data().items.filter((item) => !!item.tax_family_id && !item.tax_exemption // ne pas inclure si l'item est sans taxe
|
|
1009
|
+
);
|
|
870
1010
|
let notTaxableItems = this.data().items.filter((item) => !!item.tax_exemption);
|
|
871
1011
|
let correspondingSubTax = undefined;
|
|
872
1012
|
let amountToApplyTaxTo = 0;
|
|
1013
|
+
// 2. Si le nb d'items avec tax_family_id === 0, on retourne simplement le calcul de la sous-taxe
|
|
873
1014
|
if (!!!customTaxableItems.length) {
|
|
874
1015
|
amountToApplyTaxTo = subtotalWithShipping;
|
|
875
1016
|
}
|
|
876
1017
|
else {
|
|
1018
|
+
// 3. Sinon...
|
|
877
1019
|
let totalPriceAmountCustomTaxable = 0;
|
|
1020
|
+
// 3a. On parcourt tous les items avec tax_family_id, pour sortir la tax family associée
|
|
878
1021
|
customTaxableItems.map((item) => {
|
|
879
1022
|
let priceToTakeOut = (0, cart_2.getLowestAppliedPrice)(item).amount;
|
|
1023
|
+
// Si on trouve la sous taxe dans les taxes de l'item, on l'enregistre dans correspondingSubTax (pour avoir le taux associé)
|
|
880
1024
|
const correspondingTaxes = this._allTaxes.filter((tax) => tax.id === item.tax_family_id)[0].taxes;
|
|
881
1025
|
correspondingSubTax = correspondingTaxes.find((tax) => tax.label_fr === taxNameFr);
|
|
1026
|
+
// 3b. Si, parmi les sous-taxes (taxes) de la famille, on trouve le même sous-taxe label_fr que celle vérifiée présentement,
|
|
1027
|
+
// on pousse 0, pour que le montant de l'article ne soit pas considéré dans le calcul de la sous-taxe,
|
|
882
1028
|
if (!!correspondingSubTax) {
|
|
883
1029
|
totalPriceAmountCustomTaxable += 0;
|
|
884
1030
|
}
|
|
885
1031
|
else {
|
|
1032
|
+
// 3c. Si non, on pousse le montant calculé du produit pour qu'il soit déduit du calcul de la sous-taxe
|
|
1033
|
+
// + si on trouve la sous taxe dans les taxes du cart, on l'enregistre dans correspondingSubTax (pour avoir le taux associé)
|
|
886
1034
|
const sameTaxInCart = this.data().taxes.find((tax) => tax.taxes.find((t) => taxNameFr === t.label_fr));
|
|
887
1035
|
if (!!sameTaxInCart) {
|
|
888
1036
|
correspondingSubTax = sameTaxInCart.taxes.find((tax) => tax.label_fr === taxNameFr);
|
|
@@ -890,9 +1038,13 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
890
1038
|
totalPriceAmountCustomTaxable += priceToTakeOut * item.qte;
|
|
891
1039
|
}
|
|
892
1040
|
});
|
|
1041
|
+
// 3d. On calcule le ratio correspondant au montant des articles avec taxe "custom" par rapport le sous-total AVEC promotion
|
|
893
1042
|
const ratioOfCustomTaxToSubtotal = (totalPriceAmountCustomTaxable * subtotal) / subtotalWithoutPromotions;
|
|
1043
|
+
// 3e. On calcule le montant de taxes par défault, en déduisant le prix "custom" du prix par défault
|
|
1044
|
+
// + on arrondit avant de retourner
|
|
894
1045
|
amountToApplyTaxTo = (0, round_1.default)(subtotalWithShipping - ratioOfCustomTaxToSubtotal, 2);
|
|
895
1046
|
}
|
|
1047
|
+
// 4. Si certains items de la commande sont non-taxable, les exclure du sous-total sur lequel le montant de la taxe est calculé
|
|
896
1048
|
if (!!notTaxableItems.length) {
|
|
897
1049
|
let totalNotTaxableItems = 0;
|
|
898
1050
|
notTaxableItems.forEach((item) => {
|
|
@@ -902,6 +1054,9 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
902
1054
|
amountToApplyTaxTo -= totalNotTaxableItems;
|
|
903
1055
|
}
|
|
904
1056
|
taxAmount = (0, round_1.default)(amountToApplyTaxTo * taxValue, 2);
|
|
1057
|
+
// 4. Pour enregister le montant total de cette sous-taxe dans le Cart, il faut savoir :
|
|
1058
|
+
// - à quelle famille de taxes dans le array taxes du Cart elle appartient (position 0 du array sameTaxInDefaultCart)
|
|
1059
|
+
// - à quelle sous-taxe de cette famille elle appartient (position 1 du array sameTaxInDefaultCart)
|
|
905
1060
|
let sameTaxInDefaultCart = [];
|
|
906
1061
|
if (!!this.data().taxes) {
|
|
907
1062
|
sameTaxInDefaultCart = this.data().taxes.map((tax, key) => {
|
|
@@ -909,6 +1064,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
909
1064
|
return [key, tax.taxes.indexOf(taxToCheck)];
|
|
910
1065
|
})[0];
|
|
911
1066
|
}
|
|
1067
|
+
// 5. On reconstruit le array de taxes du Cart avec la nouvelle valeur du "amount" au bon endroit
|
|
912
1068
|
if (sameTaxInDefaultCart.indexOf(-1) === -1) {
|
|
913
1069
|
this._data = Object.assign(Object.assign({}, this._data), { taxes: [
|
|
914
1070
|
...this._data.taxes.slice(0, sameTaxInDefaultCart[0]),
|
|
@@ -921,8 +1077,11 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
921
1077
|
] });
|
|
922
1078
|
}
|
|
923
1079
|
}
|
|
1080
|
+
// 6. On retourne le résultat de l'affichage
|
|
924
1081
|
return (0, round_1.default)(taxAmount, 2);
|
|
925
1082
|
};
|
|
1083
|
+
//#endregion
|
|
1084
|
+
//#region CUSTOMERS
|
|
926
1085
|
this.setProCustomerInfo = async (customer) => {
|
|
927
1086
|
var _b, _c, _d, _e, _f, _g, _h, _j;
|
|
928
1087
|
const proInfo = (0, data_1.getProCustomerInfo)(customer.basic_info, customer.company_info);
|
|
@@ -955,11 +1114,14 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
955
1114
|
}
|
|
956
1115
|
return this._data;
|
|
957
1116
|
};
|
|
1117
|
+
//#endregion
|
|
1118
|
+
//#region PAYMENT
|
|
958
1119
|
this.createPaymentIntent = async () => {
|
|
959
1120
|
const space = await Space_2.default.getCurrentSpaceWithRef(this._collection.path, this._user);
|
|
960
1121
|
const shippingServiceCredz = space.data().external_services.find((es) => !!es.is_active && es.type === 'payment');
|
|
961
1122
|
if (!!!shippingServiceCredz)
|
|
962
1123
|
throw new Error(`Must have a payment service to use this`);
|
|
1124
|
+
// this.save({ status: CartStatusEnum.CHECKOUT_PROCESSING_PAYMENT } as Partial<ICart>)
|
|
963
1125
|
switch (shippingServiceCredz.external_service_name) {
|
|
964
1126
|
case 'stripe':
|
|
965
1127
|
if (!!!shippingServiceCredz.external_service_infos.secret) {
|
|
@@ -998,6 +1160,8 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
998
1160
|
throw new Error(`This payment service is not handled yet`);
|
|
999
1161
|
}
|
|
1000
1162
|
};
|
|
1163
|
+
//#endregion
|
|
1164
|
+
//#region ORDER
|
|
1001
1165
|
this.paymentDetails = async (payment_details) => {
|
|
1002
1166
|
return await this.save({ payment_details }, undefined, true);
|
|
1003
1167
|
};
|
|
@@ -1008,6 +1172,34 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1008
1172
|
let paysafe_payload = undefined;
|
|
1009
1173
|
console.log('====================');
|
|
1010
1174
|
console.log('in processPOSPayment');
|
|
1175
|
+
// TODO - Uncomment when ready to use store credits!
|
|
1176
|
+
// // Valider les store credits si utilisés comme mode de paiement
|
|
1177
|
+
// let usedCredit = 0
|
|
1178
|
+
// type IPaymentWithRef = IPayment & { ref: string }
|
|
1179
|
+
// const foundStoreCreditPayment = !!payment_request_payload.multi_payment_methods
|
|
1180
|
+
// ? (payment_request_payload.multi_payment_methods.find(
|
|
1181
|
+
// (p) => p.method == PaymentTypeEnum.STORE_CREDITS && !!p.ref
|
|
1182
|
+
// ) as IPaymentWithRef | undefined)
|
|
1183
|
+
// : undefined
|
|
1184
|
+
// if (foundStoreCreditPayment) {
|
|
1185
|
+
// const creditCheck = await validateStoreCreditUsage(
|
|
1186
|
+
// foundStoreCreditPayment.amount,
|
|
1187
|
+
// cart.data().customer_id,
|
|
1188
|
+
// space,
|
|
1189
|
+
// foundStoreCreditPayment.ref!
|
|
1190
|
+
// )
|
|
1191
|
+
// if (!creditCheck.valid)
|
|
1192
|
+
// return {
|
|
1193
|
+
// error: creditCheck.error || {
|
|
1194
|
+
// fr: 'Impossible de vérifier le crédit magasin pour la commande',
|
|
1195
|
+
// en: 'Could not check store credit for order'
|
|
1196
|
+
// }
|
|
1197
|
+
// }
|
|
1198
|
+
// usedCredit = foundStoreCreditPayment.amount
|
|
1199
|
+
// }
|
|
1200
|
+
// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
1201
|
+
// Apply payments to cart and create ref
|
|
1202
|
+
// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
1011
1203
|
try {
|
|
1012
1204
|
console.log('---------------');
|
|
1013
1205
|
let delay1 = (0, moment_1.default)();
|
|
@@ -1033,6 +1225,33 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1033
1225
|
};
|
|
1034
1226
|
}
|
|
1035
1227
|
console.log('createOrderWithSuccessfulPaymentPayload delay: ', (0, moment_1.default)().diff(delay1, 'seconds'));
|
|
1228
|
+
// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
1229
|
+
// Check for store credits to update in customer data
|
|
1230
|
+
// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
1231
|
+
// TODO - Uncomment when ready to use store credits!
|
|
1232
|
+
// const cartData = cart.data()
|
|
1233
|
+
// if (usedCredit > 0 && !!cartData.customer_id && foundStoreCreditPayment) {
|
|
1234
|
+
// try {
|
|
1235
|
+
// const lastUserToTakePayment = getLastUserWhoTookPayment(cartData)
|
|
1236
|
+
// await space.customers.credits.modify(
|
|
1237
|
+
// cartData.customer_id,
|
|
1238
|
+
// foundStoreCreditPayment.ref,
|
|
1239
|
+
// -usedCredit,
|
|
1240
|
+
// `Commande #${cart.getCartRef(space).order}`,
|
|
1241
|
+
// `POS ${lastUserToTakePayment ? lastUserToTakePayment.user_id || lastUserToTakePayment.user_name : 'Unknown'}`
|
|
1242
|
+
// )
|
|
1243
|
+
// } catch (err) {
|
|
1244
|
+
// return {
|
|
1245
|
+
// error: {
|
|
1246
|
+
// fr: "Impossible d'ajuster les crédits magasin.",
|
|
1247
|
+
// en: 'Could not store credits.'
|
|
1248
|
+
// }
|
|
1249
|
+
// }
|
|
1250
|
+
// }
|
|
1251
|
+
// }
|
|
1252
|
+
// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
1253
|
+
// Check if Algolia is on -- save cart in algo
|
|
1254
|
+
// ------------------------------------------------------------------------------------------------------------------------------------------------------------------------
|
|
1036
1255
|
if (!!indexCart) {
|
|
1037
1256
|
console.log('---------------');
|
|
1038
1257
|
let delay2 = (0, moment_1.default)();
|
|
@@ -1074,6 +1293,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1074
1293
|
console.log('error while fetching customer: ', e.toString());
|
|
1075
1294
|
}
|
|
1076
1295
|
}
|
|
1296
|
+
// NEW FUNCTION - returns indexedCartData
|
|
1077
1297
|
const indexedCartData = (0, cart_1.getIndexedCartData)(cart.data(), space, {
|
|
1078
1298
|
setPaidAtIfUndefined: true,
|
|
1079
1299
|
customer: !!customer ? customer.data() : undefined,
|
|
@@ -1161,11 +1381,19 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1161
1381
|
? this.data().payment_reference
|
|
1162
1382
|
: '';
|
|
1163
1383
|
const multiPaymentMethods = !!multi_payment_methods
|
|
1164
|
-
? multi_payment_methods.map((p) => (Object.assign(Object.assign({}, p), { ref: p.ref || getPaymentRef()
|
|
1384
|
+
? multi_payment_methods.map((p) => (Object.assign(Object.assign({}, p), { ref: p.ref || getPaymentRef() // keep current payment ref if set for payment method, else fetch generic ref from "base" payment type
|
|
1385
|
+
})))
|
|
1165
1386
|
: undefined;
|
|
1387
|
+
// Fetch space invoice next ref
|
|
1166
1388
|
let newRef = !!isDev ? 123456789 : undefined;
|
|
1389
|
+
// -----------------------------------------------------------------------------------------
|
|
1390
|
+
// We will fetch the next avaible ref number from the api
|
|
1391
|
+
// in case of issue up to 3 attemps will be done
|
|
1392
|
+
// if none of these worked we raise an exception
|
|
1393
|
+
// -----------------------------------------------------------------------------------------
|
|
1167
1394
|
if (!!this._data.ref) {
|
|
1168
1395
|
console.log('Cart already has ref #', this._data.ref, ', skipping ref increment');
|
|
1396
|
+
// if ref already in cart, set newRef with ref value so empty string is not saved in cart afterwards
|
|
1169
1397
|
newRef = (0, toNumber_1.default)(this._data.ref);
|
|
1170
1398
|
await (0, logs_1.SystemLog)({
|
|
1171
1399
|
clientName: `sdk-admin | Cart | ...SuccPayPayload, space: ${(0, services_1.getSpaceInitialsByID)(space.data().id)}`,
|
|
@@ -1201,7 +1429,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1201
1429
|
catch (e) {
|
|
1202
1430
|
console.log('Error fetching invoice number', e);
|
|
1203
1431
|
}
|
|
1204
|
-
await (0, tools_1.waitFor)(1000);
|
|
1432
|
+
await (0, tools_1.waitFor)(1000); // whait a second before trying again, server need to recover
|
|
1205
1433
|
triesLeft--;
|
|
1206
1434
|
}
|
|
1207
1435
|
if (triesLeft == 0)
|
|
@@ -1209,6 +1437,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1209
1437
|
}
|
|
1210
1438
|
console.log('increment space ref delay: ', (0, moment_1.default)().diff(delay1, 'seconds'));
|
|
1211
1439
|
}
|
|
1440
|
+
// Update customer last_activity prop.
|
|
1212
1441
|
const customerId = this.data().customer_id;
|
|
1213
1442
|
if (!!customerId) {
|
|
1214
1443
|
try {
|
|
@@ -1218,6 +1447,9 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1218
1447
|
console.log(`Could not update last_activity prop for customer: ${customerId}, ${e}`);
|
|
1219
1448
|
}
|
|
1220
1449
|
}
|
|
1450
|
+
// -----------------------------------------------------------------------------------------
|
|
1451
|
+
// Create new partial cart data with info
|
|
1452
|
+
// -----------------------------------------------------------------------------------------
|
|
1221
1453
|
const isPOSTransactionnal = this.data().cart_type === Cart_1.CartTypeEnum.POS_TRANSACTIONNAL;
|
|
1222
1454
|
const partialCartPaidData = Object.assign(Object.assign(Object.assign(Object.assign({ paid_by: this.getPaymentMethod({
|
|
1223
1455
|
paypal_payload,
|
|
@@ -1243,15 +1475,22 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1243
1475
|
}, logs_1.LogType.WARNING, `Cart already has ref #${this._data.ref}, but doesn't have an id??, ${this._data.id}`);
|
|
1244
1476
|
}
|
|
1245
1477
|
let delay2 = (0, moment_1.default)();
|
|
1478
|
+
// -----------------------------------
|
|
1479
|
+
// Save the cart and set it as "PAID"
|
|
1246
1480
|
const newCartId = await this.save(partialCartPaidData, undefined, saveToDatabase);
|
|
1247
1481
|
console.log('saving to DB delay: ', (0, moment_1.default)().diff(delay2, 'seconds'));
|
|
1482
|
+
// -----------------------------------------------------------------------------------------
|
|
1483
|
+
// If cart is of type POS_TRANSACTIONNAL, check if should create invoice_ref & add order to G2
|
|
1484
|
+
// If so, save partial data to cart
|
|
1248
1485
|
if (!!isPOSTransactionnal) {
|
|
1249
1486
|
console.log('---------------');
|
|
1250
1487
|
let delay3 = (0, moment_1.default)();
|
|
1488
|
+
// a. Create invoice_ref
|
|
1251
1489
|
const invoiceRef = await this.setCartWithInvoiceRef(space, false, partialCartPaidData.ref);
|
|
1252
1490
|
console.log('setting invoice ref delay: ', (0, moment_1.default)().diff(delay3, 'seconds'));
|
|
1253
1491
|
console.log('---------------');
|
|
1254
1492
|
let delay4 = (0, moment_1.default)();
|
|
1493
|
+
// b. Add order to G2
|
|
1255
1494
|
const skipRef = !!this.data().is_booking || !!this.data().is_booking_beton;
|
|
1256
1495
|
let g2OrderRef;
|
|
1257
1496
|
if (!skipRef && !(0, cart_2.checkIfCartContainsType)(cart_3.CartGeneralTypeEnum.SAMPLE, this.data())) {
|
|
@@ -1262,11 +1501,15 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1262
1501
|
}
|
|
1263
1502
|
console.log('saving g2 order & setting external_value delay: ', (0, moment_1.default)().diff(delay4, 'seconds'));
|
|
1264
1503
|
console.log(`saving POS transactionnal cart to database: ${!!saveToDatabase}, with ref: ${partialCartPaidData.ref}, status: ${partialCartPaidData.status} and invoice ref: ${invoiceRef}${!!g2OrderRef ? ' and external_value.noCommande: ' + g2OrderRef : ''}`);
|
|
1504
|
+
// c. save to database
|
|
1265
1505
|
await this.save(Object.assign({ id: this.data().id || newCartId, invoice_ref: invoiceRef }, (!!g2OrderRef ? { external_values: { noCommande: g2OrderRef } } : {})), undefined, saveToDatabase, true);
|
|
1266
1506
|
}
|
|
1507
|
+
// -----------------------------------
|
|
1508
|
+
// Save inventory for cart items
|
|
1267
1509
|
console.log('---------------');
|
|
1268
1510
|
let delay5 = (0, moment_1.default)();
|
|
1269
1511
|
try {
|
|
1512
|
+
// Adjust cart items inventory
|
|
1270
1513
|
await space.inventory.ajust(this.data().items, 'paid', this.data().cart_type, {
|
|
1271
1514
|
currentStoreId: this.data().current_store_id || ''
|
|
1272
1515
|
});
|
|
@@ -1276,6 +1519,8 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1276
1519
|
await (0, console_1.alertAdminV2)(`Error while updating inventory`, `We are here: /src/lib/Cart/index.ts#1574. We are in space ${space.data().id}. JSON error: ${JSON.stringify(error)}`, error.toString(), space.getRef());
|
|
1277
1520
|
}
|
|
1278
1521
|
console.log('adjusting inventory delay: ', (0, moment_1.default)().diff(delay5, 'seconds'));
|
|
1522
|
+
// -----------------------------------
|
|
1523
|
+
// If cart has promises to purchase, check if banks used are now empty
|
|
1279
1524
|
if (!!this._data.promise_to_purchase) {
|
|
1280
1525
|
console.log('---------------');
|
|
1281
1526
|
let delay6 = (0, moment_1.default)();
|
|
@@ -1295,30 +1540,51 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1295
1540
|
console.log('====================');
|
|
1296
1541
|
return this;
|
|
1297
1542
|
};
|
|
1543
|
+
/**
|
|
1544
|
+
* Sets a cart to status completed, and generates invoice_ref if necessary.
|
|
1545
|
+
* @param saveToDatabase - Optional, defaults to true.
|
|
1546
|
+
* @returns
|
|
1547
|
+
*/
|
|
1298
1548
|
this.setCartAsCompleted = async (saveToDatabase = true, user, store) => {
|
|
1299
1549
|
console.log('====================');
|
|
1300
1550
|
console.log('in setCartAsCompleted');
|
|
1301
1551
|
try {
|
|
1552
|
+
// ---------------------------------------------------------
|
|
1553
|
+
// 1. Fetch space
|
|
1302
1554
|
const space = await Space_2.default.getCurrentSpaceWithRef(this._collection.path, this._user);
|
|
1303
1555
|
if (!!!space)
|
|
1304
1556
|
throw new Error('could not init space obj');
|
|
1305
1557
|
console.log('---------------');
|
|
1306
1558
|
let delay1 = (0, moment_1.default)();
|
|
1559
|
+
// ---------------------------------------------------------
|
|
1560
|
+
// 2. Check if cart should not have invoice_ref generated
|
|
1307
1561
|
let skipRef = false;
|
|
1562
|
+
// a. If booking, skip invoice_ref
|
|
1308
1563
|
if (!!this.data().is_booking || !!this.data().is_booking_beton)
|
|
1309
1564
|
skipRef = true;
|
|
1565
|
+
// b. If order was generated 6 months ago or earlier, skip invoice_ref
|
|
1566
|
+
// let orderPaidAtDate = !!this.data().paid_at ? formatDate(this.data().paid_at) : undefined
|
|
1567
|
+
// if (!!!orderPaidAtDate || !moment().subtract(6, 'month').isBefore(moment(orderPaidAtDate))) skipRef = true
|
|
1568
|
+
// ---------------------------------------------------------
|
|
1569
|
+
// 3. Generate invoice ref and save to cart locally (if set, saved to database with status change)
|
|
1570
|
+
// (only if no invoice_ref in cart and should not skip ref)
|
|
1310
1571
|
if (!!!this.data().invoice_ref && !!!skipRef) {
|
|
1311
1572
|
await this.setCartWithInvoiceRef(space, false);
|
|
1312
1573
|
}
|
|
1313
1574
|
console.log('setting invoice ref delay: ', (0, moment_1.default)().diff(delay1, 'seconds'));
|
|
1314
1575
|
console.log('---------------');
|
|
1315
1576
|
let delay2 = (0, moment_1.default)();
|
|
1577
|
+
// ---------------------------------------------------------
|
|
1578
|
+
// 4. Check to save cart to G2 if cart isn't a booking or sample cart
|
|
1579
|
+
// Checks if G2 is set as external service in function transformAddioCartToG2Order
|
|
1316
1580
|
if (!skipRef && !(0, cart_2.checkIfCartContainsType)(cart_3.CartGeneralTypeEnum.SAMPLE, this.data())) {
|
|
1317
1581
|
await this.setG2ExternalOrderRef(space, false);
|
|
1318
1582
|
}
|
|
1319
1583
|
console.log('setting g2 ref delay: ', (0, moment_1.default)().diff(delay2, 'seconds'));
|
|
1320
1584
|
console.log('---------------');
|
|
1321
1585
|
let delay3 = (0, moment_1.default)();
|
|
1586
|
+
// ---------------------------------------------------------
|
|
1587
|
+
// 4. Save cart to DB with new status
|
|
1322
1588
|
await this.save(Object.assign({ status: Cart_1.CartStatusEnum.COMPLETED }, (!!user
|
|
1323
1589
|
? {
|
|
1324
1590
|
completed_by: this.getCartAssignedUserData(user, store)
|
|
@@ -1333,21 +1599,25 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1333
1599
|
}
|
|
1334
1600
|
};
|
|
1335
1601
|
this.saveCartModification = async (partial, oldItems, newItems, currentUser, options = {}) => {
|
|
1602
|
+
// default saveToDatabase to true
|
|
1336
1603
|
const shouldSaveToDB = typeof options.saveToDatabase == 'boolean' ? options.saveToDatabase : true;
|
|
1337
1604
|
try {
|
|
1338
1605
|
const itemsForInventory = (0, cart_1.getModifiedItems)(newItems, oldItems);
|
|
1339
1606
|
const space = await Space_2.default.getCurrentSpaceWithRef(this._collection.path, this._user);
|
|
1340
1607
|
if (!!!space)
|
|
1341
1608
|
throw new Error('could not init space obj');
|
|
1609
|
+
// If the cart is associated to a promise
|
|
1342
1610
|
if (!!options.usedPromise) {
|
|
1343
1611
|
for (const bank of options.usedPromise.banks_used) {
|
|
1344
1612
|
const promiseQuery = await space.promisesToPurchase.get({
|
|
1345
1613
|
query: [{ field: 'id', operator: '==', value: bank.promise_id }]
|
|
1346
1614
|
});
|
|
1615
|
+
// If the promise is closed or doesn't exist, we don't adjust it
|
|
1347
1616
|
if (!!!promiseQuery || !!!promiseQuery.length)
|
|
1348
1617
|
continue;
|
|
1349
1618
|
if (!!promiseQuery[0].data().ending_date)
|
|
1350
1619
|
continue;
|
|
1620
|
+
// If the bank is inactive, we don't adjust it
|
|
1351
1621
|
const bankInDB = promiseQuery[0].data().banks.find((b) => b.bank_type_id === bank.bank_type_id);
|
|
1352
1622
|
if (!!!bankInDB || !!!bankInDB.active)
|
|
1353
1623
|
continue;
|
|
@@ -1376,6 +1646,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1376
1646
|
}
|
|
1377
1647
|
}
|
|
1378
1648
|
await this.save(partial, undefined, shouldSaveToDB, true);
|
|
1649
|
+
// INVENTORY MANAGEMENT
|
|
1379
1650
|
const data = this.data();
|
|
1380
1651
|
const storeIdToUse = !!data.current_store_id
|
|
1381
1652
|
? data.current_store_id
|
|
@@ -1400,6 +1671,8 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1400
1671
|
previousItems: oldItems,
|
|
1401
1672
|
shouldCheckReservedQte: this.data().status === Cart_1.CartStatusEnum.CHECKOUT_PAYMENT_SUCCESS
|
|
1402
1673
|
});
|
|
1674
|
+
// ASSOCIATED TRANSFER REQUEST MANAGEMENT
|
|
1675
|
+
// Only do logic if order is not already processed
|
|
1403
1676
|
if (!!options.associatedTransferRequests && this.data().status === Cart_1.CartStatusEnum.CHECKOUT_PAYMENT_SUCCESS) {
|
|
1404
1677
|
const transfersWithItemsToUpdate = (0, cart_1.getItemsToUpdateByTransfer)(options.associatedTransferRequests, itemsForInventory.map((i) => ({
|
|
1405
1678
|
item: i,
|
|
@@ -1432,8 +1705,13 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1432
1705
|
}
|
|
1433
1706
|
};
|
|
1434
1707
|
this.defineWhatICanBe = () => {
|
|
1708
|
+
// Pre-order
|
|
1709
|
+
// SDC
|
|
1710
|
+
// Déterminer la règle qui permet de trouver si le cart contient des items en précommande
|
|
1435
1711
|
return [];
|
|
1436
1712
|
};
|
|
1713
|
+
//#endregion
|
|
1714
|
+
//#region DISCOUNTS RULES
|
|
1437
1715
|
this.checkDiscountConditions = (discount) => {
|
|
1438
1716
|
return (0, discount_1.checkPromoCodeEligibility)(this._data, discount);
|
|
1439
1717
|
};
|
|
@@ -1475,13 +1753,14 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1475
1753
|
}
|
|
1476
1754
|
const cartPromo = this.getCartPromo();
|
|
1477
1755
|
if (!!cartPromo && !!cartPromo.length) {
|
|
1756
|
+
// If promo already in cart
|
|
1478
1757
|
if (!!cartPromo.some((i) => i.promo_code === promoCode)) {
|
|
1479
1758
|
this.addError(Cart_1.CartErrorEnum.PROMO_CODE_ALREADY_IN_CART);
|
|
1480
1759
|
return Cart_1.CartErrorEnum.PROMO_CODE_ALREADY_IN_CART;
|
|
1481
1760
|
}
|
|
1482
1761
|
if (!!cartPromo.some((i) => i.promo_code) ||
|
|
1483
1762
|
!!cartData.free_shipping ||
|
|
1484
|
-
(!!!discountWithSamePromoCode.is_stackable && !!cartPromo.length) ||
|
|
1763
|
+
(!!!discountWithSamePromoCode.is_stackable && !!cartPromo.length) || // si non stack et déja kkchose
|
|
1485
1764
|
cartPromo.some((x) => !x.stackable)) {
|
|
1486
1765
|
this.addError(Cart_1.CartErrorEnum.PROMO_CODE_CART_ALREADY_DISCOUNTED);
|
|
1487
1766
|
return Cart_1.CartErrorEnum.PROMO_CODE_CART_ALREADY_DISCOUNTED;
|
|
@@ -1566,6 +1845,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1566
1845
|
}
|
|
1567
1846
|
};
|
|
1568
1847
|
this.setDiscountRules = async (removePaymentIncentive) => {
|
|
1848
|
+
// If cart is a booking cart, discount rules are independant from "normal cart" discount rules, skip check!
|
|
1569
1849
|
if (!!this._data.is_booking || !!this._data.is_booking_beton) {
|
|
1570
1850
|
if (!!__1.isTestEnv)
|
|
1571
1851
|
console.log('skipping discount rule check for booking cart!');
|
|
@@ -1580,13 +1860,16 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1580
1860
|
let discountsToAdd = [];
|
|
1581
1861
|
for (let discount of allDiscountRules) {
|
|
1582
1862
|
let discountData = discount.data();
|
|
1863
|
+
// Remove all draft discounts
|
|
1583
1864
|
if (!!discountData.draft)
|
|
1584
1865
|
continue;
|
|
1866
|
+
// Remove all payment incentive if necessary
|
|
1585
1867
|
if (!!removePaymentIncentive) {
|
|
1586
1868
|
if (!!!discountData.result.action ||
|
|
1587
1869
|
[IDiscountRule_1.ResultActionEnum.AMOUNT_AFTER_TAXES, IDiscountRule_1.ResultActionEnum.PERCENT_AFTER_TAXES].includes(discountData.result.action))
|
|
1588
1870
|
continue;
|
|
1589
1871
|
}
|
|
1872
|
+
// If discount has been overriden don't update it
|
|
1590
1873
|
const cartDiscountRule = this.data().discount_rules.find((rule) => {
|
|
1591
1874
|
return rule.id === discountData.id;
|
|
1592
1875
|
});
|
|
@@ -1600,6 +1883,14 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1600
1883
|
...discountsToAdd
|
|
1601
1884
|
] });
|
|
1602
1885
|
};
|
|
1886
|
+
/**
|
|
1887
|
+
* Check and apply tier pricing prices to items in cart based on values found in specific item. Should be called for every item in cart, and returns all cart items.
|
|
1888
|
+
* @param itemToCheck - The current cart item to check
|
|
1889
|
+
* @param qte - The current cart item qte
|
|
1890
|
+
* @param index - The index of the item in the cart
|
|
1891
|
+
* @param findWithSku - Optionnal. If item should be found by sku instead of index
|
|
1892
|
+
* @param originalDecli - Optionnal. The IIndexedDeclination used to create the cart item. Used to calculate original item price before it was overidden, if necessary. Must be provided in most POS cases.
|
|
1893
|
+
*/
|
|
1603
1894
|
this.checkTierPricing = (itemToCheck, qte, index, findWithSku = false, originalDecli) => {
|
|
1604
1895
|
const currentItems = this._data.items;
|
|
1605
1896
|
if (!!!itemToCheck)
|
|
@@ -1607,13 +1898,21 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1607
1898
|
const item = currentItems.find((anItem) => anItem.sku === (typeof itemToCheck === 'string' ? itemToCheck : itemToCheck.sku));
|
|
1608
1899
|
if (!!!item)
|
|
1609
1900
|
return currentItems;
|
|
1901
|
+
// If item does not have tier_pricing
|
|
1902
|
+
// update quantity and return
|
|
1610
1903
|
if (!!!item.tier_pricing || !!!item.tier_pricing.length) {
|
|
1611
1904
|
this._updateQuantity(item, qte);
|
|
1612
1905
|
return currentItems;
|
|
1613
1906
|
}
|
|
1907
|
+
// If tier_pricing must be counted with other items in cart,
|
|
1908
|
+
// return checkAttributes result
|
|
1909
|
+
// --- This is why we return a full array of items instead of the item checked :
|
|
1910
|
+
// --- some tier_pricing have dependencies with other items in a same cart, so that
|
|
1911
|
+
// --- when a item changes quantities, the price of many items in cart might need to change
|
|
1614
1912
|
if (item.tier_pricing.some((aTier) => !!aTier.check_attribute_value || !!aTier.check_other_items_category)) {
|
|
1615
1913
|
return this.checkAttributes(item, qte);
|
|
1616
1914
|
}
|
|
1915
|
+
// If price was overidden, continue to check tier-pricing, but replace discount_price.original_price instead of discount_price.amount
|
|
1617
1916
|
const setOriginalPrice = !!item.discount_price &&
|
|
1618
1917
|
!!item.discount_price.overridden &&
|
|
1619
1918
|
typeof item.discount_price.original_amount === 'number';
|
|
@@ -1687,6 +1986,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1687
1986
|
for (const aTier of item.tier_pricing) {
|
|
1688
1987
|
if (isFirst && (0, toNumber_1.default)(aTier.from) > totalQte) {
|
|
1689
1988
|
for (const anItem of allSameCategory) {
|
|
1989
|
+
// const index = this._data.items.indexOf(anItem)
|
|
1690
1990
|
this._updateItems(this._data.items.map((i) => {
|
|
1691
1991
|
if (i.sku !== anItem.sku)
|
|
1692
1992
|
return i;
|
|
@@ -1724,6 +2024,13 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1724
2024
|
return Object.assign(Object.assign({}, i), { qte: qte });
|
|
1725
2025
|
}));
|
|
1726
2026
|
};
|
|
2027
|
+
//#endregion
|
|
2028
|
+
//#region TOTALS
|
|
2029
|
+
/**
|
|
2030
|
+
* Get default space taxes for cart. If cart outside of canada, reset taxes to empty array.
|
|
2031
|
+
* @param space
|
|
2032
|
+
* @param allTaxes
|
|
2033
|
+
*/
|
|
1727
2034
|
this._getDefaultTaxesForCart = (space, allTaxes) => {
|
|
1728
2035
|
const shippingAddress = this.data().shipping_address;
|
|
1729
2036
|
const currentTaxes = this.data().taxes;
|
|
@@ -1741,6 +2048,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1741
2048
|
}
|
|
1742
2049
|
}
|
|
1743
2050
|
else if (!!currentTaxes.length) {
|
|
2051
|
+
// Reset to empty array if address is outside of Canada
|
|
1744
2052
|
defaultCartTaxes = [];
|
|
1745
2053
|
}
|
|
1746
2054
|
return defaultCartTaxes;
|
|
@@ -1750,6 +2058,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1750
2058
|
const space = await Space_2.default.getCurrentSpaceWithRef(this._collection.path, this._user);
|
|
1751
2059
|
if (!!!space)
|
|
1752
2060
|
return new Error(`Can't find space`);
|
|
2061
|
+
// 0. Check for general taxes array, in case it was not set correctly on cart init
|
|
1753
2062
|
let allTaxes = this._allTaxes;
|
|
1754
2063
|
if (!!!allTaxes || !!!allTaxes.length) {
|
|
1755
2064
|
try {
|
|
@@ -1770,7 +2079,9 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1770
2079
|
}, logs_1.LogType.ERROR, `error on fetching taxe rates from space: ${e.toString()}`);
|
|
1771
2080
|
}
|
|
1772
2081
|
}
|
|
2082
|
+
// 1. calcul du SUBTOTAL
|
|
1773
2083
|
this.calculateSubtotal(space, forcedPromos);
|
|
2084
|
+
// 2. gestion des taxes selon l'adresse de livraison
|
|
1774
2085
|
const shippingAddress = this.data().shipping_address;
|
|
1775
2086
|
const currentTaxes = this.data().taxes;
|
|
1776
2087
|
const addressForTaxes = !!shippingAddress ? shippingAddress.address : undefined;
|
|
@@ -1787,11 +2098,13 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1787
2098
|
newCartTaxes = [newTaxes];
|
|
1788
2099
|
}
|
|
1789
2100
|
else {
|
|
2101
|
+
// Fetch default space taxes in last resort
|
|
1790
2102
|
newCartTaxes = this._getDefaultTaxesForCart(space, allTaxes);
|
|
1791
2103
|
}
|
|
1792
2104
|
}
|
|
1793
2105
|
}
|
|
1794
2106
|
else {
|
|
2107
|
+
// Fetch default space taxes in last resort
|
|
1795
2108
|
newCartTaxes = this._getDefaultTaxesForCart(space, allTaxes);
|
|
1796
2109
|
}
|
|
1797
2110
|
this._data = Object.assign(Object.assign({}, this._data), { taxes: newCartTaxes });
|
|
@@ -1806,6 +2119,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1806
2119
|
clientToken: (_d = process.env.NEXT_PUBLIC_LOG_SYSTEM_KEY) !== null && _d !== void 0 ? _d : ''
|
|
1807
2120
|
}, logs_1.LogType.ERROR, `NO TAXES IN CART EVEN IF SUBTOTAL HAS AMOUNT! Cart ref: ${this._data.ref}, id: ${this._data.id}`);
|
|
1808
2121
|
}
|
|
2122
|
+
// 3. Calcul du total
|
|
1809
2123
|
try {
|
|
1810
2124
|
this.calculateTotal(true, !!currency ? currency : space.preferences.default.currency());
|
|
1811
2125
|
await this.save(undefined, undefined, false);
|
|
@@ -1823,6 +2137,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1823
2137
|
});
|
|
1824
2138
|
};
|
|
1825
2139
|
this._getSubtotalToCheck = (space, feePromosTotalRemoved, removeServiceFees) => {
|
|
2140
|
+
// ** NEW - Now excludes escompte supp. products from services when checking subtotal for promotions
|
|
1826
2141
|
const serviceFeeProducts = !!!removeServiceFees
|
|
1827
2142
|
? []
|
|
1828
2143
|
: this.data().items.filter((i) => !!i.is_service && !(0, g2_1.isEscompteSuppItem)(i.sku));
|
|
@@ -1833,9 +2148,11 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1833
2148
|
return (0, round_1.default)(((0, isNumber_1.default)(itemPrice) ? Number(itemPrice) : 0) * i.qte, space.data().product_preferences.decimals || 2);
|
|
1834
2149
|
});
|
|
1835
2150
|
let totalRemoved = serviceFeeSubtotal;
|
|
2151
|
+
// If there is a service and fees total, calculates the service and fees total after taking into account their promos
|
|
1836
2152
|
if (!!totalRemoved) {
|
|
1837
2153
|
totalRemoved -= feePromosTotalRemoved;
|
|
1838
2154
|
}
|
|
2155
|
+
// Removes that calculated total from the current subtotal to get the subtotal without services and fees, in order to calculate the right promo amount
|
|
1839
2156
|
return this._data.subtotal - totalRemoved;
|
|
1840
2157
|
};
|
|
1841
2158
|
this.calculateSubtotal = (space, forcedPromos) => {
|
|
@@ -1850,7 +2167,15 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1850
2167
|
const currentCartPromos = this.getCartPromo();
|
|
1851
2168
|
if (!!currentCartPromos && !!currentCartPromos.length) {
|
|
1852
2169
|
const oldSubtotal = this._data.subtotal;
|
|
2170
|
+
// REMOVE PAYMENT INCENTIVE PROMOS FROM ARRAY
|
|
2171
|
+
// Since this type of promos ('total_after_taxes') must be calculated and
|
|
2172
|
+
// removed from total amount AFTER shipping and taxes are calculated,
|
|
2173
|
+
// they will be dealt with later in process and must not count in "subtotalWithoutPromotions" prop
|
|
1853
2174
|
let cartPromos = currentCartPromos.filter((c) => c.applies_to != Cart_1.CartPromoAppliesToEnum.TOTAL_AFTER_TAXES);
|
|
2175
|
+
// REORDER PROMOS
|
|
2176
|
+
// a. if promos apply to products, bring to front of array
|
|
2177
|
+
// b. if promos contain a promo_code that applies to subtotal,
|
|
2178
|
+
// push it to the end of the array to check that one last
|
|
1854
2179
|
cartPromos = (0, orderBy_1.default)(cartPromos, (p) => {
|
|
1855
2180
|
if (p.applies_to === Cart_1.CartPromoAppliesToEnum.PRODUCT)
|
|
1856
2181
|
return 1;
|
|
@@ -1891,6 +2216,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1891
2216
|
else {
|
|
1892
2217
|
amountToRemove = (_b = aPromo.amount_removed) !== null && _b !== void 0 ? _b : 0;
|
|
1893
2218
|
}
|
|
2219
|
+
// round amountToRemove before removing from subtotal
|
|
1894
2220
|
amountToRemove = (0, round_1.default)(amountToRemove, 2);
|
|
1895
2221
|
const newSubtotal = amountUnit === IDiscountRule_1.ResultActionEnum.AMOUNT || aPromo.applies_to === Cart_1.CartPromoAppliesToEnum.PRODUCT
|
|
1896
2222
|
? this._data.subtotal - amountToRemove
|
|
@@ -1898,6 +2224,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1898
2224
|
this._data = Object.assign(Object.assign({}, this._data), { subtotalWithoutPromotions: oldSubtotal, subtotal: (0, round_1.default)(newSubtotal, 2) });
|
|
1899
2225
|
}
|
|
1900
2226
|
else if (!!aPromo && !!aPromo.free_shipping) {
|
|
2227
|
+
// ** si un item de la liste ne peut être inclu dans la promo free_shipping
|
|
1901
2228
|
if (!!this._data.items.some((item) => !!item.exclude_from_free_shipping)) {
|
|
1902
2229
|
this.addError(Cart_1.CartErrorEnum.FREE_SHIPPING_NOT_ELIGIBLE_BECAUSE_OF_ITEM);
|
|
1903
2230
|
this._data = Object.assign(Object.assign(Object.assign(Object.assign({}, this._data), (!!this._data.cart_promo_applied ? { cart_promo_applied: null } : {})), (!!this._data.cart_promos_applied && !!aPromo.discount_id
|
|
@@ -1907,6 +2234,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1907
2234
|
: {})), { subtotalWithoutPromotions: null, free_shipping: false });
|
|
1908
2235
|
}
|
|
1909
2236
|
else {
|
|
2237
|
+
// ** si l'adresse de shipping n'est pas encore définie
|
|
1910
2238
|
if (!!!this._data.shipping_address) {
|
|
1911
2239
|
this._data = Object.assign(Object.assign(Object.assign(Object.assign({}, this._data), (!!this._data.cart_promo_applied ? { cart_promo_applied: null } : {})), (!!this._data.cart_promos_applied && !!aPromo.discount_id
|
|
1912
2240
|
? {
|
|
@@ -1929,6 +2257,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1929
2257
|
cart_promos_applied: this._data.cart_promos_applied.filter((p) => p.discount_id !== aPromo.discount_id)
|
|
1930
2258
|
}
|
|
1931
2259
|
: {})), { subtotalWithoutPromotions: null });
|
|
2260
|
+
// return "La livraison gratuite n'est pas elligible pour votre région."
|
|
1932
2261
|
}
|
|
1933
2262
|
}
|
|
1934
2263
|
}
|
|
@@ -1947,16 +2276,23 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1947
2276
|
return this._data.subtotal;
|
|
1948
2277
|
};
|
|
1949
2278
|
this.calculateTotal = (canCartBeEmpty, currency = 'CAD') => {
|
|
2279
|
+
// 1. At a minimum, total is always equivalent to the current subtotal amount
|
|
1950
2280
|
const subtotal = (0, round_1.default)(this.data().subtotal, 2);
|
|
1951
2281
|
let total = subtotal;
|
|
2282
|
+
// 2. Check if taxes and shipping should be added to total amount
|
|
1952
2283
|
const shouldCalculate = !!canCartBeEmpty ? this._data.items.length >= 0 : this._data.items.length >= 1;
|
|
1953
2284
|
if (!!shouldCalculate) {
|
|
2285
|
+
// A. Get shipping amount
|
|
1954
2286
|
const shipping = this._checkShippingAmount();
|
|
2287
|
+
// B. Calculate taxes
|
|
1955
2288
|
const taxesAmount = (0, round_1.default)((0, sumBy_1.default)(this.data().taxes, (tax) => (0, sumBy_1.default)(tax.taxes, (t) => this.getATax(t.label_fr, t.value, currency))), 2);
|
|
2289
|
+
// C. Add to total
|
|
1956
2290
|
total += shipping + taxesAmount;
|
|
1957
2291
|
}
|
|
2292
|
+
// 3. Check if cart contains payment incentive promos, and calculate amount from current total
|
|
1958
2293
|
let promoAfterTaxesAmount = (0, round_1.default)((0, discount_1.getAfterTaxesPromosTotalAmount)(this._data), 2);
|
|
1959
2294
|
total -= promoAfterTaxesAmount;
|
|
2295
|
+
// 4. Round total to 2 decimals
|
|
1960
2296
|
total = (0, round_1.default)(total, 2);
|
|
1961
2297
|
this._data = Object.assign(Object.assign({}, this._data), { promo_after_taxes_amount: promoAfterTaxesAmount || null, total: total });
|
|
1962
2298
|
return total;
|
|
@@ -1972,6 +2308,8 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
1972
2308
|
return [];
|
|
1973
2309
|
}
|
|
1974
2310
|
};
|
|
2311
|
+
//#endregion
|
|
2312
|
+
//#region SHIPPING
|
|
1975
2313
|
this._checkShippingAmount = () => {
|
|
1976
2314
|
const cartPromo = this.getCartPromo();
|
|
1977
2315
|
const cartHasFreeShipping = !!this._data.free_shipping || (!!cartPromo && !!cartPromo.find((p) => !!p.free_shipping));
|
|
@@ -2011,11 +2349,16 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2011
2349
|
};
|
|
2012
2350
|
this._getCredz = async () => {
|
|
2013
2351
|
const space = await Space_2.default.getCurrentSpaceWithRef(this._collection.path, this._user);
|
|
2352
|
+
// Shipping
|
|
2353
|
+
// Get external service credentials
|
|
2014
2354
|
const shippingServiceCredz = space.data().external_services.filter((es) => !!es.is_active && es.type === 'shipping');
|
|
2355
|
+
// If no credz
|
|
2015
2356
|
if (!!!shippingServiceCredz) {
|
|
2016
2357
|
const baseShippingCostDeterminedByTheOwner = space.data().transport_preferences.override_shipping_with_cost;
|
|
2358
|
+
// If no base cost
|
|
2017
2359
|
if (baseShippingCostDeterminedByTheOwner === undefined)
|
|
2018
2360
|
throw new Error(`Can't use shipping, pickup only. Admin must provide base shipping cost or set external services credentials like Shipstation.`);
|
|
2361
|
+
// Shipping with base cost
|
|
2019
2362
|
return baseShippingCostDeterminedByTheOwner;
|
|
2020
2363
|
}
|
|
2021
2364
|
return { shippingServiceCredz, space };
|
|
@@ -2025,6 +2368,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2025
2368
|
if (typeof resCredz === 'number' || Array.isArray(resCredz))
|
|
2026
2369
|
return resCredz;
|
|
2027
2370
|
const { shippingServiceCredz, space } = resCredz;
|
|
2371
|
+
// Shipping with external service
|
|
2028
2372
|
(0, console_1.workingMessage)(`Calling ${shippingServiceCredz.map((e) => e.external_service_name).join(', ')} for a quote..`);
|
|
2029
2373
|
const shipment = new Shipment_1.default(this, shippingServiceCredz);
|
|
2030
2374
|
try {
|
|
@@ -2089,6 +2433,10 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2089
2433
|
};
|
|
2090
2434
|
this.packageCartInOneBox = async (dontSaveToCart = false) => {
|
|
2091
2435
|
const space = await Space_2.default.getCurrentSpaceWithRef(this._collection.path, this._user);
|
|
2436
|
+
// if (!!!this._collection.parent) throw new Error(`Can't access space`)
|
|
2437
|
+
// const spaceSnap = await this._collection.parent.get()
|
|
2438
|
+
// if (!!!spaceSnap.exists || !!!spaceSnap.data()) throw new Error(`Can't access space`)
|
|
2439
|
+
// const space = new Space({ ...spaceSnap.data(), id: spaceSnap.id } as ISpace, this._user, spaceSnap.ref)
|
|
2092
2440
|
const spaceData = space.data();
|
|
2093
2441
|
let boxes = [];
|
|
2094
2442
|
if (!!!spaceData.transport_preferences.predefined_boxes ||
|
|
@@ -2119,15 +2467,18 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2119
2467
|
allItemsSplitted.push(item);
|
|
2120
2468
|
}
|
|
2121
2469
|
}
|
|
2470
|
+
// Begin by the biggest item
|
|
2122
2471
|
allItemsSplitted = (0, orderBy_1.default)(allItemsSplitted, (i) => i.shipping_info.weight, 'desc');
|
|
2123
2472
|
const itemsToBox = allItemsSplitted;
|
|
2124
2473
|
const totalVolume = (0, sumBy_1.default)(itemsToBox, (_item) => this._calculateItemVolume(_item));
|
|
2474
|
+
// let _allItemsGoIn: boolean = false
|
|
2125
2475
|
for (const box of boxTemplates) {
|
|
2126
2476
|
if (totalVolume < this._calculateBoxVolume(box) * 0.9) {
|
|
2127
2477
|
boxes = [
|
|
2128
2478
|
...boxes,
|
|
2129
2479
|
Object.assign(Object.assign({}, box), { item_ids: itemsToBox.map((_item) => _item.sku), occupied_volume: totalVolume / this._calculateBoxVolume(box), weight: (0, sumBy_1.default)(itemsToBox, (_item) => (0, weight_1.convertWeight)(_item.shipping_info.weight || 0, _item.shipping_info.unit_weight)) })
|
|
2130
2480
|
];
|
|
2481
|
+
// _allItemsGoIn = true
|
|
2131
2482
|
break;
|
|
2132
2483
|
}
|
|
2133
2484
|
}
|
|
@@ -2138,6 +2489,10 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2138
2489
|
};
|
|
2139
2490
|
this.packageCart = async (dontSaveToCart = false) => {
|
|
2140
2491
|
const space = await Space_2.default.getCurrentSpaceWithRef(this._collection.path, this._user);
|
|
2492
|
+
// if (!!!this._collection.parent) throw new Error(`Can't access space`)
|
|
2493
|
+
// const spaceSnap = await this._collection.parent.get()
|
|
2494
|
+
// if (!!!spaceSnap.exists || !!!spaceSnap.data()) throw new Error(`Can't access space`)
|
|
2495
|
+
// const space = new Space({ ...spaceSnap.data(), id: spaceSnap.id } as ISpace, this._user, spaceSnap.ref)
|
|
2141
2496
|
const spaceData = space.data();
|
|
2142
2497
|
let boxes = [];
|
|
2143
2498
|
if (!!!spaceData.transport_preferences.predefined_boxes ||
|
|
@@ -2168,16 +2523,23 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2168
2523
|
allItemsSplitted.push(item);
|
|
2169
2524
|
}
|
|
2170
2525
|
}
|
|
2526
|
+
// Begin by the biggest item
|
|
2171
2527
|
allItemsSplitted = (0, orderBy_1.default)(allItemsSplitted, (i) => i.shipping_info.weight, 'desc');
|
|
2172
2528
|
for (const item of allItemsSplitted) {
|
|
2173
2529
|
let itemBoxed = false;
|
|
2530
|
+
// If boxes exists
|
|
2174
2531
|
if (!!boxes.length) {
|
|
2175
2532
|
for (const existingBox of (0, orderBy_1.default)(boxes, (b) => b.occupied_volume || 0, 'asc')) {
|
|
2176
2533
|
if (this._doesGoIn(item, existingBox)) {
|
|
2177
2534
|
boxes = [
|
|
2178
2535
|
...boxes.slice(0, (0, indexOf_1.default)(boxes, existingBox)),
|
|
2179
2536
|
Object.assign(Object.assign({}, existingBox), { item_ids: [...existingBox.item_ids, item.sku], occupied_volume: existingBox.occupied_volume +
|
|
2180
|
-
this._calculateItemVolume(item) / this._calculateBoxItemVolume(existingBox),
|
|
2537
|
+
this._calculateItemVolume(item) / this._calculateBoxItemVolume(existingBox),
|
|
2538
|
+
// (existingBox.occupied_volume * this._calculateBoxItemVolume(existingBox) +
|
|
2539
|
+
// this._calculateItemVolume(item)) *
|
|
2540
|
+
// 100 /
|
|
2541
|
+
// this._calculateBoxItemVolume(existingBox),
|
|
2542
|
+
weight: existingBox.weight + (0, weight_1.convertWeight)(item.shipping_info.weight || 0, item.shipping_info.unit_weight) }),
|
|
2181
2543
|
...boxes.slice((0, indexOf_1.default)(boxes, existingBox) + 1)
|
|
2182
2544
|
];
|
|
2183
2545
|
itemBoxed = true;
|
|
@@ -2187,6 +2549,9 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2187
2549
|
}
|
|
2188
2550
|
if (itemBoxed)
|
|
2189
2551
|
continue;
|
|
2552
|
+
// If no boxes are started or item can't go in previous boxes
|
|
2553
|
+
// All items starting by this one can enter a new box
|
|
2554
|
+
// If allitems goes in ?
|
|
2190
2555
|
let _allItemsGoIn = false;
|
|
2191
2556
|
const itemsToBox = allItemsSplitted.slice((0, indexOf_1.default)(allItemsSplitted, item));
|
|
2192
2557
|
const totalVolume = (0, sumBy_1.default)(itemsToBox, (_item) => this._calculateItemVolume(_item));
|
|
@@ -2203,13 +2568,16 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2203
2568
|
if (_allItemsGoIn)
|
|
2204
2569
|
break;
|
|
2205
2570
|
for (const box of boxTemplates) {
|
|
2571
|
+
// Begin by the smallest
|
|
2206
2572
|
if (this._doesGoIn(item, Object.assign(Object.assign({}, box), { item_ids: [], occupied_volume: 0, weight: 0 }))) {
|
|
2573
|
+
// If fits, add item to a new box
|
|
2207
2574
|
boxes = [
|
|
2208
2575
|
...boxes,
|
|
2209
2576
|
Object.assign(Object.assign({}, box), { item_ids: [item.sku], occupied_volume: this._calculateItemVolume(item) / this._calculateBoxVolume(box), weight: (0, weight_1.convertWeight)(item.shipping_info.weight || 0, item.shipping_info.unit_weight) })
|
|
2210
2577
|
];
|
|
2211
2578
|
break;
|
|
2212
2579
|
}
|
|
2580
|
+
// Otherwise create a custom box the size of the item
|
|
2213
2581
|
boxes = [
|
|
2214
2582
|
...boxes,
|
|
2215
2583
|
{
|
|
@@ -2314,6 +2682,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2314
2682
|
throw new Error(`Can't access invoices collection`);
|
|
2315
2683
|
this.save({
|
|
2316
2684
|
shipping_payload: trackingInfo
|
|
2685
|
+
// status: CartStatusEnum.CHECKOUT_SHIPPING
|
|
2317
2686
|
});
|
|
2318
2687
|
};
|
|
2319
2688
|
this._getItems = () => this.data().items;
|
|
@@ -2543,6 +2912,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2543
2912
|
const possible = [
|
|
2544
2913
|
order_1.PackageTypeEnum.MY_ENVELOPE,
|
|
2545
2914
|
order_1.PackageTypeEnum.PACKAGE
|
|
2915
|
+
// PackageTypeEnum.PALLET
|
|
2546
2916
|
];
|
|
2547
2917
|
if (this.getTotalWeight('pounds') <= 1)
|
|
2548
2918
|
possible.push(order_1.PackageTypeEnum.LETTER);
|
|
@@ -2632,6 +3002,15 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2632
3002
|
getBoxDimension: this._getBoxDimension,
|
|
2633
3003
|
setBoxDimension: this._setBoxDimension
|
|
2634
3004
|
};
|
|
3005
|
+
//#endregion
|
|
3006
|
+
//#region PROMISES TO PURCHASE
|
|
3007
|
+
/**
|
|
3008
|
+
* Function updateWithPromiseToPurchasePrices
|
|
3009
|
+
* @description update the cart by replacing the items with their custom price equivalent and add discount items in the cart
|
|
3010
|
+
* @param escompteItems list of discount products from the dash
|
|
3011
|
+
* @param customPriceList list of products with their custom pric from G2
|
|
3012
|
+
* @param banksUsedForCart Optionnal. Array of banks_used applied to cart
|
|
3013
|
+
*/
|
|
2635
3014
|
this.updateWithPromiseToPurchasePrices = async (escompteItems, customPriceList = undefined, banksUsedForCart) => {
|
|
2636
3015
|
if (!!!customPriceList || typeof customPriceList == 'string')
|
|
2637
3016
|
throw new Error('CustomPriceList is undefined!');
|
|
@@ -2642,16 +3021,23 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2642
3021
|
return;
|
|
2643
3022
|
}
|
|
2644
3023
|
const updatedPriceProducts = this.data()
|
|
2645
|
-
.items.filter((item) => !(0, g2_1.isEscompteSuppItem)(item.sku))
|
|
3024
|
+
.items.filter((item) => !(0, g2_1.isEscompteSuppItem)(item.sku)) // remove discount items from the cart
|
|
2646
3025
|
.map((item) => {
|
|
3026
|
+
// Only check customPriceList for prices if :
|
|
3027
|
+
// - banksUsedForCart is not set
|
|
3028
|
+
// - banksUsedForCart contains the associated bank id
|
|
2647
3029
|
const shouldCheckPriceList = !!!banksUsedForCart ||
|
|
2648
3030
|
(!!item.promise_to_purchase_association_ids &&
|
|
2649
3031
|
!!item.promise_to_purchase_association_ids.some((id) => !!banksUsedForCart.map((b) => b.bank_type_id).includes(id)));
|
|
2650
3032
|
return (!!shouldCheckPriceList ? (0, g2_1.checkForCustomPriceEquivalent)(item, customPriceList) : item);
|
|
2651
3033
|
});
|
|
2652
3034
|
const associatedEscomptes = new Array();
|
|
3035
|
+
// for each item in the cart look for an associated discount item
|
|
2653
3036
|
for (let index = 0; index < updatedPriceProducts.length; index++) {
|
|
2654
3037
|
const item = updatedPriceProducts[index];
|
|
3038
|
+
// if item hasn't got an associated bank,
|
|
3039
|
+
// or if associated bank not found in banks used for cart,
|
|
3040
|
+
// don't look for an associated discount item
|
|
2655
3041
|
if (!!!item.promise_to_purchase_association_ids ||
|
|
2656
3042
|
item.promise_to_purchase_association_ids.length == 0 ||
|
|
2657
3043
|
(!!banksUsedForCart &&
|
|
@@ -2669,14 +3055,30 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2669
3055
|
this._data = Object.assign(Object.assign({}, this._data), { items: [...updatedPriceProducts, ...associatedEscomptes] });
|
|
2670
3056
|
await this.calculateTotals();
|
|
2671
3057
|
};
|
|
3058
|
+
/**
|
|
3059
|
+
* Function canBePaidWithMyPromiseToPurchase
|
|
3060
|
+
* @description Check if a cart can be paid with a promise to purchase
|
|
3061
|
+
* @param applicableBanks the list of potential banks that could be applied for cart
|
|
3062
|
+
* @param applicableBanksHistory the list of all associated history entries for applicable banks (flattened in a single array)
|
|
3063
|
+
* @param customPriceList a list of custom price items
|
|
3064
|
+
* @param contingency contingency (from the space)
|
|
3065
|
+
* @param forceCartTypeid Optionnal. A cart type ID to use for bank to apply check, if should be forced
|
|
3066
|
+
* @returns true if cart can be paid, false if it cannot
|
|
3067
|
+
*/
|
|
2672
3068
|
this.canBePaidWithMyPromiseToPurchase = async (applicableBanks, applicableBanksHistory, customPriceList = undefined, contingency = 0, forcedBankTypeId) => {
|
|
2673
3069
|
if (!!!customPriceList || typeof customPriceList == 'string')
|
|
2674
3070
|
throw new Error(PromiseToPurchase_2.ApplyBanksToCartErrorsEnum.CUSTOM_PRICE_LIST_UNDEFINED);
|
|
3071
|
+
// NEW - used to have a check here if contingency was undefined, but it makes more sense to let the logic pass, even if no contingency exists (could be a volontary decision from user)
|
|
2675
3072
|
await this._savePromiseToPurchaseInCart(applicableBanks, false);
|
|
3073
|
+
// Calculate remaining amounts
|
|
2676
3074
|
try {
|
|
2677
3075
|
const space = await Space_2.default.getCurrentSpaceWithRef(this._collection.path, this._user);
|
|
2678
3076
|
const remainingAmounts = await PromiseToPurchase_1.default.calculateRemainingAmounts(this, applicableBanks, applicableBanksHistory, space);
|
|
3077
|
+
// If only one bank is used and said bank has no initial amount, returns empty array
|
|
3078
|
+
// (so there is no overlap between "bank goes over allowed amount" and "bank is disabled in promise")
|
|
2679
3079
|
const potentialRemainingAmounts = this.calculatePotentialRemainingAmountsAndSetBanksUsedAmounts(remainingAmounts, applicableBanks, forcedBankTypeId);
|
|
3080
|
+
// if bank to use has no initial amount, return false
|
|
3081
|
+
// if payment for any of the banks goes over the remaining amount + the contingency, return false
|
|
2680
3082
|
if (!!!potentialRemainingAmounts.length) {
|
|
2681
3083
|
throw new Error(PromiseToPurchase_2.ApplyBanksToCartErrorsEnum.BANK_NOT_FOUND);
|
|
2682
3084
|
}
|
|
@@ -2690,14 +3092,26 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2690
3092
|
return e.message;
|
|
2691
3093
|
}
|
|
2692
3094
|
};
|
|
3095
|
+
/**
|
|
3096
|
+
* Function calculatePotentialRemainingAmountsAndSetBanksUsedAmounts
|
|
3097
|
+
* @description Calculate the amounts that would remain in the promise's banks if we paid this cart with the promise and associates the amounts to use in the banks to the cart
|
|
3098
|
+
* @param remainingAmounts remaining amounts BEFORE including this cart
|
|
3099
|
+
* @param applicableBanks the list of potential banks that could be applied for cart
|
|
3100
|
+
* @param promiseToPurchase the promise to purchase
|
|
3101
|
+
* @returns an array of IBankUsed
|
|
3102
|
+
*/
|
|
2693
3103
|
this.calculatePotentialRemainingAmountsAndSetBanksUsedAmounts = (remainingAmounts, applicableBanks, forcedBankTypeId) => {
|
|
2694
3104
|
let accountedForItems = new Array();
|
|
2695
3105
|
let itemsToCheck = this.data().items;
|
|
3106
|
+
// allow payment only if the cart contains at least one item that is associated to only one bank
|
|
2696
3107
|
const singleBankItems = itemsToCheck.filter((item) => !!item.promise_to_purchase_association_ids && item.promise_to_purchase_association_ids.length == 1);
|
|
2697
3108
|
if (singleBankItems.length == 0) {
|
|
2698
3109
|
throw new Error(PromiseToPurchase_2.ApplyBanksToCartErrorsEnum.ONLY_ITEMS_WITH_MULTI_ASSOCIATED_BANKS);
|
|
2699
3110
|
}
|
|
3111
|
+
// manage mixed products if the cart contains any
|
|
3112
|
+
// mixed product => product with no associated bank (can be deduced from any bank) or with more than one associated bank
|
|
2700
3113
|
const multipleBankItems = itemsToCheck.filter((item) => !!!item.promise_to_purchase_association_ids || item.promise_to_purchase_association_ids.length != 1);
|
|
3114
|
+
// If forcedBankTypeId is defined, only keep associated remainingAmount
|
|
2701
3115
|
if (!!forcedBankTypeId) {
|
|
2702
3116
|
let bankToUse = remainingAmounts.find((bank) => bank.bank_type_id == forcedBankTypeId);
|
|
2703
3117
|
if (!!!bankToUse)
|
|
@@ -2725,6 +3139,9 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2725
3139
|
};
|
|
2726
3140
|
}
|
|
2727
3141
|
}
|
|
3142
|
+
// check that not all banks to use are disabled in the promise to purchase
|
|
3143
|
+
// if banks to use is disabled make remainingAmounts an empty array :
|
|
3144
|
+
// the cart won't use bank because no bank corresponding to the cart is enabled in the promise to purchase
|
|
2728
3145
|
if (!!remainingAmounts.length) {
|
|
2729
3146
|
const banksToUse = remainingAmounts;
|
|
2730
3147
|
const promiseBanksToUse = banksToUse
|
|
@@ -2733,6 +3150,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2733
3150
|
return !!sameInApplicable ? sameInApplicable.bank : undefined;
|
|
2734
3151
|
})
|
|
2735
3152
|
.filter((bank) => !!bank);
|
|
3153
|
+
// If all banks to apply are found in inactive promise, throw error
|
|
2736
3154
|
const allBanksAreInInactivePA = promiseBanksToUse.every((b) => {
|
|
2737
3155
|
const sameInApplicable = applicableBanks.find((ab) => ab.bank.bank_type_id === b.bank_type_id);
|
|
2738
3156
|
return !!sameInApplicable && !!!sameInApplicable.pa_is_active;
|
|
@@ -2740,6 +3158,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2740
3158
|
if (!!allBanksAreInInactivePA) {
|
|
2741
3159
|
throw new Error(PromiseToPurchase_2.ApplyBanksToCartErrorsEnum.PA_IS_INACTIVE);
|
|
2742
3160
|
}
|
|
3161
|
+
// If all banks to apply are inactive, throw error
|
|
2743
3162
|
const allBanksAreInactive = promiseBanksToUse.every((b) => {
|
|
2744
3163
|
const sameInApplicable = applicableBanks.find((ab) => ab.bank.bank_type_id === b.bank_type_id);
|
|
2745
3164
|
return !!sameInApplicable && !!!sameInApplicable.bank.active;
|
|
@@ -2747,6 +3166,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2747
3166
|
if (!!allBanksAreInactive) {
|
|
2748
3167
|
throw new Error(PromiseToPurchase_2.ApplyBanksToCartErrorsEnum.BANK_NOT_FOUND);
|
|
2749
3168
|
}
|
|
3169
|
+
// If the bank's pa or the bank itself is inactive, remove from remainingamounts
|
|
2750
3170
|
for (let bankToUse of promiseBanksToUse) {
|
|
2751
3171
|
const sameInApplicable = applicableBanks.find((ab) => ab.bank.bank_type_id === bankToUse.bank_type_id);
|
|
2752
3172
|
if (!!sameInApplicable && (!!!sameInApplicable.pa_is_active || !!!sameInApplicable.bank.active)) {
|
|
@@ -2767,7 +3187,10 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2767
3187
|
let potentialRemainingAmounts = [];
|
|
2768
3188
|
for (let bank of remainingAmounts) {
|
|
2769
3189
|
let amountToRemove = 0;
|
|
2770
|
-
const { bank_type_id, amount } = bank, rest = __rest(bank
|
|
3190
|
+
const { bank_type_id, amount } = bank, rest = __rest(bank
|
|
3191
|
+
// If forcedBankTypeId is defined, and is same bank type than current loop check, use cart subtotal for amountToRemove
|
|
3192
|
+
, ["bank_type_id", "amount"]);
|
|
3193
|
+
// If forcedBankTypeId is defined, and is same bank type than current loop check, use cart subtotal for amountToRemove
|
|
2771
3194
|
if (!!forcedBankTypeId) {
|
|
2772
3195
|
amountToRemove = this.getSubtotal();
|
|
2773
3196
|
}
|
|
@@ -2800,7 +3223,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2800
3223
|
!!!accountedForItems.includes(item.sku));
|
|
2801
3224
|
});
|
|
2802
3225
|
amountToRemove = (0, sumBy_1.default)(itemsToAccount, (item) => {
|
|
2803
|
-
accountedForItems.push(item.sku);
|
|
3226
|
+
accountedForItems.push(item.sku); // do not account for the same items twice if it was already deduced from a bank (for items associated to more than one bank)
|
|
2804
3227
|
const priceToPay = this.getLowestPrice(item);
|
|
2805
3228
|
return priceToPay * item.qte;
|
|
2806
3229
|
});
|
|
@@ -2808,6 +3231,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2808
3231
|
if (amountToRemove > 0 && amount < 1)
|
|
2809
3232
|
throw new Error(PromiseToPurchase_2.ApplyBanksToCartErrorsEnum.EMPTY_BANK);
|
|
2810
3233
|
if (amountToRemove > 0) {
|
|
3234
|
+
// Update banks used array
|
|
2811
3235
|
banksUsed.push(Object.assign(Object.assign({}, rest), { bank_type_id: bank_type_id, amount: amountToRemove }));
|
|
2812
3236
|
potentialRemainingAmounts.push(Object.assign(Object.assign({}, rest), { bank_type_id: bank_type_id, amount: amount - amountToRemove }));
|
|
2813
3237
|
}
|
|
@@ -2833,12 +3257,24 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2833
3257
|
banks_used: bankAmountsUpdated
|
|
2834
3258
|
} });
|
|
2835
3259
|
};
|
|
3260
|
+
/**
|
|
3261
|
+
* Function canBePaidWithPA
|
|
3262
|
+
* @description used to determine whether the cart can be paid with the promise to purchase and to update the items of the cart with the new prices and associated discount items
|
|
3263
|
+
* @param applicableBanks the list of applicable banks for cart
|
|
3264
|
+
* @param customerID the customer ID associated to the cart
|
|
3265
|
+
* @param customPriceList a list of custom price items
|
|
3266
|
+
* @param space the space
|
|
3267
|
+
* @param forcedCartType Optionnal. If provided, overrides cart type found by check cart item types.
|
|
3268
|
+
* @returns the updated cart and a boolean canBePaid determining if the cart can be paid with the promise or not
|
|
3269
|
+
*/
|
|
2836
3270
|
this.canBePaidWithPA = async (applicableBanks, customerID, customPriceList, space, forcedBankTypeId) => {
|
|
2837
3271
|
const contingency = space.promisesToPurchase.getContingency();
|
|
2838
3272
|
const escomptesItems = await space.promisesToPurchase.getEscompteItems();
|
|
3273
|
+
// Get use history for applicable banks
|
|
2839
3274
|
let applicableBanksHistory = [];
|
|
2840
3275
|
for (let applicable of applicableBanks) {
|
|
2841
3276
|
const { promise_id, bank } = applicable;
|
|
3277
|
+
// don't fetch history if no initial_amount
|
|
2842
3278
|
if (!!!bank.initial_amount)
|
|
2843
3279
|
continue;
|
|
2844
3280
|
try {
|
|
@@ -2852,6 +3288,8 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2852
3288
|
}
|
|
2853
3289
|
}
|
|
2854
3290
|
const filteredApplicableBanksHistory = (0, flatten_1.default)(applicableBanksHistory).filter((b) => !!b);
|
|
3291
|
+
// set possible escomptes in cart so correct amounts are used when checking available amounts
|
|
3292
|
+
// only set escomptes in cart based on potential applicableBanks where pa is active, bank is active and initial amount is set
|
|
2855
3293
|
const possibleBanksToUse = applicableBanks
|
|
2856
3294
|
.filter((b) => !!b.pa_is_active && !!b.bank.active && !!b.bank.initial_amount)
|
|
2857
3295
|
.map((b) => ({
|
|
@@ -2862,6 +3300,8 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2862
3300
|
}));
|
|
2863
3301
|
await this.updateWithPromiseToPurchasePrices(escomptesItems, customPriceList, possibleBanksToUse);
|
|
2864
3302
|
const canBePaidCheck = await this.canBePaidWithMyPromiseToPurchase(applicableBanks, filteredApplicableBanksHistory, customPriceList, contingency, forcedBankTypeId);
|
|
3303
|
+
// if banks applicable length is different from banks truly applied to cart,
|
|
3304
|
+
// adjust added escomptes with banks used for cart
|
|
2865
3305
|
if (!!this._data.promise_to_purchase &&
|
|
2866
3306
|
applicableBanks.length !== this._data.promise_to_purchase.banks_used.length) {
|
|
2867
3307
|
await this.updateWithPromiseToPurchasePrices(escomptesItems, customPriceList, this._data.promise_to_purchase.banks_used);
|
|
@@ -2875,8 +3315,10 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2875
3315
|
if (!!!promisesInCart)
|
|
2876
3316
|
return;
|
|
2877
3317
|
const banksToDeactivate = {};
|
|
3318
|
+
// Check for each bank if it should be deactivated
|
|
2878
3319
|
for (let bank of promisesInCart.banks_used) {
|
|
2879
3320
|
try {
|
|
3321
|
+
// Fetch associated promise from DB
|
|
2880
3322
|
const promiseQuery = await space.promisesToPurchase.get({
|
|
2881
3323
|
query: [{ field: 'id', operator: '==', value: bank.promise_id }]
|
|
2882
3324
|
});
|
|
@@ -2886,6 +3328,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2886
3328
|
const sameBankInPromise = promise.data().banks.find((b) => b.bank_type_id === bank.bank_type_id);
|
|
2887
3329
|
if (!!!sameBankInPromise)
|
|
2888
3330
|
throw new Error('Could not find same bank in promise');
|
|
3331
|
+
// Fetch bank use history from index
|
|
2889
3332
|
let bankUseHistory = [];
|
|
2890
3333
|
try {
|
|
2891
3334
|
const historyQuery = await space.promisesToPurchase.getBanksUsedHistory({
|
|
@@ -2894,6 +3337,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2894
3337
|
bankTypeID: bank.bank_type_id
|
|
2895
3338
|
}, { hpp: 1000 });
|
|
2896
3339
|
if (!!historyQuery) {
|
|
3340
|
+
// Only keep history different from current cart
|
|
2897
3341
|
bankUseHistory = historyQuery.filter((h) => !!!h.associated_cart_ref ||
|
|
2898
3342
|
h.associated_cart_ref !== this._data.ref ||
|
|
2899
3343
|
(!!this._data.paid_at && h.date !== (0, moment_1.default)((0, data_1.formatDate)(this._data.paid_at)).unix()));
|
|
@@ -2912,6 +3356,8 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2912
3356
|
clientToken: (_c = process.env.NEXT_PUBLIC_LOG_SYSTEM_KEY) !== null && _c !== void 0 ? _c : ''
|
|
2913
3357
|
}, logs_1.LogType.ERROR, `Cart ref: ${this._data.ref} | Error on fetching history for banks: ${e.toString()}`);
|
|
2914
3358
|
}
|
|
3359
|
+
// Calculated remaining amount without most recent entry
|
|
3360
|
+
// Then remove most recent entry from remaining
|
|
2915
3361
|
const { remaining_amount } = (0, promiseToPurchase_1.calculatedRemainingBankAmount)(sameBankInPromise.initial_amount, bankUseHistory);
|
|
2916
3362
|
if (typeof remaining_amount === 'number') {
|
|
2917
3363
|
const remainingAmount = remaining_amount - bank.amount;
|
|
@@ -2919,6 +3365,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2919
3365
|
clientName: `sdk-admin | Cart | checkForEmptyBanks, space: ${(0, services_1.getSpaceInitialsByID)(space.data().id)}`,
|
|
2920
3366
|
clientToken: (_d = process.env.NEXT_PUBLIC_LOG_SYSTEM_KEY) !== null && _d !== void 0 ? _d : ''
|
|
2921
3367
|
}, logs_1.LogType.INFO, `Cart ref: ${this._data.ref} | Remaining amount for bank ${(0, locale_1.getPrincipalWord)(sameBankInPromise.name, space)}, for customer ${this._data.customer_id}: before ${(0, round_1.default)(remaining_amount, 2)}, after: ${(0, round_1.default)(remainingAmount, 2)}`);
|
|
3368
|
+
// If bank is now empty, set bank to be deactivated
|
|
2922
3369
|
if ((0, round_1.default)(remainingAmount, 2) < 1) {
|
|
2923
3370
|
const promiseAlreadySetInObj = banksToDeactivate[bank.promise_id];
|
|
2924
3371
|
banksToDeactivate[bank.promise_id] = {
|
|
@@ -2943,6 +3390,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2943
3390
|
}
|
|
2944
3391
|
}
|
|
2945
3392
|
try {
|
|
3393
|
+
// Save promises with empty banks
|
|
2946
3394
|
await Promise.all(Object.values(banksToDeactivate).map(async ({ promiseObj, bankIDsWithRemainingAmounts }) => await promiseObj.disableEmptyPABanks(bankIDsWithRemainingAmounts)));
|
|
2947
3395
|
}
|
|
2948
3396
|
catch (e) {
|
|
@@ -2953,6 +3401,8 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2953
3401
|
}, logs_1.LogType.ERROR, `Cart ref: ${this._data.ref} | Error on saving promises with empty banks: ${e.toString()}`);
|
|
2954
3402
|
}
|
|
2955
3403
|
};
|
|
3404
|
+
//#endregion
|
|
3405
|
+
// #region PROCESSED CART
|
|
2956
3406
|
this.setCartAsProcessed = async (processedAtStore, space, options) => {
|
|
2957
3407
|
if (!!!this.data().status || this.data().status != Cart_1.CartStatusEnum.CHECKOUT_PAYMENT_SUCCESS) {
|
|
2958
3408
|
console.log('cannot process cart! returning');
|
|
@@ -2960,16 +3410,21 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2960
3410
|
}
|
|
2961
3411
|
let newData = Object.assign({}, this.data());
|
|
2962
3412
|
let spaceShippingIsProduct = space.preferences.shipping.asProduct.get();
|
|
3413
|
+
// 1. Change cart status to READY_TO_PROCESS or SHIPPING_AWAITING_OR_PICKUP_READY (if pickup of shipping is a product for space)
|
|
2963
3414
|
newData.status =
|
|
2964
3415
|
!!newData.is_pickup || spaceShippingIsProduct
|
|
2965
3416
|
? Cart_1.CartStatusEnum.SHIPPING_AWAITING_OR_PICKUP_READY
|
|
2966
3417
|
: Cart_1.CartStatusEnum.CART_READY_TO_PROCESS;
|
|
3418
|
+
// 2. set current_store_id if not set
|
|
2967
3419
|
if (!!!newData.current_store_id && !!processedAtStore) {
|
|
2968
3420
|
newData.current_store_id = processedAtStore.id;
|
|
2969
3421
|
}
|
|
3422
|
+
// 3. set processed_by props
|
|
2970
3423
|
if (!!options.currentUser) {
|
|
2971
3424
|
newData.processed_by = this.getCartAssignedUserData(options.currentUser, processedAtStore);
|
|
2972
3425
|
}
|
|
3426
|
+
// 4. if quantities unavailable for store, set bypassed quantities property in cart items
|
|
3427
|
+
// also update reserved quantities (if defined) to total required quantity (so any transfers or checks will consider cart as "full" and new quantites will be added to available quantities for store)
|
|
2973
3428
|
if (!!options.unavailableItemQtes) {
|
|
2974
3429
|
const updatedItems = newData.items.map((item) => {
|
|
2975
3430
|
let sameInUnavailable = options.unavailableItemQtes[item.sku];
|
|
@@ -2980,6 +3435,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2980
3435
|
});
|
|
2981
3436
|
newData.items = updatedItems;
|
|
2982
3437
|
}
|
|
3438
|
+
// 5. save cart, return ref
|
|
2983
3439
|
try {
|
|
2984
3440
|
const saved = this.save(newData, undefined, true);
|
|
2985
3441
|
if (!!!saved) {
|
|
@@ -2991,8 +3447,16 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
2991
3447
|
console.log('error on saving cart as processed: ', e.toString());
|
|
2992
3448
|
}
|
|
2993
3449
|
};
|
|
3450
|
+
/**
|
|
3451
|
+
* Change processing store for an un-completed cart that was already processed
|
|
3452
|
+
* @param newProcessedAtStore - New store where cart is to be processed
|
|
3453
|
+
* @param space
|
|
3454
|
+
* @param options.currentUser
|
|
3455
|
+
* @param options.unavailableItemQtes
|
|
3456
|
+
*/
|
|
2994
3457
|
this.changeProcessingStoreForCart = async (newProcessedAtStore, space, options) => {
|
|
2995
3458
|
let cartUpdated = false;
|
|
3459
|
+
// If cart is completed or not already processed once, return
|
|
2996
3460
|
if (!!!this.data().status ||
|
|
2997
3461
|
this.data().status < Cart_1.CartStatusEnum.CART_READY_TO_PROCESS ||
|
|
2998
3462
|
this.data().status >= Cart_1.CartStatusEnum.COMPLETED) {
|
|
@@ -3002,6 +3466,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
3002
3466
|
const prevStoreId = this.data().current_store_id;
|
|
3003
3467
|
const newStoreId = newProcessedAtStore.id;
|
|
3004
3468
|
if (!!prevStoreId && !!newStoreId) {
|
|
3469
|
+
// A. Update inventory for concerned stores :
|
|
3005
3470
|
try {
|
|
3006
3471
|
await space.inventory.ajust(this.data().items, 'updatedProcessingStore', this.data().cart_type, {
|
|
3007
3472
|
currentStoreId: prevStoreId,
|
|
@@ -3012,14 +3477,18 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
3012
3477
|
catch (s) {
|
|
3013
3478
|
console.log('error on ajusting inventory for new processing store');
|
|
3014
3479
|
}
|
|
3480
|
+
// B. Update value for current store id in cart
|
|
3015
3481
|
let newPartialCart = {
|
|
3016
3482
|
id: this._data.id,
|
|
3017
3483
|
current_store_id: newStoreId
|
|
3018
3484
|
};
|
|
3485
|
+
// C. Add updated_by entry to cart
|
|
3019
3486
|
if (!!options.currentUser) {
|
|
3020
3487
|
const updatedByData = this.getCartAssignedUserData(options.currentUser, undefined, Cart_1.UpdateTypeEnum.PROCESSING_STORE);
|
|
3021
3488
|
newPartialCart.updated_by = [...(this._data.updated_by || []), updatedByData];
|
|
3022
3489
|
}
|
|
3490
|
+
// D. if quantities unavailable for store, set bypassed quantities property in cart items
|
|
3491
|
+
// also update reserved quantities (if defined) to total required quantity (so any transfers or checks will consider cart as "full" and new quantites will be added to available quantities for store)
|
|
3023
3492
|
if (!!options.unavailableItemQtes ||
|
|
3024
3493
|
this._data.items.some((i) => typeof i.qte_bypass_inventory_check == 'number')) {
|
|
3025
3494
|
const updatedItems = this._data.items.map((item) => {
|
|
@@ -3032,6 +3501,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
3032
3501
|
});
|
|
3033
3502
|
newPartialCart.items = updatedItems;
|
|
3034
3503
|
}
|
|
3504
|
+
// E. Save cart to database
|
|
3035
3505
|
try {
|
|
3036
3506
|
await this.save(newPartialCart, undefined, true, true);
|
|
3037
3507
|
cartUpdated = true;
|
|
@@ -3045,9 +3515,16 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
3045
3515
|
}
|
|
3046
3516
|
return cartUpdated;
|
|
3047
3517
|
};
|
|
3518
|
+
/**
|
|
3519
|
+
* Create and set new invoice_ref number in cart.
|
|
3520
|
+
* @param space - Space obj.
|
|
3521
|
+
* @param saveToDatabase - Optionnal. Defaults to true in save function
|
|
3522
|
+
* @param newCartRef - Optionnal. If cart does not have ref saved to local object when calling function, will replace ref in data with value provided.
|
|
3523
|
+
*/
|
|
3048
3524
|
this.setCartWithInvoiceRef = async (space, saveToDatabase, newCartRef) => {
|
|
3049
3525
|
let invoiceRef = undefined;
|
|
3050
3526
|
let newData = Object.assign(Object.assign({}, this.data()), (!!newCartRef && !!!this.data().ref ? { ref: newCartRef } : {}));
|
|
3527
|
+
// 1. Check to set new invoice_ref in cart
|
|
3051
3528
|
try {
|
|
3052
3529
|
invoiceRef = await space.invoices.incrementRef(newData);
|
|
3053
3530
|
if (!!invoiceRef) {
|
|
@@ -3061,13 +3538,21 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
3061
3538
|
}
|
|
3062
3539
|
return invoiceRef;
|
|
3063
3540
|
};
|
|
3541
|
+
/**
|
|
3542
|
+
* Save cart to external_service G2 as G2OrderSlip. Created G2 order id is then saved to cart object
|
|
3543
|
+
* @param space
|
|
3544
|
+
* @param saveToDatabase
|
|
3545
|
+
* @param newlyCreatedCartRef
|
|
3546
|
+
= */
|
|
3064
3547
|
this.setG2ExternalOrderRef = async (space, saveToDatabase = true, newlyCreatedCartData) => {
|
|
3065
3548
|
var _b, _c;
|
|
3549
|
+
// Check if space has G2 service set
|
|
3066
3550
|
const G2Service = space.services({ field: 'external_service_name', value: 'G2' });
|
|
3067
3551
|
if (!!!G2Service || !!!G2Service.length) {
|
|
3068
3552
|
console.log('Space does not have G2 set as external service. Returning!');
|
|
3069
3553
|
return;
|
|
3070
3554
|
}
|
|
3555
|
+
// Call G2 service via API
|
|
3071
3556
|
const cartDataToUse = Object.assign(Object.assign({}, this.data()), (newlyCreatedCartData || {}));
|
|
3072
3557
|
let g2OrderRef;
|
|
3073
3558
|
try {
|
|
@@ -3102,6 +3587,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
3102
3587
|
if (attempt === MAX_RETRIES - 1) {
|
|
3103
3588
|
throw err;
|
|
3104
3589
|
}
|
|
3590
|
+
// Wait 500ms before next retry to not hmammer the server
|
|
3105
3591
|
await new Promise((res) => setTimeout(res, 500));
|
|
3106
3592
|
}
|
|
3107
3593
|
}
|
|
@@ -3119,6 +3605,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
3119
3605
|
: `on save to G2 for cart ref ${this.data().ref}`;
|
|
3120
3606
|
const errorCode = !!g2OrderRef ? G2_1.G2OrderSaveErrors.ADDIO_SAVE_CART_ERROR : G2_1.G2OrderSaveErrors.G2_ERROR;
|
|
3121
3607
|
console.log(`${__1.isTestEnv ? 'TESTENV - ' : ''}G2 ORDER BUG ${errorStr}:`, e.toString());
|
|
3608
|
+
// '%%' Will be used as seperator to deconstruct info from logs for daily recap
|
|
3122
3609
|
await (0, logs_1.SystemLog)({
|
|
3123
3610
|
clientName: `sdk-admin | Cart | setG2ExternalOrderRef | ${(0, services_1.getSpaceInitialsByID)(space.data().id)}`,
|
|
3124
3611
|
clientToken: (_c = process.env.NEXT_PUBLIC_LOG_SYSTEM_KEY) !== null && _c !== void 0 ? _c : ''
|
|
@@ -3128,6 +3615,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
3128
3615
|
return g2OrderRef;
|
|
3129
3616
|
};
|
|
3130
3617
|
this.setCartAsRefunded = async (partial, itemsToReturnInventory, storeId) => {
|
|
3618
|
+
//1. Reset Inventories to available for items that were refunded
|
|
3131
3619
|
if (!!itemsToReturnInventory && !!itemsToReturnInventory.length) {
|
|
3132
3620
|
try {
|
|
3133
3621
|
const space = await Space_2.default.getCurrentSpaceWithRef(this._collection.path, this._user);
|
|
@@ -3143,6 +3631,7 @@ class Cart extends baseService_1.BaseServiceClass {
|
|
|
3143
3631
|
console.error(e);
|
|
3144
3632
|
}
|
|
3145
3633
|
}
|
|
3634
|
+
// 2. save cart with info about refunded_qty for each item, then return ref
|
|
3146
3635
|
try {
|
|
3147
3636
|
const saved = this.save(partial, undefined, true);
|
|
3148
3637
|
if (!!!saved) {
|