addio-admin-sdk 1.7.144 → 1.7.145
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/.babelrc +17 -17
- package/.claude/settings.local.json +7 -0
- package/.env +14 -0
- package/.env.dev +14 -14
- package/.github/workflows/run_unit_test.yaml +48 -48
- package/addio-sdk-doc.md +1473 -1473
- package/changelog.md +564 -564
- package/dist/Interfaces/Address/index.d.ts +21 -21
- package/dist/Interfaces/Address/index.js +16 -16
- package/dist/Interfaces/Algolia/index.d.ts +177 -177
- package/dist/Interfaces/Algolia/index.js +2 -2
- package/dist/Interfaces/Attachement/index.d.ts +5 -5
- package/dist/Interfaces/Attachement/index.js +2 -2
- package/dist/Interfaces/Attribute/index.d.ts +53 -53
- package/dist/Interfaces/Attribute/index.js +10 -10
- package/dist/Interfaces/BGJob/index.d.ts +56 -56
- package/dist/Interfaces/BGJob/index.js +25 -25
- package/dist/Interfaces/BaseClass/index.d.ts +8 -8
- package/dist/Interfaces/BaseClass/index.js +2 -2
- package/dist/Interfaces/Blog/IBlogArticle.d.ts +18 -18
- package/dist/Interfaces/Blog/IBlogArticle.js +2 -2
- package/dist/Interfaces/Blog/IBlogAuthor.d.ts +7 -7
- package/dist/Interfaces/Blog/IBlogAuthor.js +2 -2
- package/dist/Interfaces/Blog/IBlogCategory.d.ts +9 -9
- package/dist/Interfaces/Blog/IBlogCategory.js +2 -2
- package/dist/Interfaces/Blog/IBlogComment.d.ts +13 -13
- package/dist/Interfaces/Blog/IBlogComment.js +2 -2
- package/dist/Interfaces/Blog/IBlogKeywords.d.ts +9 -9
- package/dist/Interfaces/Blog/IBlogKeywords.js +2 -2
- package/dist/Interfaces/Booking/index.d.ts +74 -74
- package/dist/Interfaces/Booking/index.js +17 -17
- package/dist/Interfaces/Brand/index.d.ts +15 -15
- package/dist/Interfaces/Brand/index.js +2 -2
- package/dist/Interfaces/CMS/index.d.ts +28 -28
- package/dist/Interfaces/CMS/index.js +5 -5
- package/dist/Interfaces/Cart/IElavonPayload.d.ts +93 -93
- package/dist/Interfaces/Cart/IElavonPayload.js +17 -17
- package/dist/Interfaces/Cart/IPandaPayload.d.ts +64 -64
- package/dist/Interfaces/Cart/IPandaPayload.js +18 -18
- package/dist/Interfaces/Cart/IPaymentCard.d.ts +22 -22
- package/dist/Interfaces/Cart/IPaymentCard.js +44 -44
- package/dist/Interfaces/Cart/IPaypalPayload.d.ts +9 -9
- package/dist/Interfaces/Cart/IPaypalPayload.js +2 -2
- package/dist/Interfaces/Cart/IPaysafePayload.d.ts +72 -72
- package/dist/Interfaces/Cart/IPaysafePayload.js +2 -2
- package/dist/Interfaces/Cart/IStripePayload.d.ts +66 -66
- package/dist/Interfaces/Cart/IStripePayload.js +2 -2
- package/dist/Interfaces/Cart/index.d.ts +444 -444
- package/dist/Interfaces/Cart/index.js +197 -197
- package/dist/Interfaces/CartReservedQuantities/index.d.ts +10 -10
- package/dist/Interfaces/CartReservedQuantities/index.js +2 -2
- package/dist/Interfaces/CashDrawers/index.d.ts +37 -37
- package/dist/Interfaces/CashDrawers/index.js +19 -19
- package/dist/Interfaces/Catalogue/index.d.ts +68 -68
- package/dist/Interfaces/Catalogue/index.js +37 -37
- package/dist/Interfaces/Category/index.d.ts +33 -33
- package/dist/Interfaces/Category/index.js +2 -2
- package/dist/Interfaces/Chart/index.d.ts +11 -11
- package/dist/Interfaces/Chart/index.js +2 -2
- package/dist/Interfaces/Class/index.d.ts +8 -8
- package/dist/Interfaces/Class/index.js +2 -2
- package/dist/Interfaces/Consent/index.d.ts +6 -6
- package/dist/Interfaces/Consent/index.js +2 -2
- package/dist/Interfaces/Context/IContextProps.d.ts +4 -4
- package/dist/Interfaces/Context/IContextProps.js +2 -2
- package/dist/Interfaces/Context/IContextState.d.ts +15 -15
- package/dist/Interfaces/Context/IContextState.js +2 -2
- package/dist/Interfaces/Customer/ICustomerBadge.d.ts +2 -2
- package/dist/Interfaces/Customer/ICustomerBadge.js +2 -2
- package/dist/Interfaces/Customer/ICustomerRating.d.ts +10 -10
- package/dist/Interfaces/Customer/ICustomerRating.js +2 -2
- package/dist/Interfaces/Customer/IStoreCredit.d.ts +13 -13
- package/dist/Interfaces/Customer/IStoreCredit.js +2 -2
- package/dist/Interfaces/Customer/index.d.ts +104 -104
- package/dist/Interfaces/Customer/index.js +148 -148
- package/dist/Interfaces/Declination/index.d.ts +117 -117
- package/dist/Interfaces/Declination/index.js +66 -66
- package/dist/Interfaces/Document/index.d.ts +8 -8
- package/dist/Interfaces/Document/index.js +2 -2
- package/dist/Interfaces/Elastic/index.d.ts +89 -89
- package/dist/Interfaces/Elastic/index.js +2 -2
- package/dist/Interfaces/Email/CustomGR/I3DPrintEmail.d.ts +11 -11
- package/dist/Interfaces/Email/CustomGR/I3DPrintEmail.js +2 -2
- package/dist/Interfaces/Email/CustomGR/IBorrowToolsEmail.d.ts +15 -15
- package/dist/Interfaces/Email/CustomGR/IBorrowToolsEmail.js +2 -2
- package/dist/Interfaces/Email/CustomGR/IPickupMaterialsEmail.d.ts +12 -12
- package/dist/Interfaces/Email/CustomGR/IPickupMaterialsEmail.js +2 -2
- package/dist/Interfaces/Email/CustomGR/IPreMeetingFormEmail.d.ts +36 -36
- package/dist/Interfaces/Email/CustomGR/IPreMeetingFormEmail.js +2 -2
- package/dist/Interfaces/Email/CustomGR/ISponsorRequestEmail.d.ts +12 -12
- package/dist/Interfaces/Email/CustomGR/ISponsorRequestEmail.js +2 -2
- package/dist/Interfaces/Email/CustomGR/ITransportEmail.d.ts +12 -12
- package/dist/Interfaces/Email/CustomGR/ITransportEmail.js +2 -2
- package/dist/Interfaces/Email/CustomGR/ITransportQuoteEmail.d.ts +12 -12
- package/dist/Interfaces/Email/CustomGR/ITransportQuoteEmail.js +2 -2
- package/dist/Interfaces/Email/CustomGR/IVegetalsEmail.d.ts +16 -16
- package/dist/Interfaces/Email/CustomGR/IVegetalsEmail.js +2 -2
- package/dist/Interfaces/Email/CustomGR/IWishlistEmail.d.ts +15 -15
- package/dist/Interfaces/Email/CustomGR/IWishlistEmail.js +2 -2
- package/dist/Interfaces/Email/IAbandonnedCartEmail.d.ts +29 -29
- package/dist/Interfaces/Email/IAbandonnedCartEmail.js +2 -2
- package/dist/Interfaces/Email/IAccountConfirmationEmail.d.ts +22 -22
- package/dist/Interfaces/Email/IAccountConfirmationEmail.js +2 -2
- package/dist/Interfaces/Email/IApplicationEmail.d.ts +19 -19
- package/dist/Interfaces/Email/IApplicationEmail.js +2 -2
- package/dist/Interfaces/Email/IBackInStockEmail.d.ts +21 -21
- package/dist/Interfaces/Email/IBackInStockEmail.js +2 -2
- package/dist/Interfaces/Email/IContactEmail.d.ts +20 -20
- package/dist/Interfaces/Email/IContactEmail.js +2 -2
- package/dist/Interfaces/Email/ICustomerBookingAdminEmail.d.ts +15 -15
- package/dist/Interfaces/Email/ICustomerBookingAdminEmail.js +2 -2
- package/dist/Interfaces/Email/ICustomerBookingEmail.d.ts +14 -14
- package/dist/Interfaces/Email/ICustomerBookingEmail.js +2 -2
- package/dist/Interfaces/Email/IEmail.d.ts +20 -20
- package/dist/Interfaces/Email/IEmail.js +60 -60
- package/dist/Interfaces/Email/IOrderConfirmationEmail.d.ts +47 -47
- package/dist/Interfaces/Email/IOrderConfirmationEmail.js +2 -2
- package/dist/Interfaces/Email/IPasswordResetEmail.d.ts +17 -17
- package/dist/Interfaces/Email/IPasswordResetEmail.js +2 -2
- package/dist/Interfaces/Email/IPhotoShootEmail.d.ts +14 -14
- package/dist/Interfaces/Email/IPhotoShootEmail.js +2 -2
- package/dist/Interfaces/Email/IPickupConfirmation.d.ts +23 -23
- package/dist/Interfaces/Email/IPickupConfirmation.js +2 -2
- package/dist/Interfaces/Email/IShippingConfirmation.d.ts +23 -23
- package/dist/Interfaces/Email/IShippingConfirmation.js +2 -2
- package/dist/Interfaces/Email/IWelcomeEmail.d.ts +19 -19
- package/dist/Interfaces/Email/IWelcomeEmail.js +2 -2
- package/dist/Interfaces/ExportSchema/index.d.ts +7 -7
- package/dist/Interfaces/ExportSchema/index.js +2 -2
- package/dist/Interfaces/ExternalService/BaseExternalService.d.ts +12 -12
- package/dist/Interfaces/ExternalService/BaseExternalService.js +2 -2
- package/dist/Interfaces/ExternalService/ExternalProductsService.d.ts +4 -4
- package/dist/Interfaces/ExternalService/ExternalProductsService.js +2 -2
- package/dist/Interfaces/ExternalService/index.d.ts +9 -9
- package/dist/Interfaces/ExternalService/index.js +2 -2
- package/dist/Interfaces/FirstOrderTracking/index.d.ts +5 -5
- package/dist/Interfaces/FirstOrderTracking/index.js +2 -2
- package/dist/Interfaces/G2/index.d.ts +556 -556
- package/dist/Interfaces/G2/index.js +38 -38
- package/dist/Interfaces/Indexed/Product/IIndexedLastSavedProduct.d.ts +20 -20
- package/dist/Interfaces/Indexed/Product/IIndexedLastSavedProduct.js +2 -2
- package/dist/Interfaces/Indexed/Product/index.d.ts +105 -105
- package/dist/Interfaces/Indexed/Product/index.js +253 -253
- package/dist/Interfaces/Inventory/index.d.ts +19 -19
- package/dist/Interfaces/Inventory/index.js +8 -8
- package/dist/Interfaces/Invoice/index.d.ts +4 -4
- package/dist/Interfaces/Invoice/index.js +2 -2
- package/dist/Interfaces/MarketplacePublication/MarketplaceOrderData.d.ts +3 -3
- package/dist/Interfaces/MarketplacePublication/MarketplaceOrderData.js +2 -2
- package/dist/Interfaces/MarketplacePublication/index.d.ts +23 -23
- package/dist/Interfaces/MarketplacePublication/index.js +22 -22
- package/dist/Interfaces/Menu/index.d.ts +40 -40
- package/dist/Interfaces/Menu/index.js +16 -16
- package/dist/Interfaces/Note/index.d.ts +10 -10
- package/dist/Interfaces/Note/index.js +7 -7
- package/dist/Interfaces/Operations/ICreatedBy.d.ts +6 -6
- package/dist/Interfaces/Operations/ICreatedBy.js +2 -2
- package/dist/Interfaces/Operations/IUpdate.d.ts +5 -5
- package/dist/Interfaces/Operations/IUpdate.js +2 -2
- package/dist/Interfaces/Order/index.d.ts +4 -4
- package/dist/Interfaces/Order/index.js +2 -2
- package/dist/Interfaces/Org/IRelUser.d.ts +9 -9
- package/dist/Interfaces/Org/IRelUser.js +2 -2
- package/dist/Interfaces/Org/index.d.ts +29 -29
- package/dist/Interfaces/Org/index.js +12 -12
- package/dist/Interfaces/Payment/index.d.ts +26 -26
- package/dist/Interfaces/Payment/index.js +14 -14
- package/dist/Interfaces/Product/IAttributeFamily.d.ts +6 -6
- package/dist/Interfaces/Product/IAttributeFamily.js +2 -2
- package/dist/Interfaces/Product/IImportProduct.d.ts +42 -42
- package/dist/Interfaces/Product/IImportProduct.js +882 -882
- package/dist/Interfaces/Product/IInventoryItem.d.ts +74 -74
- package/dist/Interfaces/Product/IInventoryItem.js +38 -38
- package/dist/Interfaces/Product/IPricing.d.ts +177 -177
- package/dist/Interfaces/Product/IPricing.js +180 -180
- package/dist/Interfaces/Product/index.d.ts +138 -138
- package/dist/Interfaces/Product/index.js +64 -64
- package/dist/Interfaces/ProductAttribute/index.d.ts +11 -11
- package/dist/Interfaces/ProductAttribute/index.js +2 -2
- package/dist/Interfaces/PromiseToPurchase/BankType.d.ts +41 -41
- package/dist/Interfaces/PromiseToPurchase/BankType.js +41 -41
- package/dist/Interfaces/PromiseToPurchase/IIndexedBankUsed.d.ts +33 -33
- package/dist/Interfaces/PromiseToPurchase/IIndexedBankUsed.js +15 -15
- package/dist/Interfaces/PromiseToPurchase/IIndexedCustomerPromiseToPurchase.d.ts +19 -19
- package/dist/Interfaces/PromiseToPurchase/IIndexedCustomerPromiseToPurchase.js +2 -2
- package/dist/Interfaces/PromiseToPurchase/index.d.ts +50 -50
- package/dist/Interfaces/PromiseToPurchase/index.js +13 -13
- package/dist/Interfaces/PurchaseOrder/index.d.ts +17 -17
- package/dist/Interfaces/PurchaseOrder/index.js +2 -2
- package/dist/Interfaces/Query/IBrandQueryOptions.d.ts +11 -11
- package/dist/Interfaces/Query/IBrandQueryOptions.js +2 -2
- package/dist/Interfaces/Query/ICategoryQueryOptions.d.ts +11 -11
- package/dist/Interfaces/Query/ICategoryQueryOptions.js +2 -2
- package/dist/Interfaces/Query/IProductQueryOptions.d.ts +16 -16
- package/dist/Interfaces/Query/IProductQueryOptions.js +2 -2
- package/dist/Interfaces/Quote/index.d.ts +5 -5
- package/dist/Interfaces/Quote/index.js +2 -2
- package/dist/Interfaces/Refunds/index.d.ts +106 -106
- package/dist/Interfaces/Refunds/index.js +2 -2
- package/dist/Interfaces/Rules/IDiscountRule.d.ts +155 -155
- package/dist/Interfaces/Rules/IDiscountRule.js +114 -114
- package/dist/Interfaces/Schedule/index.d.ts +48 -48
- package/dist/Interfaces/Schedule/index.js +2 -2
- package/dist/Interfaces/Services/IAddServiceResponse.d.ts +4 -4
- package/dist/Interfaces/Services/IAddServiceResponse.js +2 -2
- package/dist/Interfaces/Services/IService.d.ts +16 -16
- package/dist/Interfaces/Services/IService.js +2 -2
- package/dist/Interfaces/Services/IServiceSecret.d.ts +8 -8
- package/dist/Interfaces/Services/IServiceSecret.js +2 -2
- package/dist/Interfaces/Shipping/Shipstation/carriers.d.ts +10 -10
- package/dist/Interfaces/Shipping/Shipstation/carriers.js +2 -2
- package/dist/Interfaces/Shipping/Shipstation/order.d.ts +227 -227
- package/dist/Interfaces/Shipping/Shipstation/order.js +2 -2
- package/dist/Interfaces/Shipping/Shipstation/quote.d.ts +31 -31
- package/dist/Interfaces/Shipping/Shipstation/quote.js +2 -2
- package/dist/Interfaces/Shipping/Shiptime/order.d.ts +54 -54
- package/dist/Interfaces/Shipping/Shiptime/order.js +71 -71
- package/dist/Interfaces/Shipping/Shiptime/quote.d.ts +111 -111
- package/dist/Interfaces/Shipping/Shiptime/quote.js +2 -2
- package/dist/Interfaces/Slider/GR.d.ts +114 -114
- package/dist/Interfaces/Slider/GR.js +271 -271
- package/dist/Interfaces/Slider/index.d.ts +30 -30
- package/dist/Interfaces/Slider/index.js +2 -2
- package/dist/Interfaces/Space/IExternalService.d.ts +53 -53
- package/dist/Interfaces/Space/IExternalService.js +44 -44
- package/dist/Interfaces/Space/IMember.d.ts +16 -16
- package/dist/Interfaces/Space/IMember.js +9 -9
- package/dist/Interfaces/Space/index.d.ts +407 -405
- package/dist/Interfaces/Space/index.js +174 -174
- package/dist/Interfaces/Space/index.js.map +1 -1
- package/dist/Interfaces/Specials/gr.d.ts +61 -61
- package/dist/Interfaces/Specials/gr.js +2 -2
- package/dist/Interfaces/StockNotification/index.d.ts +7 -7
- package/dist/Interfaces/StockNotification/index.js +2 -2
- package/dist/Interfaces/Store/index.d.ts +63 -63
- package/dist/Interfaces/Store/index.js +27 -27
- package/dist/Interfaces/Supplier/ICommand.d.ts +11 -11
- package/dist/Interfaces/Supplier/ICommand.js +2 -2
- package/dist/Interfaces/Supplier/index.d.ts +36 -36
- package/dist/Interfaces/Supplier/index.js +24 -24
- package/dist/Interfaces/TCG/index.d.ts +161 -161
- package/dist/Interfaces/TCG/index.js +54 -54
- package/dist/Interfaces/Tag/index.d.ts +18 -18
- package/dist/Interfaces/Tag/index.js +2 -2
- package/dist/Interfaces/Tax/index.d.ts +13 -13
- package/dist/Interfaces/Tax/index.js +2 -2
- package/dist/Interfaces/TransferRequest/index.d.ts +103 -103
- package/dist/Interfaces/TransferRequest/index.js +46 -46
- package/dist/Interfaces/Translation/index.d.ts +8 -8
- package/dist/Interfaces/Translation/index.js +5 -5
- package/dist/Interfaces/Update/index.d.ts +10 -10
- package/dist/Interfaces/Update/index.js +2 -2
- package/dist/Interfaces/User/IUser.d.ts +65 -65
- package/dist/Interfaces/User/IUser.js +8 -8
- package/dist/Interfaces/Version/index.d.ts +11 -11
- package/dist/Interfaces/Version/index.js +2 -2
- package/dist/Interfaces/Wishlist/index.d.ts +7 -7
- package/dist/Interfaces/Wishlist/index.js +2 -2
- package/dist/constants/Interfaces/IBaseApi.d.ts +15 -15
- package/dist/constants/Interfaces/IBaseApi.js +2 -2
- package/dist/constants/Interfaces/IEndpointResult.d.ts +9 -9
- package/dist/constants/Interfaces/IEndpointResult.js +2 -2
- package/dist/constants/enums.d.ts +6 -6
- package/dist/constants/enums.js +10 -10
- package/dist/constants/services.d.ts +2 -2
- package/dist/constants/services.js +117 -117
- package/dist/constants/version.d.ts +2 -2
- package/dist/constants/version.js +5 -5
- package/dist/index.d.ts +50 -50
- package/dist/index.js +266 -266
- package/dist/lib/Attribute/index.d.ts +14 -14
- package/dist/lib/Attribute/index.js +186 -186
- package/dist/lib/BGJob/index.d.ts +9 -9
- package/dist/lib/BGJob/index.js +216 -216
- package/dist/lib/BackgroundWorker/index.d.ts +34 -34
- package/dist/lib/BackgroundWorker/index.js +59 -59
- package/dist/lib/Blog/BlogArticle.d.ts +5 -5
- package/dist/lib/Blog/BlogArticle.js +10 -10
- package/dist/lib/Blog/BlogAuthor.d.ts +5 -5
- package/dist/lib/Blog/BlogAuthor.js +10 -10
- package/dist/lib/Blog/BlogCategory.d.ts +5 -5
- package/dist/lib/Blog/BlogCategory.js +10 -10
- package/dist/lib/Blog/BlogKeyword.d.ts +5 -5
- package/dist/lib/Blog/BlogKeyword.js +10 -10
- package/dist/lib/Booking/index.d.ts +85 -85
- package/dist/lib/Booking/index.js +596 -596
- package/dist/lib/Brand/index.d.ts +26 -26
- package/dist/lib/Brand/index.js +131 -131
- package/dist/lib/Cart/index.d.ts +335 -335
- package/dist/lib/Cart/index.js +3977 -3977
- package/dist/lib/CartReservedQuantities/index.d.ts +49 -49
- package/dist/lib/CartReservedQuantities/index.js +159 -159
- package/dist/lib/CashDrawerShift/index.d.ts +83 -83
- package/dist/lib/CashDrawerShift/index.js +205 -205
- package/dist/lib/Catalogue/index.d.ts +15 -15
- package/dist/lib/Catalogue/index.js +78 -78
- package/dist/lib/Category/index.d.ts +34 -34
- package/dist/lib/Category/index.js +230 -230
- package/dist/lib/Class/index.d.ts +16 -16
- package/dist/lib/Class/index.js +66 -66
- package/dist/lib/Consent/index.d.ts +4 -4
- package/dist/lib/Consent/index.js +29 -29
- package/dist/lib/Customer/index.d.ts +30 -30
- package/dist/lib/Customer/index.js +92 -92
- package/dist/lib/Declination/index.d.ts +9 -9
- package/dist/lib/Declination/index.js +26 -26
- package/dist/lib/Discount/index.d.ts +27 -27
- package/dist/lib/Discount/index.js +493 -493
- package/dist/lib/ElasticSearch/index.d.ts +13 -13
- package/dist/lib/ElasticSearch/index.js +50 -50
- package/dist/lib/Elavon/index.d.ts +18 -18
- package/dist/lib/Elavon/index.js +135 -135
- package/dist/lib/Email/AbandonedCartEmail.d.ts +16 -16
- package/dist/lib/Email/AbandonedCartEmail.js +24 -24
- package/dist/lib/Email/AccountConfirmationEmail.d.ts +19 -19
- package/dist/lib/Email/AccountConfirmationEmail.js +30 -30
- package/dist/lib/Email/AdminOrderConfirmationEmail.d.ts +16 -16
- package/dist/lib/Email/AdminOrderConfirmationEmail.js +24 -24
- package/dist/lib/Email/ApplicationEmail.d.ts +16 -16
- package/dist/lib/Email/ApplicationEmail.js +24 -24
- package/dist/lib/Email/BackInStockEmail.d.ts +16 -16
- package/dist/lib/Email/BackInStockEmail.js +24 -24
- package/dist/lib/Email/ContactEmail.d.ts +16 -16
- package/dist/lib/Email/ContactEmail.js +24 -24
- package/dist/lib/Email/CustomerBookingAdminEmail.d.ts +16 -16
- package/dist/lib/Email/CustomerBookingAdminEmail.js +24 -24
- package/dist/lib/Email/CustomerBookingEmail.d.ts +16 -16
- package/dist/lib/Email/CustomerBookingEmail.js +24 -24
- package/dist/lib/Email/OrderConfirmationEmail.d.ts +16 -16
- package/dist/lib/Email/OrderConfirmationEmail.js +24 -24
- package/dist/lib/Email/OrderDenounciationEmail.d.ts +16 -16
- package/dist/lib/Email/OrderDenounciationEmail.js +24 -24
- package/dist/lib/Email/OrderSampleEmail.d.ts +16 -16
- package/dist/lib/Email/OrderSampleEmail.js +24 -24
- package/dist/lib/Email/OtherTypeEmails.d.ts +16 -16
- package/dist/lib/Email/OtherTypeEmails.js +27 -27
- package/dist/lib/Email/PasswordResetEmail.d.ts +16 -16
- package/dist/lib/Email/PasswordResetEmail.js +24 -24
- package/dist/lib/Email/PhotoShootEmail.d.ts +16 -16
- package/dist/lib/Email/PhotoShootEmail.js +24 -24
- package/dist/lib/Email/PickUpConfirmation.d.ts +16 -16
- package/dist/lib/Email/PickUpConfirmation.js +24 -24
- package/dist/lib/Email/ShippingConfirmation.d.ts +16 -16
- package/dist/lib/Email/ShippingConfirmation.js +24 -24
- package/dist/lib/Email/WelcomeEmail.d.ts +16 -16
- package/dist/lib/Email/WelcomeEmail.js +24 -24
- package/dist/lib/Email/index.d.ts +16 -16
- package/dist/lib/Email/index.js +31 -31
- package/dist/lib/ExternalService/Ebay.d.ts +74 -74
- package/dist/lib/ExternalService/Ebay.js +124 -124
- package/dist/lib/ExternalService/index.d.ts +5 -5
- package/dist/lib/ExternalService/index.js +10 -10
- package/dist/lib/FirstOrderTracking/index.d.ts +5 -5
- package/dist/lib/FirstOrderTracking/index.js +10 -10
- package/dist/lib/Indexed/IndexedCart.d.ts +13 -13
- package/dist/lib/Indexed/IndexedCart.js +91 -91
- package/dist/lib/Indexed/Product.d.ts +17 -17
- package/dist/lib/Indexed/Product.js +98 -98
- package/dist/lib/Inventory/index.d.ts +112 -112
- package/dist/lib/Inventory/index.js +492 -492
- package/dist/lib/Invoice/index.d.ts +16 -16
- package/dist/lib/Invoice/index.js +21 -21
- package/dist/lib/MarketplacePublication/index.d.ts +9 -9
- package/dist/lib/MarketplacePublication/index.js +426 -426
- package/dist/lib/Menu/index.d.ts +11 -11
- package/dist/lib/Menu/index.js +107 -107
- package/dist/lib/MongoDB/BaseAPI.d.ts +18 -18
- package/dist/lib/MongoDB/BaseAPI.js +200 -200
- package/dist/lib/Note/index.d.ts +4 -4
- package/dist/lib/Note/index.js +6 -6
- package/dist/lib/Order/index.d.ts +27 -27
- package/dist/lib/Order/index.js +56 -56
- package/dist/lib/Org/index.d.ts +68 -68
- package/dist/lib/Org/index.js +216 -216
- package/dist/lib/PandaPay/index.d.ts +16 -16
- package/dist/lib/PandaPay/index.js +176 -176
- package/dist/lib/Paysafe/index.d.ts +11 -11
- package/dist/lib/Paysafe/index.js +41 -41
- package/dist/lib/Product/index.d.ts +182 -182
- package/dist/lib/Product/index.js +847 -847
- package/dist/lib/ProductAttribute/index.d.ts +15 -15
- package/dist/lib/ProductAttribute/index.js +45 -45
- package/dist/lib/PromiseToPurchase/index.d.ts +109 -109
- package/dist/lib/PromiseToPurchase/index.js +343 -343
- package/dist/lib/PurchaseOrder/index.d.ts +20 -20
- package/dist/lib/PurchaseOrder/index.js +28 -28
- package/dist/lib/Schedule/index.d.ts +5 -5
- package/dist/lib/Schedule/index.js +12 -12
- package/dist/lib/Service/Enum/ServiceEnum.d.ts +3 -3
- package/dist/lib/Service/Enum/ServiceEnum.js +7 -7
- package/dist/lib/Service/index.d.ts +13 -13
- package/dist/lib/Service/index.js +21 -21
- package/dist/lib/Shipment/index.d.ts +28 -28
- package/dist/lib/Shipment/index.js +370 -370
- package/dist/lib/Slider/index.d.ts +22 -22
- package/dist/lib/Slider/index.js +119 -119
- package/dist/lib/Space/index.d.ts +1150 -1150
- package/dist/lib/Space/index.js +5792 -5792
- package/dist/lib/StockNotification/index.d.ts +4 -4
- package/dist/lib/StockNotification/index.js +6 -6
- package/dist/lib/Store/index.d.ts +5 -5
- package/dist/lib/Store/index.js +12 -12
- package/dist/lib/Supplier/Command.d.ts +5 -5
- package/dist/lib/Supplier/Command.js +10 -10
- package/dist/lib/Supplier/index.d.ts +25 -25
- package/dist/lib/Supplier/index.js +27 -27
- package/dist/lib/Tags/index.d.ts +6 -6
- package/dist/lib/Tags/index.js +26 -26
- package/dist/lib/Tax/index.d.ts +8 -8
- package/dist/lib/Tax/index.js +54 -54
- package/dist/lib/TransferRequest/index.d.ts +290 -290
- package/dist/lib/TransferRequest/index.js +1026 -1026
- package/dist/lib/Update/index.d.ts +10 -10
- package/dist/lib/Update/index.js +22 -22
- package/dist/lib/User/index.d.ts +89 -89
- package/dist/lib/User/index.js +328 -328
- package/dist/lib/Wishlist/index.d.ts +5 -5
- package/dist/lib/Wishlist/index.js +10 -10
- package/dist/lib/base.d.ts +14 -14
- package/dist/lib/base.js +62 -62
- package/dist/lib/baseService.d.ts +17 -17
- package/dist/lib/baseService.js +69 -69
- package/dist/rules/GR/constants/data.d.ts +26 -26
- package/dist/rules/GR/constants/data.js +81 -81
- package/dist/rules/GR/constants/expedition.d.ts +4 -4
- package/dist/rules/GR/constants/expedition.js +9 -9
- package/dist/rules/GR/constants/products.d.ts +22 -22
- package/dist/rules/GR/constants/products.js +263 -263
- package/dist/rules/GR/interfaces/cart.d.ts +84 -84
- package/dist/rules/GR/interfaces/cart.js +41 -41
- package/dist/rules/GR/interfaces/data.d.ts +101 -101
- package/dist/rules/GR/interfaces/data.js +114 -114
- package/dist/rules/GR/interfaces/products.d.ts +61 -61
- package/dist/rules/GR/interfaces/products.js +10 -10
- package/dist/rules/GR/utils/cart.d.ts +95 -95
- package/dist/rules/GR/utils/cart.js +839 -836
- package/dist/rules/GR/utils/cart.js.map +1 -1
- package/dist/rules/GR/utils/data.d.ts +3 -3
- package/dist/rules/GR/utils/data.js +28 -28
- package/dist/rules/GR/utils/expedition.d.ts +140 -140
- package/dist/rules/GR/utils/expedition.js +2016 -2016
- package/dist/rules/GR/utils/g2.d.ts +209 -209
- package/dist/rules/GR/utils/g2.js +999 -999
- package/dist/rules/GR/utils/invoices.d.ts +51 -51
- package/dist/rules/GR/utils/invoices.js +215 -215
- package/dist/rules/GR/utils/products.d.ts +277 -277
- package/dist/rules/GR/utils/products.js +1350 -1350
- package/dist/rules/GR/utils/upsells.d.ts +111 -111
- package/dist/rules/GR/utils/upsells.js +215 -215
- package/dist/services/database/BaseProvider.d.ts +29 -29
- package/dist/services/database/BaseProvider.js +28 -28
- package/dist/services/database/BatchUtils.d.ts +14 -14
- package/dist/services/database/BatchUtils.js +43 -43
- package/dist/services/database/Config.d.ts +2 -2
- package/dist/services/database/Config.js +5 -5
- package/dist/services/database/DatabaseService.d.ts +125 -125
- package/dist/services/database/DatabaseService.js +237 -237
- package/dist/services/database/FirebaseProvider.d.ts +17 -17
- package/dist/services/database/FirebaseProvider.js +235 -235
- package/dist/services/database/NotFirebaseProvider.d.ts +49 -49
- package/dist/services/database/NotFirebaseProvider.js +262 -262
- package/dist/services/g2/G2OrderSlip.d.ts +49 -49
- package/dist/services/g2/G2OrderSlip.js +228 -228
- package/dist/services/g2/utils.d.ts +19 -19
- package/dist/services/g2/utils.js +953 -953
- package/dist/services/logs/index.d.ts +23 -23
- package/dist/services/logs/index.js +66 -66
- package/dist/services/marketplace/BaseMarketServiceClass.d.ts +52 -52
- package/dist/services/marketplace/BaseMarketServiceClass.js +111 -111
- package/dist/services/marketplace/CardtraderServiceClass.d.ts +17 -17
- package/dist/services/marketplace/CardtraderServiceClass.js +139 -139
- package/dist/services/marketplace/utils.d.ts +14 -14
- package/dist/services/marketplace/utils.js +29 -29
- package/dist/services/products/BaseClass.d.ts +50 -50
- package/dist/services/products/BaseClass.js +66 -66
- package/dist/services/products/TCGService.d.ts +32 -32
- package/dist/services/products/TCGService.js +555 -555
- package/dist/services/products/utils.d.ts +31 -31
- package/dist/services/products/utils.js +144 -144
- package/dist/utils/algolia.d.ts +46 -46
- package/dist/utils/algolia.js +21 -21
- package/dist/utils/anonymisation.d.ts +54 -54
- package/dist/utils/anonymisation.js +280 -280
- package/dist/utils/array.d.ts +5 -5
- package/dist/utils/array.js +14 -14
- package/dist/utils/aws.d.ts +36 -36
- package/dist/utils/aws.js +154 -154
- package/dist/utils/booking.d.ts +30 -30
- package/dist/utils/booking.js +127 -127
- package/dist/utils/cart.d.ts +259 -259
- package/dist/utils/cart.js +1145 -1145
- package/dist/utils/categories.d.ts +2 -2
- package/dist/utils/categories.js +54 -54
- package/dist/utils/cmv.d.ts +10 -10
- package/dist/utils/cmv.js +107 -107
- package/dist/utils/console.d.ts +6 -6
- package/dist/utils/console.js +59 -59
- package/dist/utils/context.d.ts +20 -20
- package/dist/utils/context.js +61 -61
- package/dist/utils/currency.d.ts +6 -6
- package/dist/utils/currency.js +91 -91
- package/dist/utils/data.d.ts +31 -31
- package/dist/utils/data.js +296 -296
- package/dist/utils/date.d.ts +1 -1
- package/dist/utils/date.js +16 -16
- package/dist/utils/dimensions.d.ts +3 -3
- package/dist/utils/dimensions.js +16 -16
- package/dist/utils/discount.d.ts +164 -164
- package/dist/utils/discount.js +1111 -1111
- package/dist/utils/errors.d.ts +113 -113
- package/dist/utils/errors.js +113 -113
- package/dist/utils/file-admin.d.ts +8 -8
- package/dist/utils/file-admin.js +39 -39
- package/dist/utils/file.d.ts +39 -39
- package/dist/utils/file.js +208 -208
- package/dist/utils/firebase-admin.d.ts +11 -11
- package/dist/utils/firebase-admin.js +73 -73
- package/dist/utils/firebase.d.ts +58 -58
- package/dist/utils/firebase.js +148 -148
- package/dist/utils/import.d.ts +1 -1
- package/dist/utils/import.js +21 -21
- package/dist/utils/inventories.d.ts +101 -101
- package/dist/utils/inventories.js +467 -467
- package/dist/utils/locale.d.ts +24 -24
- package/dist/utils/locale.js +89 -89
- package/dist/utils/mailchimp.d.ts +58 -58
- package/dist/utils/mailchimp.js +531 -531
- package/dist/utils/mathUtils.d.ts +17 -17
- package/dist/utils/mathUtils.js +324 -324
- package/dist/utils/mongodb.d.ts +1 -1
- package/dist/utils/mongodb.js +22 -22
- package/dist/utils/object.d.ts +32 -32
- package/dist/utils/object.js +133 -133
- package/dist/utils/payment.d.ts +10 -10
- package/dist/utils/payment.js +23 -23
- package/dist/utils/products.d.ts +39 -39
- package/dist/utils/products.js +195 -195
- package/dist/utils/promiseToPurchase.d.ts +88 -88
- package/dist/utils/promiseToPurchase.js +229 -229
- package/dist/utils/prosprsearch.d.ts +42 -42
- package/dist/utils/prosprsearch.js +216 -216
- package/dist/utils/refunds.d.ts +2 -2
- package/dist/utils/refunds.js +21 -21
- package/dist/utils/sdc.d.ts +10 -10
- package/dist/utils/sdc.js +1309 -1309
- package/dist/utils/searchIndexes.d.ts +58 -58
- package/dist/utils/searchIndexes.js +247 -247
- package/dist/utils/services.d.ts +42 -42
- package/dist/utils/services.js +409 -409
- package/dist/utils/shipment.d.ts +110 -110
- package/dist/utils/shipment.js +345 -345
- package/dist/utils/simpletexting.d.ts +2 -2
- package/dist/utils/simpletexting.js +45 -45
- package/dist/utils/sliders.d.ts +4 -4
- package/dist/utils/sliders.js +24 -24
- package/dist/utils/string.d.ts +16 -16
- package/dist/utils/string.js +192 -192
- package/dist/utils/tcgService.d.ts +74 -74
- package/dist/utils/tcgService.js +308 -308
- package/dist/utils/tools.d.ts +5 -5
- package/dist/utils/tools.js +13 -13
- package/dist/utils/transferRequests.d.ts +43 -43
- package/dist/utils/transferRequests.js +67 -67
- package/dist/utils/update.d.ts +7 -7
- package/dist/utils/update.js +137 -137
- package/dist/utils/weight.d.ts +3 -3
- package/dist/utils/weight.js +16 -16
- package/dist/utils/zones.d.ts +11 -11
- package/dist/utils/zones.js +218 -218
- package/package.json +107 -107
- package/publish.sh +143 -143
- package/readme.md +182 -182
- package/dist/lib/Queue/index.d.ts +0 -40
- package/dist/lib/Queue/index.js +0 -255
- package/dist/lib/Queue/index.js.map +0 -1
|
@@ -1,1351 +1,1351 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
-
var t = {};
|
|
4
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
-
t[p] = s[p];
|
|
6
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
-
t[p[i]] = s[p[i]];
|
|
10
|
-
}
|
|
11
|
-
return t;
|
|
12
|
-
};
|
|
13
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
-
};
|
|
16
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
-
exports.shouldHideItemIfRegPriceIs0 = exports.getFormattedProdGR = exports.applyProCustomPromo = exports.shouldShowProCustomPromo = exports.fetchFeesBeforeCart = exports.getVracType = exports.getConcreteItemsByAvailability = exports.getConcreteQteText = exports.getInstallItemPrice = exports.getInstallationArray = exports.matchesFuelSurchargeParent = exports.shouldHideItemInCheckout = exports.applyAllInclusiveOverrides = exports.isInstallAllInclusiveActive = exports.getInstallationAllInclusiveFromPriceList = exports.roundGrassQte = exports.handleGrassProductQtyRoundForShipping = exports.getGrassSubQuestionsByType = exports.getGrassServicesFees = exports.getGrassQteText = exports.getMinQtyFeeAmountText = exports.getMinQtyFeeText = exports.getAllMinGrassQuantities = exports.isMinQtyFee = exports.fuseGrassProducts = exports.getAllInstallFromItems = exports.checkIfProductIsInstallation = exports.checkIfIsNonSpecialityGrass = exports.checkIfProductIsOfType = exports.getProductFormOptions = exports.getParentProductCategoryGroup = exports.getProdName = exports.splitOnDashes = exports.getRoundedUnitProductQuantities = exports.getRoundedSellUnitProductQuantities = exports.getDescriptionString = exports.getDescriptionLength = exports.getProductAttributes = exports.productUnitSupportsDecimals = exports.getCorrectPluralSellUnit = exports.getPluralUnitLabelWithSlug = exports.getUnitLabelWithSlug = exports.getProductUnitLabel = exports.getProductSellUnitLabel = void 0;
|
|
18
|
-
const ceil_1 = __importDefault(require("lodash/ceil"));
|
|
19
|
-
const maxBy_1 = __importDefault(require("lodash/maxBy"));
|
|
20
|
-
const orderBy_1 = __importDefault(require("lodash/orderBy"));
|
|
21
|
-
const toNumber_1 = __importDefault(require("lodash/toNumber"));
|
|
22
|
-
const round_1 = __importDefault(require("lodash/round"));
|
|
23
|
-
const flatten_1 = __importDefault(require("lodash/flatten"));
|
|
24
|
-
const uniqBy_1 = __importDefault(require("lodash/uniqBy"));
|
|
25
|
-
const sumBy_1 = __importDefault(require("lodash/sumBy"));
|
|
26
|
-
const floor_1 = __importDefault(require("lodash/floor"));
|
|
27
|
-
const Cart_1 = require("../../../Interfaces/Cart");
|
|
28
|
-
const G2_1 = require("../../../Interfaces/G2");
|
|
29
|
-
const IDiscountRule_1 = require("../../../Interfaces/Rules/IDiscountRule");
|
|
30
|
-
// General utils
|
|
31
|
-
const string_1 = require("../../../utils/string");
|
|
32
|
-
const locale_1 = require("../../../utils/locale");
|
|
33
|
-
const inventories_1 = require("../../../utils/inventories");
|
|
34
|
-
const products_1 = require("../../../utils/products");
|
|
35
|
-
// Specitic utils
|
|
36
|
-
const expedition_1 = require("./expedition");
|
|
37
|
-
const products_2 = require("../constants/products");
|
|
38
|
-
const g2_1 = require("./g2");
|
|
39
|
-
const cart_1 = require("./cart");
|
|
40
|
-
// Specific interfaces
|
|
41
|
-
const products_3 = require("../interfaces/products");
|
|
42
|
-
const data_1 = require("../interfaces/data");
|
|
43
|
-
const cart_2 = require("../interfaces/cart");
|
|
44
|
-
const upsells_1 = require("./upsells");
|
|
45
|
-
const object_1 = require("../../../utils/object");
|
|
46
|
-
// ----------------------------------------------------------------------------------------------------------
|
|
47
|
-
// #region PRODUCT UNITS
|
|
48
|
-
const pluralSellUnits = {
|
|
49
|
-
p2: { fr: 'pi²', en: 'sqft' },
|
|
50
|
-
sac: { fr: 'sacs', en: 'bags' },
|
|
51
|
-
unite: { fr: 'unités', en: 'units' },
|
|
52
|
-
tonne: { fr: 'tonnes', en: 'tons' },
|
|
53
|
-
rouleau: { fr: 'rouleaux', en: 'rolls' }
|
|
54
|
-
};
|
|
55
|
-
const pluralSellUnitsBySlug = {
|
|
56
|
-
p2: { fr: 'pi²', en: 'sqft' },
|
|
57
|
-
sac: { fr: 'sacs', en: 'bags' },
|
|
58
|
-
unite: { fr: 'unités', en: 'units' },
|
|
59
|
-
tonne: { fr: 'tonnes', en: 'tons' },
|
|
60
|
-
roul: { fr: 'rouleaux', en: 'rolls' },
|
|
61
|
-
pal: { fr: 'palettes', en: 'pallets' },
|
|
62
|
-
rg: { fr: 'rangs', en: 'rows' },
|
|
63
|
-
ensemble: { fr: 'ensembles', en: 'kits' },
|
|
64
|
-
pl: { fr: 'pL', en: 'linear feet' },
|
|
65
|
-
mcx: { fr: 'morceaux', en: 'pieces' },
|
|
66
|
-
vg3: { fr: 'vg³', en: 'yd³' },
|
|
67
|
-
demipalsm: { fr: 'Demi-palettes (petite)', en: 'Half-pallets (small)' },
|
|
68
|
-
demipallg: { fr: 'Demi-palettes (lg)', en: 'Half-pallets (lg)' },
|
|
69
|
-
tonnes: { fr: 'tonnes', en: 'tons' },
|
|
70
|
-
bte: { fr: 'boîtes', en: 'boxes' },
|
|
71
|
-
pqt: { fr: 'paquets', en: 'bundles' },
|
|
72
|
-
'': { fr: 'unités', en: 'units' }
|
|
73
|
-
};
|
|
74
|
-
const sellUnitsBySlug = {
|
|
75
|
-
p2: { fr: 'pi²', en: 'sqft' },
|
|
76
|
-
sac: { fr: 'sac', en: 'bag' },
|
|
77
|
-
unite: { fr: 'unité', en: 'unit' },
|
|
78
|
-
tonne: { fr: 'tonne', en: 'ton' },
|
|
79
|
-
roul: { fr: 'rouleau', en: 'roll' },
|
|
80
|
-
pal: { fr: 'palette', en: 'pallet' },
|
|
81
|
-
rg: { fr: 'rang', en: 'row' },
|
|
82
|
-
ensemble: { fr: 'ensemble', en: 'kit' },
|
|
83
|
-
pl: { fr: 'pL', en: 'linear feet' },
|
|
84
|
-
mcx: { fr: 'morceau', en: 'piece' },
|
|
85
|
-
vg3: { fr: 'vg³', en: 'yd³' },
|
|
86
|
-
demipalsm: { fr: 'Demi-palette (petite)', en: 'Half-pallet (small)' },
|
|
87
|
-
demipallg: { fr: 'Demi-palette (lg)', en: 'Half-pallet (lg)' },
|
|
88
|
-
tonnes: { fr: 'tonne', en: 'ton' },
|
|
89
|
-
bte: { fr: 'boîte', en: 'box' },
|
|
90
|
-
pqt: { fr: 'paquet', en: 'bundle' },
|
|
91
|
-
'': { fr: 'unité', en: 'unit' }
|
|
92
|
-
};
|
|
93
|
-
/**
|
|
94
|
-
* @description Returns sell unit label in correct language for a specific product's other_units
|
|
95
|
-
* @param {IFilledDimensionUnits[] | undefined} otherUnits The unit array we have to check to get the sell unit
|
|
96
|
-
* @param {string | undefined} locale The language in which we want to return the label
|
|
97
|
-
* @param {string[]} returnUnitForSlugs An array of the slugs we want to return the unit label for
|
|
98
|
-
* @param {boolean} options.returnPlural If plural version should be returned
|
|
99
|
-
* @param {boolean} options.returnShortByDefault If short version should be prioritized
|
|
100
|
-
*/
|
|
101
|
-
const getProductSellUnitLabel = (otherUnits, locale = 'fr', returnUnitForSlugs, options = {}) => {
|
|
102
|
-
if (!!!otherUnits)
|
|
103
|
-
return '';
|
|
104
|
-
const sellingUnit = otherUnits.find((unit) => !!unit.is_sale_unit);
|
|
105
|
-
if (!!!sellingUnit)
|
|
106
|
-
return '';
|
|
107
|
-
return (0, exports.getUnitLabelWithSlug)(sellingUnit.unit_slug, locale, options.returnPlural, returnUnitForSlugs, options.returnShortByDefault);
|
|
108
|
-
};
|
|
109
|
-
exports.getProductSellUnitLabel = getProductSellUnitLabel;
|
|
110
|
-
/**
|
|
111
|
-
* @description Returns unit label in correct language for a specific product's other_units
|
|
112
|
-
* @param {IFilledDimensionUnits[] | undefined} otherUnits The unit array we have to check to get the sell unit
|
|
113
|
-
* @param {string} type The unit type to check
|
|
114
|
-
* @param {string | undefined} locale The language in which we want to return the label
|
|
115
|
-
* @param {string[]} returnUnitForSlugs An array of the slugs we want to return the unit label for
|
|
116
|
-
* @param {boolean} options.returnPlural If plural version should be returned
|
|
117
|
-
* @param {boolean} options.returnShortByDefault If short version should be prioritized
|
|
118
|
-
*/
|
|
119
|
-
const getProductUnitLabel = (otherUnits, type, locale = 'fr', returnUnitForSlugs, options = {}) => {
|
|
120
|
-
if (!!!otherUnits)
|
|
121
|
-
return '';
|
|
122
|
-
const unitToUse = otherUnits.find((unit) => (type == 'sale_unit' ? unit.is_sale_unit : unit.is_inventory_unit));
|
|
123
|
-
if (!!!unitToUse)
|
|
124
|
-
return '';
|
|
125
|
-
return (0, exports.getUnitLabelWithSlug)(unitToUse.unit_slug, locale, options.returnPlural, returnUnitForSlugs, options.returnShortByDefault);
|
|
126
|
-
};
|
|
127
|
-
exports.getProductUnitLabel = getProductUnitLabel;
|
|
128
|
-
/**
|
|
129
|
-
* Returns the unit label for a specific slug
|
|
130
|
-
* @param {string} unitSlug The slug of the unit for which we want to get the label
|
|
131
|
-
* @param {string | undefined} locale The language in which we want to get the label
|
|
132
|
-
* @param {boolean} getPluralVersion Optionnal - If the plural version should be returned instead.
|
|
133
|
-
* @param {string[]} returnUnitForSlugs The slugs for which we want to return a default value, in this case the unit slug for unit
|
|
134
|
-
* @param {boolean} returnShortByDefault Optionnal - If the short version should be prioritized
|
|
135
|
-
*/
|
|
136
|
-
const getUnitLabelWithSlug = (unitSlug, locale = 'fr', getPluralVersion = false, returnUnitForSlugs, returnShortByDefault) => {
|
|
137
|
-
if (!!returnUnitForSlugs && !!returnUnitForSlugs.includes(unitSlug)) {
|
|
138
|
-
return (0, exports.getUnitLabelWithSlug)('unite', locale, getPluralVersion);
|
|
139
|
-
}
|
|
140
|
-
if (!!getPluralVersion)
|
|
141
|
-
return (0, exports.getPluralUnitLabelWithSlug)(unitSlug, locale, returnUnitForSlugs, returnShortByDefault);
|
|
142
|
-
const shortVersion = !!(0, inventories_1.getUnitShortDict)(unitSlug) ? (0, locale_1.translateILang)((0, inventories_1.getUnitShortDict)(unitSlug), locale) : '';
|
|
143
|
-
const longVersion = !!sellUnitsBySlug[unitSlug] ? (0, locale_1.translateILang)(sellUnitsBySlug[unitSlug], locale) : '';
|
|
144
|
-
if (!!returnShortByDefault)
|
|
145
|
-
return shortVersion;
|
|
146
|
-
return longVersion || shortVersion || unitSlug;
|
|
147
|
-
};
|
|
148
|
-
exports.getUnitLabelWithSlug = getUnitLabelWithSlug;
|
|
149
|
-
/**
|
|
150
|
-
* Returns the plural unit label for a specific slug
|
|
151
|
-
* @deprecated Should use getUnitLabelWithSlug instead (with props getPluralVersion=true)
|
|
152
|
-
* @param {string} unitSlug The slug of the unit for which we want to get the label
|
|
153
|
-
* @param {string | undefined} locale The language in which we want to get the label
|
|
154
|
-
* @param {string[]} returnUnitForSlugs The slugs for which we want to return a default value, in this case the unit slug for unit
|
|
155
|
-
*/
|
|
156
|
-
const getPluralUnitLabelWithSlug = (unitSlug, locale = 'fr', returnUnitForSlugs, useShortIfDifferent) => {
|
|
157
|
-
if (!!returnUnitForSlugs && !!returnUnitForSlugs.includes(unitSlug)) {
|
|
158
|
-
return (0, locale_1.translateILang)(pluralSellUnitsBySlug['unite'], locale);
|
|
159
|
-
}
|
|
160
|
-
const shortVersion = !!(0, inventories_1.getUnitShortDict)(unitSlug) ? (0, locale_1.translateILang)((0, inventories_1.getUnitShortDict)(unitSlug), locale) : '';
|
|
161
|
-
const normalVersion = !!sellUnitsBySlug[unitSlug] ? (0, locale_1.translateILang)(sellUnitsBySlug[unitSlug], locale) : '';
|
|
162
|
-
const pluralVersion = !!pluralSellUnitsBySlug[unitSlug] ? (0, locale_1.translateILang)(pluralSellUnitsBySlug[unitSlug], locale) : '';
|
|
163
|
-
// If useShowIfDifferent is defined, and short version is different from the "normal" version, return short value
|
|
164
|
-
if (useShortIfDifferent && shortVersion != normalVersion)
|
|
165
|
-
return shortVersion;
|
|
166
|
-
return pluralVersion || shortVersion || unitSlug;
|
|
167
|
-
};
|
|
168
|
-
exports.getPluralUnitLabelWithSlug = getPluralUnitLabelWithSlug;
|
|
169
|
-
const getCorrectPluralSellUnit = (sellUnit, locale = 'fr') => {
|
|
170
|
-
if (!!!sellUnit.unit)
|
|
171
|
-
return '';
|
|
172
|
-
const frSellUnit = (0, string_1.string_to_slug)((0, locale_1.translateILang)(sellUnit.unit, 'fr'));
|
|
173
|
-
return !!pluralSellUnits[frSellUnit]
|
|
174
|
-
? (0, locale_1.translateILang)(pluralSellUnits[frSellUnit], locale)
|
|
175
|
-
: (0, locale_1.translateILang)(sellUnit.unit, locale);
|
|
176
|
-
};
|
|
177
|
-
exports.getCorrectPluralSellUnit = getCorrectPluralSellUnit;
|
|
178
|
-
const productUnitSupportsDecimals = (unitSlug, isService) => {
|
|
179
|
-
return !!isService || !!['p2', 'pl', 'vg3', 'tonne'].includes(unitSlug);
|
|
180
|
-
};
|
|
181
|
-
exports.productUnitSupportsDecimals = productUnitSupportsDecimals;
|
|
182
|
-
// #endregion
|
|
183
|
-
// ----------------------------------------------------------------------------------------------------------
|
|
184
|
-
// ----------------------------------------------------------------------------------------------------------
|
|
185
|
-
// #region GENERAL
|
|
186
|
-
const getProductAttributes = (product) => {
|
|
187
|
-
const arrColor = !!product.attributes[data_1.AttributesIdEnumGR.SUBCOLOR]
|
|
188
|
-
? product.attributes[data_1.AttributesIdEnumGR.SUBCOLOR]
|
|
189
|
-
: [];
|
|
190
|
-
const arrDimensions = !!product.attributes[data_1.AttributesIdEnumGR.DIMENSIONS]
|
|
191
|
-
? product.attributes[data_1.AttributesIdEnumGR.DIMENSIONS]
|
|
192
|
-
: [];
|
|
193
|
-
const arrFormats = !!product.attributes[data_1.AttributesIdEnumGR.FORMATS]
|
|
194
|
-
? product.attributes[data_1.AttributesIdEnumGR.FORMATS]
|
|
195
|
-
: [];
|
|
196
|
-
return { colors: arrColor, dimensions: arrDimensions, formats: arrFormats };
|
|
197
|
-
};
|
|
198
|
-
exports.getProductAttributes = getProductAttributes;
|
|
199
|
-
const getDescriptionLength = (description, locale = 'fr') => {
|
|
200
|
-
if (!!!description || !!!(0, locale_1.getLocaleOfDictionnary)(description, locale))
|
|
201
|
-
return 0;
|
|
202
|
-
return (0, string_1.stripHTML)((0, locale_1.getLocaleOfDictionnary)(description, locale)).length;
|
|
203
|
-
};
|
|
204
|
-
exports.getDescriptionLength = getDescriptionLength;
|
|
205
|
-
const getDescriptionString = (showFullDesc, maxLength, description, locale = 'fr') => {
|
|
206
|
-
if (!!showFullDesc || (0, exports.getDescriptionLength)(description, locale) <= maxLength) {
|
|
207
|
-
return (0, string_1.stripHTML)((0, locale_1.getLocaleOfDictionnary)(description, locale));
|
|
208
|
-
}
|
|
209
|
-
let truncated = (0, string_1.stripHTML)((0, locale_1.getLocaleOfDictionnary)(description, locale)).slice(0, maxLength).split(' ');
|
|
210
|
-
truncated.pop();
|
|
211
|
-
return truncated.join(' ') + ' [...]';
|
|
212
|
-
};
|
|
213
|
-
exports.getDescriptionString = getDescriptionString;
|
|
214
|
-
/**
|
|
215
|
-
* Returns rounded product sell_unit quantities depending on current value, value of secondary input if existant and sale unit per command step ratio found in product.
|
|
216
|
-
* @param value {number} - Current quantity as entered by user in first input
|
|
217
|
-
* @param otherUnits {IFilledDimensionUnits[] | undefined} - FilledDimensionUnits found in product (possibly undefined)
|
|
218
|
-
* @param value2 {number | undefined} - Current quantity as entered by user in second input (possibly undefined)
|
|
219
|
-
* @param targetIsSecondaryInput {boolean} - If action was triggered from secondary input (defaults to false)
|
|
220
|
-
*/
|
|
221
|
-
const getRoundedSellUnitProductQuantities = (value, otherUnits = [], value2, targetIsSecondaryInput = false) => {
|
|
222
|
-
var _a;
|
|
223
|
-
const saleUnit = otherUnits.find((unit) => unit.is_sale_unit);
|
|
224
|
-
const commandUnit = otherUnits.find((unit) => unit.is_command_unit);
|
|
225
|
-
const commandStep = otherUnits.find((unit) => unit.is_command_step);
|
|
226
|
-
let roundedQuantities = {
|
|
227
|
-
qte1: value,
|
|
228
|
-
qte2: value2
|
|
229
|
-
};
|
|
230
|
-
// Now rounds quantities in calculations to 2 or 0 decimals (depending on what the unit supports)
|
|
231
|
-
if (!!targetIsSecondaryInput && typeof value2 === 'number') {
|
|
232
|
-
if (!!commandStep && !!commandStep.fitting_unit && !!commandUnit && !!commandUnit.fitting_unit && !!saleUnit) {
|
|
233
|
-
const nbCmdUnitPerCmdStep = (0, round_1.default)(commandStep.fitting_unit / commandUnit.fitting_unit, 5);
|
|
234
|
-
const nbSaleUnitPerCmdStep = (0, round_1.default)(commandStep.fitting_unit / ((_a = saleUnit.fitting_unit) !== null && _a !== void 0 ? _a : 1), (0, exports.productUnitSupportsDecimals)(saleUnit.unit_slug) ? 5 : 0);
|
|
235
|
-
// Round value2 to command step
|
|
236
|
-
const roundedValue = value2 === 0
|
|
237
|
-
? 0
|
|
238
|
-
: _roundNbUnitPerCmdStep(value2, nbCmdUnitPerCmdStep, (0, exports.productUnitSupportsDecimals)(saleUnit.unit_slug) ? 2 : 0);
|
|
239
|
-
// Calculate amount of current command units by dividing roundedValue with nbCmdUnitPerCmdStep
|
|
240
|
-
const nbOfRoundedCmdUnits = roundedValue / nbCmdUnitPerCmdStep;
|
|
241
|
-
// Then multiply result by amount of sale units in one command step
|
|
242
|
-
const nbOfRoundedSaleUnits = nbOfRoundedCmdUnits * nbSaleUnitPerCmdStep;
|
|
243
|
-
roundedQuantities = {
|
|
244
|
-
qte1: value2 === 0
|
|
245
|
-
? 0
|
|
246
|
-
: (0, round_1.default)(nbOfRoundedSaleUnits, !!saleUnit && (0, exports.productUnitSupportsDecimals)(saleUnit.unit_slug) ? 2 : 0),
|
|
247
|
-
qte2: roundedValue
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
}
|
|
251
|
-
else if (!!commandStep && !!commandStep.fitting_unit && !!saleUnit && !!saleUnit.fitting_unit) {
|
|
252
|
-
const cmdStepFittingUnit = commandStep.fitting_unit;
|
|
253
|
-
const saleFittingUnit = saleUnit.fitting_unit;
|
|
254
|
-
const nbSaleUnitPerCmdStep = (0, round_1.default)(cmdStepFittingUnit / saleFittingUnit, (0, exports.productUnitSupportsDecimals)(saleUnit.unit_slug) ? 5 : 0);
|
|
255
|
-
const roundedValue = value === 0
|
|
256
|
-
? 0
|
|
257
|
-
: _roundNbUnitPerCmdStep(value, nbSaleUnitPerCmdStep, (0, exports.productUnitSupportsDecimals)(saleUnit.unit_slug) ? 2 : 0);
|
|
258
|
-
let commandUnitQty = undefined;
|
|
259
|
-
if (!!commandUnit && !!commandUnit.fitting_unit) {
|
|
260
|
-
if (value === 0) {
|
|
261
|
-
commandUnitQty = 0;
|
|
262
|
-
}
|
|
263
|
-
// ** NOTE - Commented section here to fix rounding bug - Commented on 10-09-2025, in relation to bug GR-I540
|
|
264
|
-
// if sell_unit has a fitting unit of 1, we can simply divide the command_unit from roundedValue to get result
|
|
265
|
-
// else if (saleFittingUnit == 1) {
|
|
266
|
-
// console.log('YO YO YO are we HERE&&????')
|
|
267
|
-
// commandUnitQty = round(
|
|
268
|
-
// roundedValue / commandUnit.fitting_unit,
|
|
269
|
-
// productUnitSupportsDecimals(commandUnit.unit_slug) ? 2 : 0
|
|
270
|
-
// )
|
|
271
|
-
// }
|
|
272
|
-
else {
|
|
273
|
-
// Calculate amount of current command steps by dividing roundedValue with saleUnitsPerCommandStep
|
|
274
|
-
// ** NOTE - Added round here on 10-09-2025 in relation to bug GR-I540
|
|
275
|
-
const nbOfCmdSteps = (0, round_1.default)(roundedValue / nbSaleUnitPerCmdStep, (0, exports.productUnitSupportsDecimals)(saleUnit.unit_slug) ? 5 : 0);
|
|
276
|
-
// Then multiply result by amount of command unit in one command step
|
|
277
|
-
commandUnitQty =
|
|
278
|
-
nbOfCmdSteps *
|
|
279
|
-
(0, round_1.default)(cmdStepFittingUnit / commandUnit.fitting_unit, (0, exports.productUnitSupportsDecimals)(commandUnit.unit_slug) ? 5 : 0);
|
|
280
|
-
commandUnitQty = (0, round_1.default)(commandUnitQty, (0, exports.productUnitSupportsDecimals)(commandUnit.unit_slug) ? 2 : 0);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
roundedQuantities = {
|
|
284
|
-
qte1: roundedValue,
|
|
285
|
-
qte2: commandUnitQty
|
|
286
|
-
};
|
|
287
|
-
}
|
|
288
|
-
return roundedQuantities;
|
|
289
|
-
};
|
|
290
|
-
exports.getRoundedSellUnitProductQuantities = getRoundedSellUnitProductQuantities;
|
|
291
|
-
/**
|
|
292
|
-
* Returns rounded product quantities depending on current value per command step ratio found in product.
|
|
293
|
-
* @param value {number} - Current quantity as entered by user in first input
|
|
294
|
-
* @param otherUnits {IFilledDimensionUnits[] | undefined} - FilledDimensionUnits found in product (possibly undefined)
|
|
295
|
-
* @param type {'sale_unit' | 'inventory_unit'} - Quantity type for computing
|
|
296
|
-
*/
|
|
297
|
-
const getRoundedUnitProductQuantities = (value, otherUnits = [], type) => {
|
|
298
|
-
const unitToTest = type == 'sale_unit'
|
|
299
|
-
? otherUnits.find((unit) => unit.is_sale_unit)
|
|
300
|
-
: otherUnits.find((unit) => unit.is_inventory_unit);
|
|
301
|
-
const commandStep = otherUnits.find((unit) => unit.is_command_step);
|
|
302
|
-
let roundedQuantities = value;
|
|
303
|
-
if (!!commandStep && !!commandStep.fitting_unit && unitToTest && unitToTest.fitting_unit) {
|
|
304
|
-
const cmdStepFittingUnit = commandStep.fitting_unit;
|
|
305
|
-
const fittingUnit = unitToTest.fitting_unit;
|
|
306
|
-
const nbUnitPerCmdStep = cmdStepFittingUnit / fittingUnit;
|
|
307
|
-
const roundedValue = value === 0
|
|
308
|
-
? 0
|
|
309
|
-
: _roundNbUnitPerCmdStepV2(value, nbUnitPerCmdStep, (0, exports.productUnitSupportsDecimals)(unitToTest.unit_slug) ? 5 : 0);
|
|
310
|
-
roundedQuantities = roundedValue;
|
|
311
|
-
}
|
|
312
|
-
return roundedQuantities;
|
|
313
|
-
};
|
|
314
|
-
exports.getRoundedUnitProductQuantities = getRoundedUnitProductQuantities;
|
|
315
|
-
const _roundNbUnitPerCmdStepV2 = (value, nbUnitPerCmdStep, decimalsToCheck = 0) => {
|
|
316
|
-
const currentFittingValue = (0, floor_1.default)(value / nbUnitPerCmdStep, 5); // Rounds unsignificant quantities to lower value (ex. if result is 0.000007, we don't want it to round up to 1)
|
|
317
|
-
const roundedUp = (0, round_1.default)((0, ceil_1.default)(currentFittingValue) * nbUnitPerCmdStep, decimalsToCheck);
|
|
318
|
-
// retrun roundedUp as default value.
|
|
319
|
-
return roundedUp;
|
|
320
|
-
};
|
|
321
|
-
const _roundNbUnitPerCmdStep = (value, nbUnitPerCmdStep, decimalsToCheck = 0) => {
|
|
322
|
-
let numberBuffer = 0;
|
|
323
|
-
if (decimalsToCheck > 0) {
|
|
324
|
-
let buffer = '';
|
|
325
|
-
buffer = buffer.padStart(decimalsToCheck - 1, '0');
|
|
326
|
-
numberBuffer = (0, toNumber_1.default)(`0.${buffer}1`);
|
|
327
|
-
}
|
|
328
|
-
const rounded = (0, round_1.default)(value / nbUnitPerCmdStep, decimalsToCheck) * nbUnitPerCmdStep;
|
|
329
|
-
const roundedUp = Math.ceil(value / nbUnitPerCmdStep) * nbUnitPerCmdStep;
|
|
330
|
-
// if rounded value is 0, but roundedUp is > 0, return roundedUp
|
|
331
|
-
if (rounded == 0 && roundedUp > 0)
|
|
332
|
-
return roundedUp;
|
|
333
|
-
// ** NEW - Added on 10-09-2025 in relation to bug GR-I540
|
|
334
|
-
// if provided value is already a multiple of cmdStep, return value
|
|
335
|
-
if ((0, round_1.default)(value % nbUnitPerCmdStep, decimalsToCheck) == 0)
|
|
336
|
-
return rounded;
|
|
337
|
-
// if provided value is larger than rounded, and roundedUp is an exact multiple of rounded, return roundedUp
|
|
338
|
-
if ((0, round_1.default)(value, decimalsToCheck) > rounded + numberBuffer)
|
|
339
|
-
return roundedUp;
|
|
340
|
-
// if rounded value is an exact multiple of cmdStep, return rounded
|
|
341
|
-
if ((0, round_1.default)(rounded, decimalsToCheck) % nbUnitPerCmdStep <= numberBuffer)
|
|
342
|
-
return rounded;
|
|
343
|
-
// retrun roundedUp as default value.
|
|
344
|
-
return roundedUp;
|
|
345
|
-
};
|
|
346
|
-
/**
|
|
347
|
-
*
|
|
348
|
-
* @param {string} stringToSplit
|
|
349
|
-
* @param {string} dummyStringToReplace.currentValue, optionnal, default : '%%-%%'. Used to provide general replace values for a specific string. Is applied to both sections of the splitted string.
|
|
350
|
-
* @param {string} dummyStringToReplace.newValue, optionnal, default : ' - '. Used to provide general replace values for a specific string. Is applied to both sections of the splitted string.
|
|
351
|
-
* @returns {string[]}
|
|
352
|
-
*/
|
|
353
|
-
const splitOnDashes = (stringToSplit, dummyStringToReplace = { currentValue: '%%-%%', newValue: ' - ' }) => {
|
|
354
|
-
let splited = stringToSplit.split(' - ');
|
|
355
|
-
if (splited.length === 1)
|
|
356
|
-
splited = stringToSplit.split(' -');
|
|
357
|
-
if (splited.length === 1)
|
|
358
|
-
splited = stringToSplit.split('- ');
|
|
359
|
-
return [
|
|
360
|
-
splited[0].replace(dummyStringToReplace.currentValue, dummyStringToReplace.newValue),
|
|
361
|
-
...(!!splited[1]
|
|
362
|
-
? [splited.slice(1).join(' - ').replace(dummyStringToReplace.currentValue, dummyStringToReplace.newValue)]
|
|
363
|
-
: [])
|
|
364
|
-
];
|
|
365
|
-
};
|
|
366
|
-
exports.splitOnDashes = splitOnDashes;
|
|
367
|
-
/**
|
|
368
|
-
* Get product name as array. Array created mostly by splitting name on dash symbol (and variations).
|
|
369
|
-
* @param {IIndexedVariationAlgolia | IIndexedProduct} product
|
|
370
|
-
* @param {string | undefined} locale
|
|
371
|
-
* @returns {string[]} - Position 0 is the "commum section" of the name, and position 1 should contain all specifics (ex. color, size, etc...)
|
|
372
|
-
*/
|
|
373
|
-
const getProdName = (product, locale, platform, attributes) => {
|
|
374
|
-
var _a;
|
|
375
|
-
let name;
|
|
376
|
-
if (!!product.full_name) {
|
|
377
|
-
name = (0, locale_1.getLocaleOfDictionnary)(product.full_name, locale);
|
|
378
|
-
}
|
|
379
|
-
else {
|
|
380
|
-
name = (0, locale_1.getLocaleOfDictionnary)(product.name, locale);
|
|
381
|
-
if (!!product.use_parent && !!product.parent_name) {
|
|
382
|
-
if (typeof product.parent_name === 'string') {
|
|
383
|
-
name = product.parent_name;
|
|
384
|
-
}
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
let newNameArray = [];
|
|
388
|
-
const dashesToFind = [' - ', '- ', ' -'];
|
|
389
|
-
// If name includes parenthesis...
|
|
390
|
-
if (name.includes('(')) {
|
|
391
|
-
let newStr = '';
|
|
392
|
-
let strWithParenthesisToCheck = name;
|
|
393
|
-
// a. Replace all occurences of dashesToFind found between parenthesis with '-'
|
|
394
|
-
while (strWithParenthesisToCheck.includes('(')) {
|
|
395
|
-
let positionStart = strWithParenthesisToCheck.indexOf('(');
|
|
396
|
-
let positionEnd = strWithParenthesisToCheck.indexOf(')');
|
|
397
|
-
// When first string between paranthesis found, replace dashesToFind
|
|
398
|
-
let substrToCheck = strWithParenthesisToCheck.substring(positionStart, positionEnd + 1);
|
|
399
|
-
for (let dash of dashesToFind) {
|
|
400
|
-
substrToCheck = substrToCheck.replace(dash, '-');
|
|
401
|
-
}
|
|
402
|
-
// Add updated string to newStr from the beginning to the end of section with parenthesis
|
|
403
|
-
newStr += strWithParenthesisToCheck.substring(0, positionStart) + substrToCheck;
|
|
404
|
-
// Strip checked string to remove section added to newStr.
|
|
405
|
-
// This will mean next time we go through the loop, logic will check for next section with parenthesis. If not found, loop ends.
|
|
406
|
-
strWithParenthesisToCheck =
|
|
407
|
-
positionEnd === strWithParenthesisToCheck.length - 1 ? '' : strWithParenthesisToCheck.substring(positionEnd + 1);
|
|
408
|
-
}
|
|
409
|
-
// Add ending of string to newly formatted string after loop done (in case last parenthesis found was not at the end of the string)
|
|
410
|
-
newStr += strWithParenthesisToCheck;
|
|
411
|
-
// b. Isolate "first part" of string
|
|
412
|
-
const positionOfFirst = newStr.indexOf(')');
|
|
413
|
-
let firstPart = newStr.substring(0, positionOfFirst);
|
|
414
|
-
// If first closing parenthesis is not at end of string and firstPart contains dashesToFind, it means the ' - ' should be keep intact.
|
|
415
|
-
// Replace ' - ' found with uncommon string so we can put it back later, then call splitOnDashes function
|
|
416
|
-
if (positionOfFirst !== newStr.length - 1 && dashesToFind.some((str) => firstPart.includes(str))) {
|
|
417
|
-
const secondPart = newStr.substring(positionOfFirst);
|
|
418
|
-
for (let str of dashesToFind) {
|
|
419
|
-
firstPart.replace(str, '%%-%%');
|
|
420
|
-
}
|
|
421
|
-
newNameArray = (0, exports.splitOnDashes)(`${firstPart}${secondPart}`);
|
|
422
|
-
}
|
|
423
|
-
// Else, simply call splitOnDashes function
|
|
424
|
-
else {
|
|
425
|
-
newNameArray = (0, exports.splitOnDashes)(newStr);
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
// Else, no parenthesis found, call splitOnDashes function
|
|
429
|
-
else {
|
|
430
|
-
newNameArray = (0, exports.splitOnDashes)(name);
|
|
431
|
-
}
|
|
432
|
-
if (platform === 'pos' && !!attributes) {
|
|
433
|
-
for (const attribute of attributes) {
|
|
434
|
-
if (!!!attribute.id)
|
|
435
|
-
continue;
|
|
436
|
-
const productAttributeSlugs = (_a = product.attributes) === null || _a === void 0 ? void 0 : _a[attribute.id];
|
|
437
|
-
if (!!productAttributeSlugs) {
|
|
438
|
-
for (const attrValue of attribute.values) {
|
|
439
|
-
if (productAttributeSlugs.includes(attrValue.slug)) {
|
|
440
|
-
const label = (0, locale_1.getLocaleOfDictionnary)(attrValue.value, locale);
|
|
441
|
-
if (label) {
|
|
442
|
-
newNameArray[0] = newNameArray[0] + ` (${label})`;
|
|
443
|
-
}
|
|
444
|
-
}
|
|
445
|
-
}
|
|
446
|
-
}
|
|
447
|
-
}
|
|
448
|
-
}
|
|
449
|
-
return newNameArray;
|
|
450
|
-
};
|
|
451
|
-
exports.getProdName = getProdName;
|
|
452
|
-
/**
|
|
453
|
-
* Function getParentProductCategoryGroup
|
|
454
|
-
* @param prod - Product to check
|
|
455
|
-
*/
|
|
456
|
-
const getParentProductCategoryGroup = (prod) => {
|
|
457
|
-
let type = 'other';
|
|
458
|
-
if (!!prod.categories && !!prod.categories['lvl0']) {
|
|
459
|
-
const categorySlug = prod.categories['lvl0'];
|
|
460
|
-
switch (categorySlug) {
|
|
461
|
-
case 'gazon':
|
|
462
|
-
if (!!(0, exports.checkIfProductIsOfType)(prod, 'gazon')) {
|
|
463
|
-
type = 'gazon';
|
|
464
|
-
}
|
|
465
|
-
break;
|
|
466
|
-
case 'amenagement-paysager':
|
|
467
|
-
if (!!(0, exports.checkIfProductIsOfType)(prod, 'beton')) {
|
|
468
|
-
type = 'beton';
|
|
469
|
-
}
|
|
470
|
-
break;
|
|
471
|
-
default:
|
|
472
|
-
if (!!(0, exports.checkIfProductIsOfType)(prod, 'vrac')) {
|
|
473
|
-
type = 'vrac';
|
|
474
|
-
}
|
|
475
|
-
break;
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
return type;
|
|
479
|
-
};
|
|
480
|
-
exports.getParentProductCategoryGroup = getParentProductCategoryGroup;
|
|
481
|
-
/**
|
|
482
|
-
* Function getProductFormOptions - Returns all AttributeValues for product to construct options in add to cart form
|
|
483
|
-
* @param product - Product to check
|
|
484
|
-
* @param attributes - Array of IAttributes to fetch info from
|
|
485
|
-
*/
|
|
486
|
-
const getProductFormOptions = (product, attributes) => {
|
|
487
|
-
let allColorOptions = [];
|
|
488
|
-
let allDimensionOptions = [];
|
|
489
|
-
let allFormatOptions = [];
|
|
490
|
-
//Product Attributes
|
|
491
|
-
const product_attributes = (0, exports.getProductAttributes)(product);
|
|
492
|
-
//Overridden attr
|
|
493
|
-
let overridenAttributes = product.declinations
|
|
494
|
-
.map((declination) => declination.overriden_attributes)
|
|
495
|
-
.filter((ova) => !!ova);
|
|
496
|
-
overridenAttributes = (0, flatten_1.default)(overridenAttributes);
|
|
497
|
-
overridenAttributes = (0, uniqBy_1.default)(overridenAttributes, 'slug');
|
|
498
|
-
const getOverriddenValues = (prodAttributes, attrId) => {
|
|
499
|
-
const overridenOptions = !!overridenAttributes.length
|
|
500
|
-
? overridenAttributes.filter((attr) => attr.id === attrId)
|
|
501
|
-
: [];
|
|
502
|
-
let finalOptions = [];
|
|
503
|
-
for (const attr of prodAttributes) {
|
|
504
|
-
let isOverridden = false;
|
|
505
|
-
for (const ovOption of overridenOptions) {
|
|
506
|
-
if (!isOverridden) {
|
|
507
|
-
if (!!attr && attr.slug === ovOption.slug) {
|
|
508
|
-
isOverridden = true;
|
|
509
|
-
finalOptions = [
|
|
510
|
-
...finalOptions,
|
|
511
|
-
Object.assign(Object.assign({}, attr), { other_details: Object.assign(Object.assign({}, attr.other_details), { image: ovOption.overriden_values }) })
|
|
512
|
-
];
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
}
|
|
516
|
-
if (!isOverridden) {
|
|
517
|
-
finalOptions = [...finalOptions, attr];
|
|
518
|
-
}
|
|
519
|
-
}
|
|
520
|
-
return finalOptions;
|
|
521
|
-
};
|
|
522
|
-
// ----------------------------------------------------------
|
|
523
|
-
// #region colors
|
|
524
|
-
const subColorsAttr = attributes.find((attr) => attr.id === data_1.AttributesIdEnumGR.SUBCOLOR);
|
|
525
|
-
if (!!subColorsAttr) {
|
|
526
|
-
const subColors = subColorsAttr.values;
|
|
527
|
-
const colorsAttributes = subColors.filter((sub) => product_attributes.colors.includes(sub.slug));
|
|
528
|
-
const finalColors = getOverriddenValues(colorsAttributes, data_1.AttributesIdEnumGR.SUBCOLOR);
|
|
529
|
-
allColorOptions = (0, orderBy_1.default)(finalColors, (color) => product.declinations.findIndex((d) => d.attributes[data_1.AttributesIdEnumGR.SUBCOLOR].includes(color.slug)));
|
|
530
|
-
}
|
|
531
|
-
// #endregion
|
|
532
|
-
// ----------------------------------------------------------
|
|
533
|
-
// ----------------------------------------------------------
|
|
534
|
-
// #region dimensions
|
|
535
|
-
const dimensionsAttr = attributes.find((attr) => attr.id === data_1.AttributesIdEnumGR.DIMENSIONS);
|
|
536
|
-
if (!!dimensionsAttr) {
|
|
537
|
-
const dimensions = dimensionsAttr.values;
|
|
538
|
-
const dimensionsAttributes = dimensions.filter((d) => product_attributes.dimensions.includes(d.slug));
|
|
539
|
-
const finalDimensions = getOverriddenValues(dimensionsAttributes, data_1.AttributesIdEnumGR.DIMENSIONS);
|
|
540
|
-
allDimensionOptions = finalDimensions;
|
|
541
|
-
}
|
|
542
|
-
// #endregion
|
|
543
|
-
// ----------------------------------------------------------
|
|
544
|
-
// ----------------------------------------------------------
|
|
545
|
-
// #region formats
|
|
546
|
-
const formatsAttr = attributes.find((attr) => attr.id === data_1.AttributesIdEnumGR.FORMATS);
|
|
547
|
-
if (!!formatsAttr) {
|
|
548
|
-
const formats = formatsAttr.values;
|
|
549
|
-
allFormatOptions = formats.filter((f) => product_attributes.formats.includes(f.slug));
|
|
550
|
-
}
|
|
551
|
-
// #endregion
|
|
552
|
-
// ----------------------------------------------------------
|
|
553
|
-
return {
|
|
554
|
-
allColors: allColorOptions,
|
|
555
|
-
allDimensions: allDimensionOptions,
|
|
556
|
-
allFormats: allFormatOptions
|
|
557
|
-
};
|
|
558
|
-
};
|
|
559
|
-
exports.getProductFormOptions = getProductFormOptions;
|
|
560
|
-
/**
|
|
561
|
-
* @description Checks if product is of type by checking TYPE attribute value. Works with indexed product or cart item.
|
|
562
|
-
* @param product
|
|
563
|
-
* @param type
|
|
564
|
-
* @param excludeUndefined If excludeUndefined is true, products without the "type" attribute will return true
|
|
565
|
-
* @returns boolean
|
|
566
|
-
*/
|
|
567
|
-
const checkIfProductIsOfType = (product, type, excludeUndefined) => {
|
|
568
|
-
const attr = !!product && !!product.attributes ? product.attributes : {};
|
|
569
|
-
if (!!!attr[data_1.AttributesIdEnumGR.TYPE] && !!excludeUndefined)
|
|
570
|
-
return true;
|
|
571
|
-
return (!!attr[data_1.AttributesIdEnumGR.TYPE] &&
|
|
572
|
-
Array.isArray(attr[data_1.AttributesIdEnumGR.TYPE]) &&
|
|
573
|
-
attr[data_1.AttributesIdEnumGR.TYPE].includes(type));
|
|
574
|
-
};
|
|
575
|
-
exports.checkIfProductIsOfType = checkIfProductIsOfType;
|
|
576
|
-
// #endregion
|
|
577
|
-
// ----------------------------------------------------------------------------------------------------------
|
|
578
|
-
// ----------------------------------------------------------------------------------------------------------
|
|
579
|
-
// #region GRASS
|
|
580
|
-
/**
|
|
581
|
-
* Check if provided sku/slug corresponds to a non-speciality grass item
|
|
582
|
-
* @param sku Grass item's sku
|
|
583
|
-
* @param slug Grass item's parent product slug
|
|
584
|
-
* @param onlyBaseGrass Optionnal. If provided data should only be compared to base grass (aka Kentucky)
|
|
585
|
-
*/
|
|
586
|
-
const checkIfIsNonSpecialityGrass = (sku, slug, onlyBaseGrass) => {
|
|
587
|
-
const skusToCheck = [products_2.kentucky, ...(!onlyBaseGrass ? [products_2.prestige] : [])];
|
|
588
|
-
const slugsToCheck = ['kentucky', ...(!onlyBaseGrass ? ['prestige'] : [])];
|
|
589
|
-
return skusToCheck.includes(sku) || slugsToCheck.includes(slug);
|
|
590
|
-
};
|
|
591
|
-
exports.checkIfIsNonSpecialityGrass = checkIfIsNonSpecialityGrass;
|
|
592
|
-
const checkIfProductIsInstallation = (item) => {
|
|
593
|
-
return !!item.is_service && !!item.parent_slug && !!item.parent_slug.includes('installation');
|
|
594
|
-
};
|
|
595
|
-
exports.checkIfProductIsInstallation = checkIfProductIsInstallation;
|
|
596
|
-
/**
|
|
597
|
-
* Returns array of installation items found in provided array
|
|
598
|
-
* @param items - Array of cart items or IIndexedDeclinations to check
|
|
599
|
-
*/
|
|
600
|
-
const getAllInstallFromItems = (items) => {
|
|
601
|
-
return items.filter((i) => (!!i.parent_slug && products_2.installationProductsSlugs.includes(i.parent_slug)) ||
|
|
602
|
-
Object.values(products_2.installationProSpecSkus).includes(i.sku));
|
|
603
|
-
};
|
|
604
|
-
exports.getAllInstallFromItems = getAllInstallFromItems;
|
|
605
|
-
/**
|
|
606
|
-
* Function fuseGrassProducts
|
|
607
|
-
* @description - Returns items with only one apparent grass product (used for detail customers).
|
|
608
|
-
* ** FOR DISPLAY PURPOSES ONLY - Always save grass products separatly in ICart **
|
|
609
|
-
* @param recursiveItems - ICartItems with subitems (object created for display purposes)
|
|
610
|
-
*/
|
|
611
|
-
const fuseGrassProducts = (recursiveItems, isPro) => {
|
|
612
|
-
const specialityGrass = recursiveItems[0];
|
|
613
|
-
const kentuckyGrass = (specialityGrass.sub_items || []).find((sub) => sub.sku === products_2.kentucky || sub.parent_slug == 'kentucky');
|
|
614
|
-
let newItems = [];
|
|
615
|
-
if (!!kentuckyGrass) {
|
|
616
|
-
const kentuckyPrice = (0, products_1.getLowestPrice)(kentuckyGrass);
|
|
617
|
-
const regPriceKentucky = kentuckyGrass.regular_price.amount;
|
|
618
|
-
const newGrassRegPrice = !!kentuckyPrice.promo ? regPriceKentucky : kentuckyPrice.price.amount;
|
|
619
|
-
const newGrassDiscountPrice = (!!specialityGrass.discount_price
|
|
620
|
-
? specialityGrass.discount_price.amount
|
|
621
|
-
: specialityGrass.regular_price.amount) +
|
|
622
|
-
(!!kentuckyPrice.promo ? kentuckyPrice.price.amount : regPriceKentucky);
|
|
623
|
-
const getLowestPriceSpecialityGrass = (0, products_1.getLowestPrice)(specialityGrass);
|
|
624
|
-
newItems = [
|
|
625
|
-
Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, specialityGrass), { regular_price: Object.assign(Object.assign({}, specialityGrass.regular_price), { amount: newGrassRegPrice + specialityGrass.regular_price.amount }) }), (!!newGrassDiscountPrice
|
|
626
|
-
? {
|
|
627
|
-
discount_price: Object.assign(Object.assign({}, (specialityGrass.discount_price || { currency: 'CAD' })), { amount: newGrassDiscountPrice })
|
|
628
|
-
}
|
|
629
|
-
: {})), (!!specialityGrass.promo_price
|
|
630
|
-
? {
|
|
631
|
-
promo_price: Object.assign(Object.assign({}, specialityGrass.promo_price), { amount: specialityGrass.promo_price.amount + kentuckyPrice.price.amount })
|
|
632
|
-
}
|
|
633
|
-
: {})), (!!!isPro && !!kentuckyGrass.tier_pricing
|
|
634
|
-
? {
|
|
635
|
-
tier_pricing: kentuckyGrass.tier_pricing.map((t) => (Object.assign(Object.assign({}, t), { price: Object.assign(Object.assign({}, t.price), { amount: t.price.amount + getLowestPriceSpecialityGrass.price.amount }) })))
|
|
636
|
-
}
|
|
637
|
-
: {})), { sub_items: [
|
|
638
|
-
Object.assign(Object.assign({}, kentuckyGrass), { hide_from_summary: true }),
|
|
639
|
-
...(specialityGrass.sub_items || []).slice(1)
|
|
640
|
-
] }),
|
|
641
|
-
...recursiveItems.slice(1)
|
|
642
|
-
];
|
|
643
|
-
}
|
|
644
|
-
return newItems;
|
|
645
|
-
};
|
|
646
|
-
exports.fuseGrassProducts = fuseGrassProducts;
|
|
647
|
-
const isMinQtyFee = (slug) => {
|
|
648
|
-
return ['minimum-facturable-commande', 'frais-minimum-gazon-pour-installation'].includes(slug);
|
|
649
|
-
};
|
|
650
|
-
exports.isMinQtyFee = isMinQtyFee;
|
|
651
|
-
const getAllMinGrassQuantities = (grassProduct, isPro) => {
|
|
652
|
-
return {
|
|
653
|
-
pickup: (0, expedition_1.getMinGrassQte)(grassProduct, 'pickup', isPro),
|
|
654
|
-
shipping: (0, expedition_1.getMinGrassQte)(grassProduct, 'shipping', isPro),
|
|
655
|
-
install: (0, expedition_1.getMinQteInstall)(isPro)
|
|
656
|
-
};
|
|
657
|
-
};
|
|
658
|
-
exports.getAllMinGrassQuantities = getAllMinGrassQuantities;
|
|
659
|
-
const getMinQtyFeeText = (parent_slug = '', grassProduct, isPro, locale = 'fr', expeditionMethod, shortVersion) => {
|
|
660
|
-
const type = parent_slug === 'frais-minimum-gazon-pour-installation' ? 'install' : 'order';
|
|
661
|
-
const minQuantities = (0, exports.getAllMinGrassQuantities)(grassProduct, isPro);
|
|
662
|
-
const localeSellUnit = (0, locale_1.translateILang)(pluralSellUnits.p2, locale);
|
|
663
|
-
const localeStepUnit = (0, locale_1.translateILang)((0, inventories_1.getUnitShortDict)('roul'), locale).toLowerCase();
|
|
664
|
-
const localeMinUnit = (0, locale_1.translateILang)((0, inventories_1.getUnitShortDict)('pal'), locale).toLowerCase();
|
|
665
|
-
let str = '';
|
|
666
|
-
const endStr = (0, locale_1.translateILang)({
|
|
667
|
-
fr: ` Ce frais correspond au prix du gazon choisi multiplié par la différence entre la quantité choisie et le minimum.`,
|
|
668
|
-
en: ` Ce frais correspond au prix du gazon choisi multiplié par la différence entre la quantité choisie et le minimum.`
|
|
669
|
-
}, locale);
|
|
670
|
-
// If expedition method not chosen yet, and pickup & shipping quantities are different, show both
|
|
671
|
-
if (!!!expeditionMethod && type === 'order' && minQuantities.pickup !== minQuantities.shipping) {
|
|
672
|
-
const strMinShipping = `${minQuantities.shipping}${localeSellUnit} (${minQuantities.shipping / 740} ${localeMinUnit})`;
|
|
673
|
-
const strMinPickup = !!minQuantities.pickup
|
|
674
|
-
? `${minQuantities.pickup}${localeSellUnit} (${minQuantities.pickup / 740} ${localeMinUnit})`
|
|
675
|
-
: '';
|
|
676
|
-
str = (0, locale_1.translateILang)({
|
|
677
|
-
fr: `Les commandes de gazon sont disponibles à partir de 10${localeSellUnit} (1 ${localeStepUnit}), mais le minimum facturable pour la livraison est de ${strMinShipping}${!!strMinPickup ? ` et de ${strMinPickup} pour la cueillette.` : ``}`,
|
|
678
|
-
en: `Sod orders are available starting at 10${localeSellUnit} (1 ${localeStepUnit}), but the minimum chargeable for delivery is ${strMinShipping}${!!strMinPickup ? ` and ${strMinPickup} for pick-up.` : ``}`
|
|
679
|
-
}, locale);
|
|
680
|
-
if (!!!shortVersion) {
|
|
681
|
-
str += endStr;
|
|
682
|
-
}
|
|
683
|
-
return str;
|
|
684
|
-
}
|
|
685
|
-
// Show specific quantity for expedition type
|
|
686
|
-
const minBillableQty = type === 'install'
|
|
687
|
-
? minQuantities.install
|
|
688
|
-
: expeditionMethod === 'pickup'
|
|
689
|
-
? minQuantities.pickup
|
|
690
|
-
: minQuantities.shipping;
|
|
691
|
-
const minQtyPallets = minBillableQty !== 0 ? minBillableQty / 740 : 0;
|
|
692
|
-
const minBillableStr = `${minBillableQty}${localeSellUnit}${type === 'order' ? ' (' + minQtyPallets + ' ' + localeMinUnit + ')' : ''}`;
|
|
693
|
-
str = (0, locale_1.translateILang)({
|
|
694
|
-
fr: `${type === 'install'
|
|
695
|
-
? "L'installation"
|
|
696
|
-
: expeditionMethod === 'pickup'
|
|
697
|
-
? 'La cueillette'
|
|
698
|
-
: expeditionMethod === 'delivery'
|
|
699
|
-
? 'La livraison'
|
|
700
|
-
: 'La commande'} de gazon est disponible à partir de 10${localeSellUnit} (1 ${localeStepUnit}), mais le minimum facturable est de ${minBillableStr}.`,
|
|
701
|
-
en: `Sod ${type === 'install'
|
|
702
|
-
? 'installation'
|
|
703
|
-
: expeditionMethod === 'pickup'
|
|
704
|
-
? 'pick-up'
|
|
705
|
-
: expeditionMethod === 'delivery'
|
|
706
|
-
? 'delivery'
|
|
707
|
-
: 'ordering'} is available starting at 10${localeSellUnit} (1 ${localeStepUnit}), but the minimum billable is ${minBillableStr}.`
|
|
708
|
-
}, locale);
|
|
709
|
-
if (!!!shortVersion) {
|
|
710
|
-
str += endStr;
|
|
711
|
-
}
|
|
712
|
-
return str;
|
|
713
|
-
};
|
|
714
|
-
exports.getMinQtyFeeText = getMinQtyFeeText;
|
|
715
|
-
const getMinQtyFeeAmountText = (parent_slug = '', locale = 'fr', servicesFees, showMinFeeAmount = true) => {
|
|
716
|
-
const serviceOrFee = servicesFees.find((i) => i.parent_slug === parent_slug);
|
|
717
|
-
if (!!!serviceOrFee)
|
|
718
|
-
return '';
|
|
719
|
-
const amount = (0, toNumber_1.default)(serviceOrFee.regular_price.amount) * serviceOrFee.qte;
|
|
720
|
-
return (0, locale_1.translateILang)({
|
|
721
|
-
fr: `Une différence de ${!!showMinFeeAmount ? amount.toFixed(2) + '$' : '%LOADER%'}%BOLD% vous sera chargée si la quantité de gazon au panier est plus petite que le minimum requis.`,
|
|
722
|
-
en: `A difference of ${!!showMinFeeAmount ? amount.toFixed(2) + '$' : '%LOADER%'}%BOLD% will be charged if the quantity of sod in the cart is less than the minimum required.`
|
|
723
|
-
}, locale);
|
|
724
|
-
};
|
|
725
|
-
exports.getMinQtyFeeAmountText = getMinQtyFeeAmountText;
|
|
726
|
-
const getGrassQteText = (chosenDeclination, locale = 'fr') => {
|
|
727
|
-
let txt = '';
|
|
728
|
-
let nbRolls = 0;
|
|
729
|
-
let nbSquareFeet = 0;
|
|
730
|
-
const units = !!!chosenDeclination ? [] : chosenDeclination.other_units;
|
|
731
|
-
if (!!units && !!units.length) {
|
|
732
|
-
const itemRolls = units.find((measure) => measure.unit_slug === 'roul');
|
|
733
|
-
const itemSquareFeet = units.find((measure) => measure.unit_slug === 'pal');
|
|
734
|
-
if (!!itemSquareFeet && !!itemSquareFeet.fitting_unit) {
|
|
735
|
-
nbSquareFeet = itemSquareFeet.fitting_unit;
|
|
736
|
-
}
|
|
737
|
-
if (!!itemRolls && !!itemRolls.fitting_unit && nbSquareFeet !== 0) {
|
|
738
|
-
nbRolls = nbSquareFeet / itemRolls.fitting_unit;
|
|
739
|
-
}
|
|
740
|
-
}
|
|
741
|
-
txt = (0, locale_1.translateILang)({
|
|
742
|
-
fr: 'Pour ce produit, vous devez commander par pieds carrés. Une palette = *nbRolls* rouleaux (*nbSquareFeet*pi2)',
|
|
743
|
-
en: 'For this product, you have to order by square feet. A pallet = *nbRolls* rolls (*nbSquareFeet*pi2)'
|
|
744
|
-
}, locale);
|
|
745
|
-
txt = txt.replace('*nbRolls*', String(nbRolls));
|
|
746
|
-
txt = txt.replace('*nbSquareFeet*', String(nbSquareFeet));
|
|
747
|
-
return txt;
|
|
748
|
-
};
|
|
749
|
-
exports.getGrassQteText = getGrassQteText;
|
|
750
|
-
const getGrassServicesFees = async (grassProduct, isPro, useFees, expeditionMethod, fetchProduct, getIfAddressIsInsideZones, getDistanceFromAddress, locale, allStores, chosenGrass, baseGrass, customPriceList) => {
|
|
751
|
-
const installItems = await (0, exports.getInstallationArray)(grassProduct.qte, (!!baseGrass ? baseGrass : chosenGrass).product_upsells, fetchProduct, locale, isPro, chosenGrass.sku, customPriceList, { engrais: true, roulage: true });
|
|
752
|
-
const cart = Object.assign(Object.assign({}, (0, Cart_1.getDefaultCart)()), { items: [
|
|
753
|
-
chosenGrass,
|
|
754
|
-
...(!!baseGrass ? [baseGrass] : []),
|
|
755
|
-
...installItems.filter((item) => !!!(0, exports.isMinQtyFee)(item.parent_slug || ''))
|
|
756
|
-
] });
|
|
757
|
-
const applied = await (0, exports.fetchFeesBeforeCart)(!!useFees, cart, expeditionMethod, fetchProduct, getIfAddressIsInsideZones, getDistanceFromAddress, locale, allStores, isPro, grassProduct, undefined, { useStoreAddress: 'sainte-julie' }, customPriceList);
|
|
758
|
-
return [...installItems, ...applied.itemsToAdd];
|
|
759
|
-
};
|
|
760
|
-
exports.getGrassServicesFees = getGrassServicesFees;
|
|
761
|
-
const getGrassSubQuestionsByType = (type) => {
|
|
762
|
-
if (type === 'pro') {
|
|
763
|
-
return products_2.otherGrassSubQuestions.filter((sub) => !!sub.proOnly);
|
|
764
|
-
}
|
|
765
|
-
return products_2.otherGrassSubQuestions.filter((sub) => 'installation-gazon' === sub.associatedProductSlug || (!!sub.installOnly && !!!sub.proOnly));
|
|
766
|
-
};
|
|
767
|
-
exports.getGrassSubQuestionsByType = getGrassSubQuestionsByType;
|
|
768
|
-
/**
|
|
769
|
-
* @description For grass products. Over 1480pi2, if installation, quantities are rounded to rolls (10pi2) if pickup, and to half pal. if shipping
|
|
770
|
-
* @param grassProduct
|
|
771
|
-
* @param cartData
|
|
772
|
-
* @returns quantity rounded to rolls with items to change or undefined
|
|
773
|
-
*/
|
|
774
|
-
const handleGrassProductQtyRoundForShipping = (cartData, grassProduct) => {
|
|
775
|
-
if (!!!cartData || !!!grassProduct)
|
|
776
|
-
return;
|
|
777
|
-
const product = cartData.items.find((item) => item.sku === grassProduct.sku);
|
|
778
|
-
if (!!!product)
|
|
779
|
-
return;
|
|
780
|
-
const productOtherUnits = product.other_units;
|
|
781
|
-
if (!!!productOtherUnits)
|
|
782
|
-
return;
|
|
783
|
-
// get new rounded qte
|
|
784
|
-
const palUnit = productOtherUnits.find((u) => u.unit_slug === 'pal');
|
|
785
|
-
const rounded = (0, exports.roundGrassQte)(product.qte, !!!cartData.is_pickup, palUnit);
|
|
786
|
-
if (!!!rounded || rounded === grassProduct.qte)
|
|
787
|
-
return;
|
|
788
|
-
// ajust items with new quantity
|
|
789
|
-
let itemsToChange = [];
|
|
790
|
-
const recursiveGrassItem = (0, cart_1.getRecursiveItems)(cartData.items).find((item) => item.sku === grassProduct.sku);
|
|
791
|
-
const getItemsToChange = (item) => {
|
|
792
|
-
if (!!item.sub_items) {
|
|
793
|
-
item.sub_items.forEach((subItem) => getItemsToChange(subItem));
|
|
794
|
-
}
|
|
795
|
-
if (item.parent_slug === 'frais-de-mobilisation') {
|
|
796
|
-
const totalPallet = (0, expedition_1.getPalletQty)(cartData.items.map((i) => {
|
|
797
|
-
if ((0, exports.checkIfProductIsOfType)(i, 'gazon')) {
|
|
798
|
-
return Object.assign(Object.assign({}, i), { qte: rounded });
|
|
799
|
-
}
|
|
800
|
-
return i;
|
|
801
|
-
}), 'grass');
|
|
802
|
-
itemsToChange.push({
|
|
803
|
-
sku: item.sku,
|
|
804
|
-
qte: (0, ceil_1.default)(totalPallet / expedition_1.installationFeePalletTier)
|
|
805
|
-
});
|
|
806
|
-
return;
|
|
807
|
-
}
|
|
808
|
-
if (!!item.is_upsell_of_sku) {
|
|
809
|
-
const parentUpsellProd = cartData.items.find((i) => i.sku === item.is_upsell_of_sku);
|
|
810
|
-
if (!!parentUpsellProd) {
|
|
811
|
-
const sameUpsell = (parentUpsellProd.product_upsells || []).find((up) => up.recommendation_sku === item.sku);
|
|
812
|
-
if (!!sameUpsell) {
|
|
813
|
-
const anUpsellProduct = Object.assign(Object.assign(Object.assign(Object.assign({}, item), { parent_slug: sameUpsell.recommendation_parent_slug, recommended_qte: sameUpsell.recommendation_qty, recommended_sku: sameUpsell.recommendation_sku, matching_qte: !!sameUpsell.matching_qty, auto_add: sameUpsell.auto_add, auto_add_exceptions: sameUpsell.auto_add_exceptions, actual_qte: sameUpsell.actual_qty }), (!!sameUpsell.is_recommendation ? { is_recommendation: true } : {})), (!!sameUpsell.show_recommendation_msg ? { show_recommendation_msg: true } : {}));
|
|
814
|
-
const ratio = (0, upsells_1.calculateUpsellQte)(anUpsellProduct, rounded);
|
|
815
|
-
if (!!ratio) {
|
|
816
|
-
itemsToChange.push({
|
|
817
|
-
sku: item.sku,
|
|
818
|
-
qte: ratio
|
|
819
|
-
});
|
|
820
|
-
return;
|
|
821
|
-
}
|
|
822
|
-
}
|
|
823
|
-
}
|
|
824
|
-
}
|
|
825
|
-
itemsToChange.push({
|
|
826
|
-
sku: item.sku,
|
|
827
|
-
qte: rounded
|
|
828
|
-
});
|
|
829
|
-
return;
|
|
830
|
-
};
|
|
831
|
-
if (!!recursiveGrassItem) {
|
|
832
|
-
getItemsToChange(recursiveGrassItem);
|
|
833
|
-
}
|
|
834
|
-
return { rounded, itemsToChange };
|
|
835
|
-
};
|
|
836
|
-
exports.handleGrassProductQtyRoundForShipping = handleGrassProductQtyRoundForShipping;
|
|
837
|
-
/**
|
|
838
|
-
* Function roundGrassQte
|
|
839
|
-
* @description Returns rounded grass quantity depending on current qty, if customer selected installation and pallet unit (if defined)
|
|
840
|
-
* @param currentQte {number} - Current quantity as entered by user in input
|
|
841
|
-
* @param isShipping {boolean} - Whether customer has selected installation option
|
|
842
|
-
* @param palUnit {IFilledDimensionUnits | undefined} - Pallet FilledDimensionUnit (possibly undefined)
|
|
843
|
-
*/
|
|
844
|
-
const roundGrassQte = (currentQte, isShipping, palUnit) => {
|
|
845
|
-
let newQte = currentQte;
|
|
846
|
-
switch (true) {
|
|
847
|
-
case currentQte < 1480:
|
|
848
|
-
const rest1480 = currentQte % 10;
|
|
849
|
-
if (rest1480 !== 0) {
|
|
850
|
-
newQte = currentQte - rest1480 + 10;
|
|
851
|
-
}
|
|
852
|
-
break;
|
|
853
|
-
case currentQte >= 1480 && !!!isShipping:
|
|
854
|
-
const rest1480Install = currentQte % 10;
|
|
855
|
-
if (rest1480Install !== 0) {
|
|
856
|
-
newQte = currentQte - rest1480Install + 10;
|
|
857
|
-
}
|
|
858
|
-
break;
|
|
859
|
-
case currentQte >= 1480:
|
|
860
|
-
if (!!palUnit && !!palUnit.fitting_unit) {
|
|
861
|
-
let rest1480 = currentQte % palUnit.fitting_unit;
|
|
862
|
-
if (rest1480 !== 0 && !!((rest1480 - 400) % palUnit.fitting_unit)) {
|
|
863
|
-
newQte = currentQte - rest1480;
|
|
864
|
-
if (newQte + 400 > currentQte) {
|
|
865
|
-
newQte = newQte + 400;
|
|
866
|
-
}
|
|
867
|
-
else if (newQte + palUnit.fitting_unit > currentQte) {
|
|
868
|
-
newQte = newQte + palUnit.fitting_unit;
|
|
869
|
-
}
|
|
870
|
-
}
|
|
871
|
-
}
|
|
872
|
-
break;
|
|
873
|
-
}
|
|
874
|
-
return newQte;
|
|
875
|
-
};
|
|
876
|
-
exports.roundGrassQte = roundGrassQte;
|
|
877
|
-
/**
|
|
878
|
-
* Detects if customer has "Installation tout inclus".
|
|
879
|
-
* @param customPriceList - Customer custom price list
|
|
880
|
-
* @return All inclusive installation if exists, undefined otherwise
|
|
881
|
-
*/
|
|
882
|
-
const getInstallationAllInclusiveFromPriceList = (customPriceList) => {
|
|
883
|
-
if (!!!customPriceList || !!!customPriceList.length)
|
|
884
|
-
return;
|
|
885
|
-
const item = customPriceList.find((i) => i.sku === products_2.installationAllInclusiveSku);
|
|
886
|
-
const active = !!item && !!item.price;
|
|
887
|
-
if (!active)
|
|
888
|
-
return;
|
|
889
|
-
return item;
|
|
890
|
-
};
|
|
891
|
-
exports.getInstallationAllInclusiveFromPriceList = getInstallationAllInclusiveFromPriceList;
|
|
892
|
-
/**
|
|
893
|
-
* Checks if all-inclusive installation is active.
|
|
894
|
-
* @param hasInstallation - Whether the cart/form contains an installation
|
|
895
|
-
* @param isPro - Whether the customer is a pro
|
|
896
|
-
* @param customPriceList - Customer custom price list
|
|
897
|
-
* @returns true if all-inclusive installation is active
|
|
898
|
-
*/
|
|
899
|
-
const isInstallAllInclusiveActive = (hasInstallation, isPro, customPriceList) => {
|
|
900
|
-
return !!hasInstallation && !!isPro && !!(0, exports.getInstallationAllInclusiveFromPriceList)(customPriceList);
|
|
901
|
-
};
|
|
902
|
-
exports.isInstallAllInclusiveActive = isInstallAllInclusiveActive;
|
|
903
|
-
/**
|
|
904
|
-
* Force )$ to kentucky base grass and sod delivery fee if install all-inclusive.
|
|
905
|
-
* @param item - The cart item to potentially override
|
|
906
|
-
* @returns The item with zeroed price if applicable, or the original item
|
|
907
|
-
*/
|
|
908
|
-
const applyAllInclusiveOverrides = (item) => {
|
|
909
|
-
const isKentucky = item.parent_slug === 'kentucky' || item.sku === products_2.kentucky;
|
|
910
|
-
const isSodDelivery = item.parent_slug === 'livraison-gazon' && products_2.sodDeliverySkus.includes(item.sku);
|
|
911
|
-
if (isKentucky || isSodDelivery) {
|
|
912
|
-
return Object.assign(Object.assign({}, item), { regular_price: Object.assign(Object.assign({}, item.regular_price), { amount: 0 }), discount_price: null, promo_price: null, price_override: true });
|
|
913
|
-
}
|
|
914
|
-
return item;
|
|
915
|
-
};
|
|
916
|
-
exports.applyAllInclusiveOverrides = applyAllInclusiveOverrides;
|
|
917
|
-
// Determines if a cart item should be hidden from checkout display. Used for all-inclusive installation
|
|
918
|
-
const shouldHideItemInCheckout = (item, allItems) => {
|
|
919
|
-
const hasAllInclusive = allItems.some((i) => i.sku === products_2.installationAllInclusiveSku);
|
|
920
|
-
if (!hasAllInclusive)
|
|
921
|
-
return false;
|
|
922
|
-
if (item.regular_price.amount !== 0)
|
|
923
|
-
return false;
|
|
924
|
-
// Hide installation upsells at $0 (mobilisation, fertilisation, roulage, etc.)
|
|
925
|
-
const installationSkus = allItems.filter((i) => i.parent_slug === 'installation-gazon').map((i) => i.sku);
|
|
926
|
-
if (!!item.is_upsell_of_sku && installationSkus.includes(item.is_upsell_of_sku))
|
|
927
|
-
return true;
|
|
928
|
-
// Hide sod delivery at $0
|
|
929
|
-
if (item.parent_slug === 'livraison-gazon')
|
|
930
|
-
return true;
|
|
931
|
-
// Hide installation surcharges at $0 (e.g. surcharge mobilisation île de Montréal)
|
|
932
|
-
if (item.parent_slug === 'surcharges-installation-gazon')
|
|
933
|
-
return true;
|
|
934
|
-
return false;
|
|
935
|
-
};
|
|
936
|
-
exports.shouldHideItemInCheckout = shouldHideItemInCheckout;
|
|
937
|
-
// Check si la surcharge carburant match l'item
|
|
938
|
-
const matchesFuelSurchargeParent = (surchargeSku, item) => {
|
|
939
|
-
switch (surchargeSku) {
|
|
940
|
-
case products_2.fuelSurchargeGazonSku:
|
|
941
|
-
return item.sku === products_2.kentucky || item.parent_slug === 'kentucky';
|
|
942
|
-
case products_2.fuelSurchargeLivraisonSku:
|
|
943
|
-
return (!!item.parent_slug &&
|
|
944
|
-
['livraison-gazon', 'livraison-beton-accessoires'].includes(item.parent_slug));
|
|
945
|
-
case products_2.fuelSurchargeMobilisationSku:
|
|
946
|
-
return item.parent_slug === 'frais-de-mobilisation';
|
|
947
|
-
default:
|
|
948
|
-
return false;
|
|
949
|
-
}
|
|
950
|
-
};
|
|
951
|
-
exports.matchesFuelSurchargeParent = matchesFuelSurchargeParent;
|
|
952
|
-
const getInstallationArray = async (qte, baseGrassUpsells, fetchProduct, locale, isPro, chosenSku, customPriceList, returnOtherFees) => {
|
|
953
|
-
var _a;
|
|
954
|
-
const upsell = baseGrassUpsells;
|
|
955
|
-
if (!!!upsell)
|
|
956
|
-
return [];
|
|
957
|
-
const installation_upsell = upsell.filter((upsell) => upsell.recommendation_parent_slug === 'installation-gazon');
|
|
958
|
-
const installation_parent = await fetchProduct('installation-gazon', locale, true, true);
|
|
959
|
-
let installation_decli;
|
|
960
|
-
const minQteInstall = (0, expedition_1.getMinQteInstall)(isPro);
|
|
961
|
-
// Variable pour vérifier si une déclinaison d'installation existe déjà dans le cart
|
|
962
|
-
// ** Utile pour la modification des items du cart, vu que la props is_upsell_of_sku ne peut pas se modifier on update
|
|
963
|
-
let arrayFinal = [];
|
|
964
|
-
if (!!installation_parent && !!installation_upsell && !!installation_upsell.length) {
|
|
965
|
-
let installation_array = [];
|
|
966
|
-
if (!!isPro) {
|
|
967
|
-
installation_array = installation_parent.declinations.filter((decli) => !!decli.attributes &&
|
|
968
|
-
!!decli.attributes[data_1.AttributesIdEnumGR.CLIENT_TYPE] &&
|
|
969
|
-
!!decli.attributes[data_1.AttributesIdEnumGR.CLIENT_TYPE].includes('pro'));
|
|
970
|
-
}
|
|
971
|
-
else {
|
|
972
|
-
installation_array = installation_parent.declinations.filter((decli) => !!decli.attributes &&
|
|
973
|
-
!!decli.attributes[data_1.AttributesIdEnumGR.CLIENT_TYPE] &&
|
|
974
|
-
!!decli.attributes[data_1.AttributesIdEnumGR.CLIENT_TYPE].includes('au-detail'));
|
|
975
|
-
}
|
|
976
|
-
const installation_qte_array = installation_upsell.filter((upsell) => installation_array.find((decli) => decli.sku === upsell.recommendation_sku));
|
|
977
|
-
const closestQte = (0, maxBy_1.default)(installation_qte_array.filter((upsell) => {
|
|
978
|
-
return upsell.actual_qty <= qte;
|
|
979
|
-
}), 'actual_qty');
|
|
980
|
-
// MODIFS. FRAIS 2024 - On n'ajoute pas les frais au panier si leur prix régulier est de 0.00$
|
|
981
|
-
// Vérification faite à chaque ajout de déclinaison au arrayFinal
|
|
982
|
-
if (!!closestQte) {
|
|
983
|
-
installation_decli = installation_parent.declinations.find((decli) => decli.sku === closestQte.recommendation_sku);
|
|
984
|
-
// Check if customer has installation all-inclusive
|
|
985
|
-
const allInclusivePriceItem = !!isPro && !!customPriceList ? (0, exports.getInstallationAllInclusiveFromPriceList)(customPriceList) : undefined;
|
|
986
|
-
if (!!installation_decli) {
|
|
987
|
-
const allInclusiveDecli = !!allInclusivePriceItem && !!installation_parent
|
|
988
|
-
? installation_parent.declinations.find((d) => d.sku === allInclusivePriceItem.sku)
|
|
989
|
-
: undefined;
|
|
990
|
-
if (!!allInclusivePriceItem && !!allInclusiveDecli) {
|
|
991
|
-
const priceAmount = (_a = allInclusivePriceItem.price) !== null && _a !== void 0 ? _a : allInclusivePriceItem.reg;
|
|
992
|
-
installation_decli = Object.assign(Object.assign({}, allInclusiveDecli), { regular_price: Object.assign(Object.assign({}, allInclusiveDecli.regular_price), { amount: priceAmount }) });
|
|
993
|
-
}
|
|
994
|
-
else {
|
|
995
|
-
if (!!isPro && !!customPriceList) {
|
|
996
|
-
installation_decli = (0, g2_1.checkForCustomPriceEquivalent)(installation_decli, customPriceList);
|
|
997
|
-
}
|
|
998
|
-
}
|
|
999
|
-
// Add the correct installation option depending on whether the customer has "Installation tout inclus"
|
|
1000
|
-
if (!(0, exports.shouldHideItemIfRegPriceIs0)(installation_decli, installation_parent.slug)) {
|
|
1001
|
-
arrayFinal.push(Object.assign(Object.assign({}, installation_decli), { parent_slug: 'installation-gazon', qte: qte, is_upsell_of_sku: chosenSku, product_upsells: installation_parent.product_upsells }));
|
|
1002
|
-
}
|
|
1003
|
-
}
|
|
1004
|
-
// Frais minimum d'installation
|
|
1005
|
-
if (qte < minQteInstall) {
|
|
1006
|
-
const minimum_installation_fee = await fetchProduct('frais-minimum-gazon-pour-installation', locale, true, true);
|
|
1007
|
-
if (!!minimum_installation_fee) {
|
|
1008
|
-
let minInstallDecli = minimum_installation_fee.declinations[0];
|
|
1009
|
-
minInstallDecli = Object.assign(Object.assign({}, minInstallDecli), { regular_price: Object.assign(Object.assign({}, minInstallDecli.regular_price), { amount: installation_decli.regular_price.amount }) });
|
|
1010
|
-
if (!!isPro && !!customPriceList) {
|
|
1011
|
-
minInstallDecli = (0, g2_1.checkForCustomPriceEquivalent)(Object.assign(Object.assign({}, minInstallDecli), { price_override: true }), customPriceList);
|
|
1012
|
-
}
|
|
1013
|
-
if (!(0, exports.shouldHideItemIfRegPriceIs0)(minInstallDecli, minimum_installation_fee.slug)) {
|
|
1014
|
-
arrayFinal.push(Object.assign(Object.assign({}, minInstallDecli), { parent_slug: 'frais-minimum-gazon-pour-installation', qte: minQteInstall - qte, is_upsell_of_sku: installation_decli.sku, price_override: true }));
|
|
1015
|
-
}
|
|
1016
|
-
}
|
|
1017
|
-
}
|
|
1018
|
-
// Frais de mobilisation (pour l'installation)
|
|
1019
|
-
const mobilisation_fee = await fetchProduct('frais-de-mobilisation', locale, true, true);
|
|
1020
|
-
if (!!mobilisation_fee && !!isPro) {
|
|
1021
|
-
let mobilisationDecli = mobilisation_fee.declinations[0];
|
|
1022
|
-
if (!!customPriceList) {
|
|
1023
|
-
mobilisationDecli = (0, g2_1.checkForCustomPriceEquivalent)(mobilisationDecli, customPriceList);
|
|
1024
|
-
}
|
|
1025
|
-
if (!(0, exports.shouldHideItemIfRegPriceIs0)(mobilisationDecli, mobilisation_fee.slug, true)) {
|
|
1026
|
-
arrayFinal.push(Object.assign(Object.assign({}, mobilisationDecli), { parent_slug: 'frais-de-mobilisation', qte: (0, ceil_1.default)(qte > minQteInstall
|
|
1027
|
-
? qte / (740 * expedition_1.installationFeePalletTier)
|
|
1028
|
-
: minQteInstall / (740 * expedition_1.installationFeePalletTier)), is_upsell_of_sku: installation_decli.sku, product_upsells: mobilisation_fee.product_upsells }));
|
|
1029
|
-
}
|
|
1030
|
-
}
|
|
1031
|
-
// -----------------------------------------------------------------------
|
|
1032
|
-
// AUTRES FRAIS CONNEXES
|
|
1033
|
-
if (!!returnOtherFees) {
|
|
1034
|
-
if (!!returnOtherFees.engrais) {
|
|
1035
|
-
// fertilisation
|
|
1036
|
-
const fertilisation = await fetchProduct('installation-fertilisation', locale, true, true);
|
|
1037
|
-
if (!!fertilisation) {
|
|
1038
|
-
let minFertilisationDecli = fertilisation.declinations[0];
|
|
1039
|
-
if (!!isPro && !!customPriceList) {
|
|
1040
|
-
minFertilisationDecli = (0, g2_1.checkForCustomPriceEquivalent)(minFertilisationDecli, customPriceList);
|
|
1041
|
-
}
|
|
1042
|
-
if (!(0, exports.shouldHideItemIfRegPriceIs0)(minFertilisationDecli, fertilisation.slug, true)) {
|
|
1043
|
-
arrayFinal.push(Object.assign(Object.assign({}, minFertilisationDecli), { parent_slug: fertilisation.slug, qte: qte < minQteInstall ? minQteInstall : qte, is_upsell_of_sku: installation_decli.sku, product_upsells: fertilisation.product_upsells }));
|
|
1044
|
-
}
|
|
1045
|
-
}
|
|
1046
|
-
}
|
|
1047
|
-
if (returnOtherFees.roulage) {
|
|
1048
|
-
// roullage
|
|
1049
|
-
const roullage = await fetchProduct('installation-roulage', locale, true, true);
|
|
1050
|
-
if (!!roullage) {
|
|
1051
|
-
let minRoulageDecli = roullage.declinations[0];
|
|
1052
|
-
if (!!isPro && !!customPriceList) {
|
|
1053
|
-
minRoulageDecli = (0, g2_1.checkForCustomPriceEquivalent)(minRoulageDecli, customPriceList);
|
|
1054
|
-
}
|
|
1055
|
-
if (!(0, exports.shouldHideItemIfRegPriceIs0)(minRoulageDecli, roullage.slug, true)) {
|
|
1056
|
-
arrayFinal.push(Object.assign(Object.assign({}, minRoulageDecli), { parent_slug: roullage.slug, qte: qte < minQteInstall ? minQteInstall : qte, is_upsell_of_sku: installation_decli.sku, product_upsells: roullage.product_upsells }));
|
|
1057
|
-
}
|
|
1058
|
-
}
|
|
1059
|
-
}
|
|
1060
|
-
}
|
|
1061
|
-
}
|
|
1062
|
-
}
|
|
1063
|
-
return arrayFinal;
|
|
1064
|
-
};
|
|
1065
|
-
exports.getInstallationArray = getInstallationArray;
|
|
1066
|
-
const getInstallItemPrice = (parentSlug, servicesFees) => {
|
|
1067
|
-
let price = 0;
|
|
1068
|
-
switch (parentSlug) {
|
|
1069
|
-
case 'installation-gazon':
|
|
1070
|
-
const itemsToUse = servicesFees.filter((i) => i.parent_slug && ['installation-gazon', 'frais-de-mobilisation'].includes(i.parent_slug));
|
|
1071
|
-
if (!!itemsToUse) {
|
|
1072
|
-
price = (0, sumBy_1.default)(itemsToUse, (item) => (0, products_1.getLowestPrice)(item).price.amount * item.qte);
|
|
1073
|
-
}
|
|
1074
|
-
break;
|
|
1075
|
-
default:
|
|
1076
|
-
const itemToUse = servicesFees.find((i) => i.parent_slug === parentSlug);
|
|
1077
|
-
if (!!itemToUse) {
|
|
1078
|
-
price = (0, products_1.getLowestPrice)(itemToUse).price.amount * itemToUse.qte;
|
|
1079
|
-
}
|
|
1080
|
-
break;
|
|
1081
|
-
}
|
|
1082
|
-
return price;
|
|
1083
|
-
};
|
|
1084
|
-
exports.getInstallItemPrice = getInstallItemPrice;
|
|
1085
|
-
// #endregion
|
|
1086
|
-
// ----------------------------------------------------------------------------------------------------------
|
|
1087
|
-
// ----------------------------------------------------------------------------------------------------------
|
|
1088
|
-
// #region CONCRETE
|
|
1089
|
-
const getConcreteQteText = (declination, locale = 'fr') => {
|
|
1090
|
-
let txt = '';
|
|
1091
|
-
if (!!!declination)
|
|
1092
|
-
return txt;
|
|
1093
|
-
let nbSaleUnitsPerCmdStep = 0;
|
|
1094
|
-
let nbUnitsPerPal = 0;
|
|
1095
|
-
const other_units = declination.other_units;
|
|
1096
|
-
if (!!!other_units || !!!other_units.length) {
|
|
1097
|
-
return '';
|
|
1098
|
-
}
|
|
1099
|
-
else {
|
|
1100
|
-
const commandStep = other_units.find((unit) => unit.is_command_step);
|
|
1101
|
-
const commandUnit = other_units.find((unit) => unit.is_command_unit);
|
|
1102
|
-
const saleUnit = other_units.find((unit) => unit.is_sale_unit);
|
|
1103
|
-
const unitsPerPal = other_units.find((unit) => unit.unit_slug === 'pal');
|
|
1104
|
-
if (!!commandStep &&
|
|
1105
|
-
!!commandStep.fitting_unit &&
|
|
1106
|
-
!!commandUnit &&
|
|
1107
|
-
!!commandUnit.fitting_unit &&
|
|
1108
|
-
!!saleUnit &&
|
|
1109
|
-
!!saleUnit.fitting_unit &&
|
|
1110
|
-
!!unitsPerPal &&
|
|
1111
|
-
!!unitsPerPal.fitting_unit) {
|
|
1112
|
-
const cmdSameAsSale = commandStep.unit_slug === saleUnit.unit_slug;
|
|
1113
|
-
const nbP2PerRgSlug = !!cmdSameAsSale ? commandUnit.unit_slug : saleUnit.unit_slug;
|
|
1114
|
-
nbSaleUnitsPerCmdStep = !!cmdSameAsSale
|
|
1115
|
-
? commandStep.fitting_unit / commandUnit.fitting_unit
|
|
1116
|
-
: commandStep.fitting_unit / saleUnit.fitting_unit;
|
|
1117
|
-
// Round at correct decimals for products where commandStep.fitting_unit is 1 (meaning value calculated before is correct sell units per step)
|
|
1118
|
-
nbUnitsPerPal =
|
|
1119
|
-
commandStep.fitting_unit == 1 && !!!commandStep.is_sale_unit
|
|
1120
|
-
? unitsPerPal.fitting_unit *
|
|
1121
|
-
(0, round_1.default)(nbSaleUnitsPerCmdStep, (0, exports.productUnitSupportsDecimals)(saleUnit.unit_slug) ? 5 : 0)
|
|
1122
|
-
: unitsPerPal.fitting_unit / saleUnit.fitting_unit;
|
|
1123
|
-
txt = (0, locale_1.translateILang)({
|
|
1124
|
-
fr: 'Pour ce produit, vous devez commander par *cmdStep* (*nbUnitsPerCmdStep*).',
|
|
1125
|
-
en: 'For this product, you have to order by *cmdStep* (*nbUnitsPerCmdStep*).'
|
|
1126
|
-
}, locale);
|
|
1127
|
-
if (unitsPerPal.unit_slug != commandStep.unit_slug) {
|
|
1128
|
-
txt += (0, locale_1.translateILang)({
|
|
1129
|
-
fr: ' Une palette = *nbUnitsPerPal*.',
|
|
1130
|
-
en: ' A pallet = *nbUnitsPerPal*.'
|
|
1131
|
-
}, locale);
|
|
1132
|
-
}
|
|
1133
|
-
txt = txt.replace('*cmdStep*', String(`${(0, locale_1.translateILang)(inventories_1.unitDict[commandStep.unit_slug], locale).toLowerCase()}`));
|
|
1134
|
-
txt = txt.replace('*nbUnitsPerCmdStep*', String(`${(0, round_1.default)(nbSaleUnitsPerCmdStep, 2)} ${(0, locale_1.translateILang)(inventories_1.unitDict[nbP2PerRgSlug], locale).toLowerCase()}`));
|
|
1135
|
-
txt = txt.replace('*nbUnitsPerPal*', String(`${(0, round_1.default)(nbUnitsPerPal, 2)} ${(0, locale_1.translateILang)(inventories_1.unitDict[saleUnit.unit_slug], locale).toLowerCase()}`));
|
|
1136
|
-
}
|
|
1137
|
-
else {
|
|
1138
|
-
return '';
|
|
1139
|
-
}
|
|
1140
|
-
}
|
|
1141
|
-
return txt;
|
|
1142
|
-
};
|
|
1143
|
-
exports.getConcreteQteText = getConcreteQteText;
|
|
1144
|
-
/**
|
|
1145
|
-
* @description returns all items in cart where attribute AVAILABILITY contains wanted type.
|
|
1146
|
-
* @param cartData
|
|
1147
|
-
* @param availabilityType
|
|
1148
|
-
*/
|
|
1149
|
-
const getConcreteItemsByAvailability = (cartData, availabilityType, returnTrueIfUndefined) => {
|
|
1150
|
-
return cartData.items.filter((i) => {
|
|
1151
|
-
return ((i.attributes[data_1.AttributesIdEnumGR.AVAILABILITY] &&
|
|
1152
|
-
i.attributes[data_1.AttributesIdEnumGR.AVAILABILITY][0] === availabilityType) ||
|
|
1153
|
-
!!returnTrueIfUndefined);
|
|
1154
|
-
});
|
|
1155
|
-
};
|
|
1156
|
-
exports.getConcreteItemsByAvailability = getConcreteItemsByAvailability;
|
|
1157
|
-
// #endregion
|
|
1158
|
-
// ----------------------------------------------------------------------------------------------------------
|
|
1159
|
-
// ----------------------------------------------------------------------------------------------------------
|
|
1160
|
-
// #region VRAC
|
|
1161
|
-
/**
|
|
1162
|
-
* Function getVracType - constructs vrac helper object is cart contains vrac or vrac associated items.
|
|
1163
|
-
* @param stores
|
|
1164
|
-
* @param cartData
|
|
1165
|
-
* @param getInventoryItemCallback
|
|
1166
|
-
* @param inventoryItemArray
|
|
1167
|
-
* @returns IVracType object containing vrac_type enum value and vrac_store_ids where vrac items are available
|
|
1168
|
-
*/
|
|
1169
|
-
const getVracType = async (stores, cartData, getInventoryItemCallback, inventoyItemArray) => {
|
|
1170
|
-
const items = cartData.items;
|
|
1171
|
-
// If cart does not contain vrac or vrac-agacent accessories (.is_other_type==='vrac)), return
|
|
1172
|
-
if (!!!items ||
|
|
1173
|
-
!!!items.length ||
|
|
1174
|
-
(!!!(0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.VRAC, cartData) &&
|
|
1175
|
-
!!!cartData.items.find((item) => !!item.is_other_type && item.is_other_type === 'vrac')))
|
|
1176
|
-
return;
|
|
1177
|
-
let allStoreIds = stores.map((store) => store.id);
|
|
1178
|
-
let itemFormat = '';
|
|
1179
|
-
await Promise.all(items.map(async (item) => {
|
|
1180
|
-
const productInventory = !!!item.is_service
|
|
1181
|
-
? !!inventoyItemArray && !!inventoyItemArray.length
|
|
1182
|
-
? inventoyItemArray.find((i) => i.sku === item.sku)
|
|
1183
|
-
: await getInventoryItemCallback(item.sku)
|
|
1184
|
-
: undefined;
|
|
1185
|
-
if (!!!productInventory)
|
|
1186
|
-
return;
|
|
1187
|
-
allStoreIds = allStoreIds.filter((id) => {
|
|
1188
|
-
const sameStoreInProdInventory = productInventory.inventories.find((i) => i.store_id === id);
|
|
1189
|
-
if (!!!sameStoreInProdInventory)
|
|
1190
|
-
return true;
|
|
1191
|
-
return !!!sameStoreInProdInventory.unavailable_in_store;
|
|
1192
|
-
});
|
|
1193
|
-
if (!!!itemFormat && !!item.attributes && !!item.attributes[data_1.AttributesIdEnumGR.FORMATS]) {
|
|
1194
|
-
itemFormat = item.attributes[data_1.AttributesIdEnumGR.FORMATS][0];
|
|
1195
|
-
}
|
|
1196
|
-
}));
|
|
1197
|
-
const onlySteJulieNobel = allStoreIds.length === 1 && allStoreIds[0] === 'sainte-julie-nobel';
|
|
1198
|
-
if (!!itemFormat.includes('sac')) {
|
|
1199
|
-
return {
|
|
1200
|
-
vrac_type: !!onlySteJulieNobel ? products_3.VracTypeEnum.NOBEL_SAC : products_3.VracTypeEnum.AUTRE_SAC,
|
|
1201
|
-
vrac_store_ids: allStoreIds
|
|
1202
|
-
};
|
|
1203
|
-
}
|
|
1204
|
-
else {
|
|
1205
|
-
return {
|
|
1206
|
-
vrac_type: !!onlySteJulieNobel ? products_3.VracTypeEnum.NOBEL_TONNE : products_3.VracTypeEnum.AUTRE_TONNE,
|
|
1207
|
-
vrac_store_ids: allStoreIds
|
|
1208
|
-
};
|
|
1209
|
-
}
|
|
1210
|
-
};
|
|
1211
|
-
exports.getVracType = getVracType;
|
|
1212
|
-
// #endregion
|
|
1213
|
-
// ----------------------------------------------------------------------------------------------------------
|
|
1214
|
-
// ----------------------------------------------------------------------------------------------------------
|
|
1215
|
-
// #region FEES
|
|
1216
|
-
/**
|
|
1217
|
-
* Get all possible fees for a cart with basic info, to show approx. fee total before all data is saved in cart
|
|
1218
|
-
*
|
|
1219
|
-
* @param useFees If local fee array should be used, to save database calls
|
|
1220
|
-
* @param newCart Current cart data
|
|
1221
|
-
* @param deliveryType If fees should be checked for a pick-up or shipping order
|
|
1222
|
-
* @param fetchProduct Callback function for product fetch
|
|
1223
|
-
* @param getIfAddressIsInsideZones Callback function for zone check
|
|
1224
|
-
* @param getDistanceFromAddress Callback function to check distance with provided address
|
|
1225
|
-
* @param locale User's locale (fr or en)
|
|
1226
|
-
* @param allStores Full store array for space
|
|
1227
|
-
* @param isPro If customer associated with cart is a pro customer
|
|
1228
|
-
* @param grassProduct Constructed grass product from cart (with extra data for checks)
|
|
1229
|
-
* @param concreteOrder Constructed concrete products from cart (with extra data for checks)
|
|
1230
|
-
* @param settings.addOnePalletToPickup Optionnal - If additionnal pal. should be added for order
|
|
1231
|
-
* @param settings.saveToShippingPayload Optional - If data collected should be saved to cart's shipping_payload
|
|
1232
|
-
* @param settings.useStoreAddress Optionnal - Provided store ID for which the address should be used for check
|
|
1233
|
-
* @param settings.useDeliveryAddress Optionnal - If current carts shipping address should be used for check
|
|
1234
|
-
* @param settings.useAvailableVracStores Optionnal - Provided array of store IDs available for vrac order
|
|
1235
|
-
* @param customPriceList Optionnal - If pro customer with G2 custom price list and custom prices should be checked
|
|
1236
|
-
*/
|
|
1237
|
-
const fetchFeesBeforeCart = async (useFees, newCart, deliveryType, fetchProduct, getIfAddressIsInsideZones, getDistanceFromAddress, locale, allStores, isPro, grassProduct, concreteOrder, settings, customPriceList) => {
|
|
1238
|
-
const cartContainsVrac = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.VRAC, newCart);
|
|
1239
|
-
const cartContainsInstallation = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.INSTALLATION, newCart);
|
|
1240
|
-
const cartContainsSample = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.SAMPLE, newCart);
|
|
1241
|
-
const cartContainsAccessoriesOnly = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.ONLY_ACCESSORIES, newCart);
|
|
1242
|
-
const storeToUse = !!settings && !!settings.useStoreAddress ? allStores.find((s) => s.id == settings.useStoreAddress) : undefined;
|
|
1243
|
-
const storeAddressToUse = !!storeToUse ? storeToUse.address : undefined;
|
|
1244
|
-
return await (0, expedition_1.applyFeesToCart)(fetchProduct, getIfAddressIsInsideZones, getDistanceFromAddress, newCart, deliveryType, grassProduct, concreteOrder, deliveryType === 'pickup' ? false : cartContainsInstallation, cartContainsVrac, (0, object_1.recursiveCheckObject)(settings, 'useAvailableVracStores'), isPro, deliveryType === 'pickup' ? !!settings && !!settings.addOnePalletToPickup : false, cartContainsSample, !!settings ? !!settings.saveToShippingPayload : false, !!!settings
|
|
1245
|
-
? undefined
|
|
1246
|
-
: !!settings.useStoreAddress && !!storeAddressToUse
|
|
1247
|
-
? storeAddressToUse
|
|
1248
|
-
: !!settings.useDeliveryAddress && !!newCart.shipping_address
|
|
1249
|
-
? newCart.shipping_address.address
|
|
1250
|
-
: undefined, locale, undefined, false, cartContainsAccessoriesOnly, undefined, allStores, customPriceList, !!useFees);
|
|
1251
|
-
};
|
|
1252
|
-
exports.fetchFeesBeforeCart = fetchFeesBeforeCart;
|
|
1253
|
-
// #endregion
|
|
1254
|
-
// ----------------------------------------------------------------------------------------------------------
|
|
1255
|
-
// ----------------------------------------------------------------------------------------------------------
|
|
1256
|
-
// #region PRO SPECIFICITIES
|
|
1257
|
-
/**
|
|
1258
|
-
* Check if pro custom promo info should be shown for customer for a specific product.
|
|
1259
|
-
* @param userData
|
|
1260
|
-
* @param isPro
|
|
1261
|
-
* @param product
|
|
1262
|
-
* @param customMinPrice
|
|
1263
|
-
*/
|
|
1264
|
-
const shouldShowProCustomPromo = (userData, isPro, product, customMinPrice) => {
|
|
1265
|
-
if (!!!product || !!!isPro || !!!userData)
|
|
1266
|
-
return false;
|
|
1267
|
-
// If customMinPrice is defined (meaning customer has custom price list), and the price type is not REG or has type NET, always return true
|
|
1268
|
-
if (!!customMinPrice) {
|
|
1269
|
-
if (customMinPrice.type === G2_1.CustomPriceItemTypeEnum.REG && customMinPrice.code2 !== 'NET')
|
|
1270
|
-
return false;
|
|
1271
|
-
return true;
|
|
1272
|
-
}
|
|
1273
|
-
// Check customer group. If promo exists and should apply for customer group, return true
|
|
1274
|
-
const customerGroup = (0, object_1.recursiveCheckObject)(userData, 'userData.basic_info.customer_professionnal_info.external_customer_group');
|
|
1275
|
-
const customerType = !!customerGroup ? (0, g2_1.getG2CustomerTypeFromCode)(customerGroup) : undefined;
|
|
1276
|
-
const prodPriceClass = !!product.price_classes_range
|
|
1277
|
-
? product.price_classes_range.find((range) => !!customerType && range.external_slug ? range.external_slug === customerType : range.class === 'aspirant')
|
|
1278
|
-
: !!product.prices_list
|
|
1279
|
-
? product.prices_list.find((range) => !!customerType && range.external_slug ? range.external_slug === customerType : range.group_id === 'aspirant')
|
|
1280
|
-
: undefined;
|
|
1281
|
-
return !!prodPriceClass && !!prodPriceClass.custom_promo_applies;
|
|
1282
|
-
};
|
|
1283
|
-
exports.shouldShowProCustomPromo = shouldShowProCustomPromo;
|
|
1284
|
-
const applyProCustomPromo = (decli, userData) => {
|
|
1285
|
-
const customerCode = userData.basic_info.customer_professionnal_info &&
|
|
1286
|
-
userData.basic_info.customer_professionnal_info.external_customer_group;
|
|
1287
|
-
if (!!!customerCode)
|
|
1288
|
-
return {};
|
|
1289
|
-
const customerCustomPromo = (0, g2_1.getG2DiscountFromCode)(customerCode);
|
|
1290
|
-
if (!!!customerCustomPromo)
|
|
1291
|
-
return {};
|
|
1292
|
-
const regPrice = decli.regular_price.amount;
|
|
1293
|
-
const newDiscountAmount = (0, toNumber_1.default)(regPrice) * ((100 - customerCustomPromo) / 100);
|
|
1294
|
-
let newPromoObj = (0, IDiscountRule_1.getDefaultDiscountRule)('product');
|
|
1295
|
-
newPromoObj = Object.assign(Object.assign({}, newPromoObj), { appliesTo: Object.assign(Object.assign({}, newPromoObj.appliesTo), { label: IDiscountRule_1.AppliesToEnum.PRODUCT, value: decli.sku }), rules: [
|
|
1296
|
-
{
|
|
1297
|
-
field: IDiscountRule_1.RuleFieldEnum.CUSTOMER,
|
|
1298
|
-
condition: IDiscountRule_1.RuleConditionEnum.AND,
|
|
1299
|
-
ruleDetails: [
|
|
1300
|
-
{
|
|
1301
|
-
operator: '==',
|
|
1302
|
-
value: [userData.id],
|
|
1303
|
-
condition: IDiscountRule_1.RuleConditionEnum.AND
|
|
1304
|
-
}
|
|
1305
|
-
]
|
|
1306
|
-
}
|
|
1307
|
-
], result: {
|
|
1308
|
-
action: IDiscountRule_1.ResultActionEnum.PERCENT,
|
|
1309
|
-
action_value: customerCustomPromo
|
|
1310
|
-
} });
|
|
1311
|
-
return {
|
|
1312
|
-
discount_rules: [newPromoObj],
|
|
1313
|
-
promo_price: {
|
|
1314
|
-
currency: 'CAD',
|
|
1315
|
-
amount: (0, round_1.default)(newDiscountAmount, 3)
|
|
1316
|
-
}
|
|
1317
|
-
};
|
|
1318
|
-
};
|
|
1319
|
-
exports.applyProCustomPromo = applyProCustomPromo;
|
|
1320
|
-
// Indexed products - Custom prices if pro
|
|
1321
|
-
const getFormattedProdGR = (decli, productSlug, isPro) => {
|
|
1322
|
-
const { promo_price, discount_price, tier_pricing } = decli, rest = __rest(decli, ["promo_price", "discount_price", "tier_pricing"]);
|
|
1323
|
-
return !!isPro ? Object.assign(Object.assign({}, rest), (productSlug !== 'kentucky' ? { tier_pricing } : {})) : decli;
|
|
1324
|
-
};
|
|
1325
|
-
exports.getFormattedProdGR = getFormattedProdGR;
|
|
1326
|
-
/**
|
|
1327
|
-
* Checks if a 0.00$ reg_price item should be considered "hidden" or not.
|
|
1328
|
-
* @param item - The indexedDecli or cartItem to check
|
|
1329
|
-
* @param productSlug - The parent product's slug (in case it is not found in item)
|
|
1330
|
-
* @param isUpsellOfInstallProd - Optionnal. If item is upsell of install product (additionnal fee for installation)
|
|
1331
|
-
*/
|
|
1332
|
-
const shouldHideItemIfRegPriceIs0 = (item, productSlug, isUpsellOfInstallProd) => {
|
|
1333
|
-
// A. Check if reg price is 0. If not, should not hide item
|
|
1334
|
-
const regPriceIs0 = item.regular_price.amount == 0;
|
|
1335
|
-
if (!regPriceIs0)
|
|
1336
|
-
return false;
|
|
1337
|
-
// B. Check if item is fee or service. If not, should not hide item
|
|
1338
|
-
if (!item.is_service)
|
|
1339
|
-
return false;
|
|
1340
|
-
// C. Check if item is an upsell of an installation product (additionnal install fees). If so, should not hide item
|
|
1341
|
-
if (!!isUpsellOfInstallProd)
|
|
1342
|
-
return false;
|
|
1343
|
-
// D. Check if item is a shipping fee. If so, should not hide item
|
|
1344
|
-
if (expedition_1.slugsToCheckFromExpeditionFees.shipping.includes(productSlug))
|
|
1345
|
-
return false;
|
|
1346
|
-
return true;
|
|
1347
|
-
};
|
|
1348
|
-
exports.shouldHideItemIfRegPriceIs0 = shouldHideItemIfRegPriceIs0;
|
|
1349
|
-
// #endregion
|
|
1350
|
-
// ----------------------------------------------------------------------------------------------------------
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
14
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.shouldHideItemIfRegPriceIs0 = exports.getFormattedProdGR = exports.applyProCustomPromo = exports.shouldShowProCustomPromo = exports.fetchFeesBeforeCart = exports.getVracType = exports.getConcreteItemsByAvailability = exports.getConcreteQteText = exports.getInstallItemPrice = exports.getInstallationArray = exports.matchesFuelSurchargeParent = exports.shouldHideItemInCheckout = exports.applyAllInclusiveOverrides = exports.isInstallAllInclusiveActive = exports.getInstallationAllInclusiveFromPriceList = exports.roundGrassQte = exports.handleGrassProductQtyRoundForShipping = exports.getGrassSubQuestionsByType = exports.getGrassServicesFees = exports.getGrassQteText = exports.getMinQtyFeeAmountText = exports.getMinQtyFeeText = exports.getAllMinGrassQuantities = exports.isMinQtyFee = exports.fuseGrassProducts = exports.getAllInstallFromItems = exports.checkIfProductIsInstallation = exports.checkIfIsNonSpecialityGrass = exports.checkIfProductIsOfType = exports.getProductFormOptions = exports.getParentProductCategoryGroup = exports.getProdName = exports.splitOnDashes = exports.getRoundedUnitProductQuantities = exports.getRoundedSellUnitProductQuantities = exports.getDescriptionString = exports.getDescriptionLength = exports.getProductAttributes = exports.productUnitSupportsDecimals = exports.getCorrectPluralSellUnit = exports.getPluralUnitLabelWithSlug = exports.getUnitLabelWithSlug = exports.getProductUnitLabel = exports.getProductSellUnitLabel = void 0;
|
|
18
|
+
const ceil_1 = __importDefault(require("lodash/ceil"));
|
|
19
|
+
const maxBy_1 = __importDefault(require("lodash/maxBy"));
|
|
20
|
+
const orderBy_1 = __importDefault(require("lodash/orderBy"));
|
|
21
|
+
const toNumber_1 = __importDefault(require("lodash/toNumber"));
|
|
22
|
+
const round_1 = __importDefault(require("lodash/round"));
|
|
23
|
+
const flatten_1 = __importDefault(require("lodash/flatten"));
|
|
24
|
+
const uniqBy_1 = __importDefault(require("lodash/uniqBy"));
|
|
25
|
+
const sumBy_1 = __importDefault(require("lodash/sumBy"));
|
|
26
|
+
const floor_1 = __importDefault(require("lodash/floor"));
|
|
27
|
+
const Cart_1 = require("../../../Interfaces/Cart");
|
|
28
|
+
const G2_1 = require("../../../Interfaces/G2");
|
|
29
|
+
const IDiscountRule_1 = require("../../../Interfaces/Rules/IDiscountRule");
|
|
30
|
+
// General utils
|
|
31
|
+
const string_1 = require("../../../utils/string");
|
|
32
|
+
const locale_1 = require("../../../utils/locale");
|
|
33
|
+
const inventories_1 = require("../../../utils/inventories");
|
|
34
|
+
const products_1 = require("../../../utils/products");
|
|
35
|
+
// Specitic utils
|
|
36
|
+
const expedition_1 = require("./expedition");
|
|
37
|
+
const products_2 = require("../constants/products");
|
|
38
|
+
const g2_1 = require("./g2");
|
|
39
|
+
const cart_1 = require("./cart");
|
|
40
|
+
// Specific interfaces
|
|
41
|
+
const products_3 = require("../interfaces/products");
|
|
42
|
+
const data_1 = require("../interfaces/data");
|
|
43
|
+
const cart_2 = require("../interfaces/cart");
|
|
44
|
+
const upsells_1 = require("./upsells");
|
|
45
|
+
const object_1 = require("../../../utils/object");
|
|
46
|
+
// ----------------------------------------------------------------------------------------------------------
|
|
47
|
+
// #region PRODUCT UNITS
|
|
48
|
+
const pluralSellUnits = {
|
|
49
|
+
p2: { fr: 'pi²', en: 'sqft' },
|
|
50
|
+
sac: { fr: 'sacs', en: 'bags' },
|
|
51
|
+
unite: { fr: 'unités', en: 'units' },
|
|
52
|
+
tonne: { fr: 'tonnes', en: 'tons' },
|
|
53
|
+
rouleau: { fr: 'rouleaux', en: 'rolls' }
|
|
54
|
+
};
|
|
55
|
+
const pluralSellUnitsBySlug = {
|
|
56
|
+
p2: { fr: 'pi²', en: 'sqft' },
|
|
57
|
+
sac: { fr: 'sacs', en: 'bags' },
|
|
58
|
+
unite: { fr: 'unités', en: 'units' },
|
|
59
|
+
tonne: { fr: 'tonnes', en: 'tons' },
|
|
60
|
+
roul: { fr: 'rouleaux', en: 'rolls' },
|
|
61
|
+
pal: { fr: 'palettes', en: 'pallets' },
|
|
62
|
+
rg: { fr: 'rangs', en: 'rows' },
|
|
63
|
+
ensemble: { fr: 'ensembles', en: 'kits' },
|
|
64
|
+
pl: { fr: 'pL', en: 'linear feet' },
|
|
65
|
+
mcx: { fr: 'morceaux', en: 'pieces' },
|
|
66
|
+
vg3: { fr: 'vg³', en: 'yd³' },
|
|
67
|
+
demipalsm: { fr: 'Demi-palettes (petite)', en: 'Half-pallets (small)' },
|
|
68
|
+
demipallg: { fr: 'Demi-palettes (lg)', en: 'Half-pallets (lg)' },
|
|
69
|
+
tonnes: { fr: 'tonnes', en: 'tons' },
|
|
70
|
+
bte: { fr: 'boîtes', en: 'boxes' },
|
|
71
|
+
pqt: { fr: 'paquets', en: 'bundles' },
|
|
72
|
+
'': { fr: 'unités', en: 'units' }
|
|
73
|
+
};
|
|
74
|
+
const sellUnitsBySlug = {
|
|
75
|
+
p2: { fr: 'pi²', en: 'sqft' },
|
|
76
|
+
sac: { fr: 'sac', en: 'bag' },
|
|
77
|
+
unite: { fr: 'unité', en: 'unit' },
|
|
78
|
+
tonne: { fr: 'tonne', en: 'ton' },
|
|
79
|
+
roul: { fr: 'rouleau', en: 'roll' },
|
|
80
|
+
pal: { fr: 'palette', en: 'pallet' },
|
|
81
|
+
rg: { fr: 'rang', en: 'row' },
|
|
82
|
+
ensemble: { fr: 'ensemble', en: 'kit' },
|
|
83
|
+
pl: { fr: 'pL', en: 'linear feet' },
|
|
84
|
+
mcx: { fr: 'morceau', en: 'piece' },
|
|
85
|
+
vg3: { fr: 'vg³', en: 'yd³' },
|
|
86
|
+
demipalsm: { fr: 'Demi-palette (petite)', en: 'Half-pallet (small)' },
|
|
87
|
+
demipallg: { fr: 'Demi-palette (lg)', en: 'Half-pallet (lg)' },
|
|
88
|
+
tonnes: { fr: 'tonne', en: 'ton' },
|
|
89
|
+
bte: { fr: 'boîte', en: 'box' },
|
|
90
|
+
pqt: { fr: 'paquet', en: 'bundle' },
|
|
91
|
+
'': { fr: 'unité', en: 'unit' }
|
|
92
|
+
};
|
|
93
|
+
/**
|
|
94
|
+
* @description Returns sell unit label in correct language for a specific product's other_units
|
|
95
|
+
* @param {IFilledDimensionUnits[] | undefined} otherUnits The unit array we have to check to get the sell unit
|
|
96
|
+
* @param {string | undefined} locale The language in which we want to return the label
|
|
97
|
+
* @param {string[]} returnUnitForSlugs An array of the slugs we want to return the unit label for
|
|
98
|
+
* @param {boolean} options.returnPlural If plural version should be returned
|
|
99
|
+
* @param {boolean} options.returnShortByDefault If short version should be prioritized
|
|
100
|
+
*/
|
|
101
|
+
const getProductSellUnitLabel = (otherUnits, locale = 'fr', returnUnitForSlugs, options = {}) => {
|
|
102
|
+
if (!!!otherUnits)
|
|
103
|
+
return '';
|
|
104
|
+
const sellingUnit = otherUnits.find((unit) => !!unit.is_sale_unit);
|
|
105
|
+
if (!!!sellingUnit)
|
|
106
|
+
return '';
|
|
107
|
+
return (0, exports.getUnitLabelWithSlug)(sellingUnit.unit_slug, locale, options.returnPlural, returnUnitForSlugs, options.returnShortByDefault);
|
|
108
|
+
};
|
|
109
|
+
exports.getProductSellUnitLabel = getProductSellUnitLabel;
|
|
110
|
+
/**
|
|
111
|
+
* @description Returns unit label in correct language for a specific product's other_units
|
|
112
|
+
* @param {IFilledDimensionUnits[] | undefined} otherUnits The unit array we have to check to get the sell unit
|
|
113
|
+
* @param {string} type The unit type to check
|
|
114
|
+
* @param {string | undefined} locale The language in which we want to return the label
|
|
115
|
+
* @param {string[]} returnUnitForSlugs An array of the slugs we want to return the unit label for
|
|
116
|
+
* @param {boolean} options.returnPlural If plural version should be returned
|
|
117
|
+
* @param {boolean} options.returnShortByDefault If short version should be prioritized
|
|
118
|
+
*/
|
|
119
|
+
const getProductUnitLabel = (otherUnits, type, locale = 'fr', returnUnitForSlugs, options = {}) => {
|
|
120
|
+
if (!!!otherUnits)
|
|
121
|
+
return '';
|
|
122
|
+
const unitToUse = otherUnits.find((unit) => (type == 'sale_unit' ? unit.is_sale_unit : unit.is_inventory_unit));
|
|
123
|
+
if (!!!unitToUse)
|
|
124
|
+
return '';
|
|
125
|
+
return (0, exports.getUnitLabelWithSlug)(unitToUse.unit_slug, locale, options.returnPlural, returnUnitForSlugs, options.returnShortByDefault);
|
|
126
|
+
};
|
|
127
|
+
exports.getProductUnitLabel = getProductUnitLabel;
|
|
128
|
+
/**
|
|
129
|
+
* Returns the unit label for a specific slug
|
|
130
|
+
* @param {string} unitSlug The slug of the unit for which we want to get the label
|
|
131
|
+
* @param {string | undefined} locale The language in which we want to get the label
|
|
132
|
+
* @param {boolean} getPluralVersion Optionnal - If the plural version should be returned instead.
|
|
133
|
+
* @param {string[]} returnUnitForSlugs The slugs for which we want to return a default value, in this case the unit slug for unit
|
|
134
|
+
* @param {boolean} returnShortByDefault Optionnal - If the short version should be prioritized
|
|
135
|
+
*/
|
|
136
|
+
const getUnitLabelWithSlug = (unitSlug, locale = 'fr', getPluralVersion = false, returnUnitForSlugs, returnShortByDefault) => {
|
|
137
|
+
if (!!returnUnitForSlugs && !!returnUnitForSlugs.includes(unitSlug)) {
|
|
138
|
+
return (0, exports.getUnitLabelWithSlug)('unite', locale, getPluralVersion);
|
|
139
|
+
}
|
|
140
|
+
if (!!getPluralVersion)
|
|
141
|
+
return (0, exports.getPluralUnitLabelWithSlug)(unitSlug, locale, returnUnitForSlugs, returnShortByDefault);
|
|
142
|
+
const shortVersion = !!(0, inventories_1.getUnitShortDict)(unitSlug) ? (0, locale_1.translateILang)((0, inventories_1.getUnitShortDict)(unitSlug), locale) : '';
|
|
143
|
+
const longVersion = !!sellUnitsBySlug[unitSlug] ? (0, locale_1.translateILang)(sellUnitsBySlug[unitSlug], locale) : '';
|
|
144
|
+
if (!!returnShortByDefault)
|
|
145
|
+
return shortVersion;
|
|
146
|
+
return longVersion || shortVersion || unitSlug;
|
|
147
|
+
};
|
|
148
|
+
exports.getUnitLabelWithSlug = getUnitLabelWithSlug;
|
|
149
|
+
/**
|
|
150
|
+
* Returns the plural unit label for a specific slug
|
|
151
|
+
* @deprecated Should use getUnitLabelWithSlug instead (with props getPluralVersion=true)
|
|
152
|
+
* @param {string} unitSlug The slug of the unit for which we want to get the label
|
|
153
|
+
* @param {string | undefined} locale The language in which we want to get the label
|
|
154
|
+
* @param {string[]} returnUnitForSlugs The slugs for which we want to return a default value, in this case the unit slug for unit
|
|
155
|
+
*/
|
|
156
|
+
const getPluralUnitLabelWithSlug = (unitSlug, locale = 'fr', returnUnitForSlugs, useShortIfDifferent) => {
|
|
157
|
+
if (!!returnUnitForSlugs && !!returnUnitForSlugs.includes(unitSlug)) {
|
|
158
|
+
return (0, locale_1.translateILang)(pluralSellUnitsBySlug['unite'], locale);
|
|
159
|
+
}
|
|
160
|
+
const shortVersion = !!(0, inventories_1.getUnitShortDict)(unitSlug) ? (0, locale_1.translateILang)((0, inventories_1.getUnitShortDict)(unitSlug), locale) : '';
|
|
161
|
+
const normalVersion = !!sellUnitsBySlug[unitSlug] ? (0, locale_1.translateILang)(sellUnitsBySlug[unitSlug], locale) : '';
|
|
162
|
+
const pluralVersion = !!pluralSellUnitsBySlug[unitSlug] ? (0, locale_1.translateILang)(pluralSellUnitsBySlug[unitSlug], locale) : '';
|
|
163
|
+
// If useShowIfDifferent is defined, and short version is different from the "normal" version, return short value
|
|
164
|
+
if (useShortIfDifferent && shortVersion != normalVersion)
|
|
165
|
+
return shortVersion;
|
|
166
|
+
return pluralVersion || shortVersion || unitSlug;
|
|
167
|
+
};
|
|
168
|
+
exports.getPluralUnitLabelWithSlug = getPluralUnitLabelWithSlug;
|
|
169
|
+
const getCorrectPluralSellUnit = (sellUnit, locale = 'fr') => {
|
|
170
|
+
if (!!!sellUnit.unit)
|
|
171
|
+
return '';
|
|
172
|
+
const frSellUnit = (0, string_1.string_to_slug)((0, locale_1.translateILang)(sellUnit.unit, 'fr'));
|
|
173
|
+
return !!pluralSellUnits[frSellUnit]
|
|
174
|
+
? (0, locale_1.translateILang)(pluralSellUnits[frSellUnit], locale)
|
|
175
|
+
: (0, locale_1.translateILang)(sellUnit.unit, locale);
|
|
176
|
+
};
|
|
177
|
+
exports.getCorrectPluralSellUnit = getCorrectPluralSellUnit;
|
|
178
|
+
const productUnitSupportsDecimals = (unitSlug, isService) => {
|
|
179
|
+
return !!isService || !!['p2', 'pl', 'vg3', 'tonne'].includes(unitSlug);
|
|
180
|
+
};
|
|
181
|
+
exports.productUnitSupportsDecimals = productUnitSupportsDecimals;
|
|
182
|
+
// #endregion
|
|
183
|
+
// ----------------------------------------------------------------------------------------------------------
|
|
184
|
+
// ----------------------------------------------------------------------------------------------------------
|
|
185
|
+
// #region GENERAL
|
|
186
|
+
const getProductAttributes = (product) => {
|
|
187
|
+
const arrColor = !!product.attributes[data_1.AttributesIdEnumGR.SUBCOLOR]
|
|
188
|
+
? product.attributes[data_1.AttributesIdEnumGR.SUBCOLOR]
|
|
189
|
+
: [];
|
|
190
|
+
const arrDimensions = !!product.attributes[data_1.AttributesIdEnumGR.DIMENSIONS]
|
|
191
|
+
? product.attributes[data_1.AttributesIdEnumGR.DIMENSIONS]
|
|
192
|
+
: [];
|
|
193
|
+
const arrFormats = !!product.attributes[data_1.AttributesIdEnumGR.FORMATS]
|
|
194
|
+
? product.attributes[data_1.AttributesIdEnumGR.FORMATS]
|
|
195
|
+
: [];
|
|
196
|
+
return { colors: arrColor, dimensions: arrDimensions, formats: arrFormats };
|
|
197
|
+
};
|
|
198
|
+
exports.getProductAttributes = getProductAttributes;
|
|
199
|
+
const getDescriptionLength = (description, locale = 'fr') => {
|
|
200
|
+
if (!!!description || !!!(0, locale_1.getLocaleOfDictionnary)(description, locale))
|
|
201
|
+
return 0;
|
|
202
|
+
return (0, string_1.stripHTML)((0, locale_1.getLocaleOfDictionnary)(description, locale)).length;
|
|
203
|
+
};
|
|
204
|
+
exports.getDescriptionLength = getDescriptionLength;
|
|
205
|
+
const getDescriptionString = (showFullDesc, maxLength, description, locale = 'fr') => {
|
|
206
|
+
if (!!showFullDesc || (0, exports.getDescriptionLength)(description, locale) <= maxLength) {
|
|
207
|
+
return (0, string_1.stripHTML)((0, locale_1.getLocaleOfDictionnary)(description, locale));
|
|
208
|
+
}
|
|
209
|
+
let truncated = (0, string_1.stripHTML)((0, locale_1.getLocaleOfDictionnary)(description, locale)).slice(0, maxLength).split(' ');
|
|
210
|
+
truncated.pop();
|
|
211
|
+
return truncated.join(' ') + ' [...]';
|
|
212
|
+
};
|
|
213
|
+
exports.getDescriptionString = getDescriptionString;
|
|
214
|
+
/**
|
|
215
|
+
* Returns rounded product sell_unit quantities depending on current value, value of secondary input if existant and sale unit per command step ratio found in product.
|
|
216
|
+
* @param value {number} - Current quantity as entered by user in first input
|
|
217
|
+
* @param otherUnits {IFilledDimensionUnits[] | undefined} - FilledDimensionUnits found in product (possibly undefined)
|
|
218
|
+
* @param value2 {number | undefined} - Current quantity as entered by user in second input (possibly undefined)
|
|
219
|
+
* @param targetIsSecondaryInput {boolean} - If action was triggered from secondary input (defaults to false)
|
|
220
|
+
*/
|
|
221
|
+
const getRoundedSellUnitProductQuantities = (value, otherUnits = [], value2, targetIsSecondaryInput = false) => {
|
|
222
|
+
var _a;
|
|
223
|
+
const saleUnit = otherUnits.find((unit) => unit.is_sale_unit);
|
|
224
|
+
const commandUnit = otherUnits.find((unit) => unit.is_command_unit);
|
|
225
|
+
const commandStep = otherUnits.find((unit) => unit.is_command_step);
|
|
226
|
+
let roundedQuantities = {
|
|
227
|
+
qte1: value,
|
|
228
|
+
qte2: value2
|
|
229
|
+
};
|
|
230
|
+
// Now rounds quantities in calculations to 2 or 0 decimals (depending on what the unit supports)
|
|
231
|
+
if (!!targetIsSecondaryInput && typeof value2 === 'number') {
|
|
232
|
+
if (!!commandStep && !!commandStep.fitting_unit && !!commandUnit && !!commandUnit.fitting_unit && !!saleUnit) {
|
|
233
|
+
const nbCmdUnitPerCmdStep = (0, round_1.default)(commandStep.fitting_unit / commandUnit.fitting_unit, 5);
|
|
234
|
+
const nbSaleUnitPerCmdStep = (0, round_1.default)(commandStep.fitting_unit / ((_a = saleUnit.fitting_unit) !== null && _a !== void 0 ? _a : 1), (0, exports.productUnitSupportsDecimals)(saleUnit.unit_slug) ? 5 : 0);
|
|
235
|
+
// Round value2 to command step
|
|
236
|
+
const roundedValue = value2 === 0
|
|
237
|
+
? 0
|
|
238
|
+
: _roundNbUnitPerCmdStep(value2, nbCmdUnitPerCmdStep, (0, exports.productUnitSupportsDecimals)(saleUnit.unit_slug) ? 2 : 0);
|
|
239
|
+
// Calculate amount of current command units by dividing roundedValue with nbCmdUnitPerCmdStep
|
|
240
|
+
const nbOfRoundedCmdUnits = roundedValue / nbCmdUnitPerCmdStep;
|
|
241
|
+
// Then multiply result by amount of sale units in one command step
|
|
242
|
+
const nbOfRoundedSaleUnits = nbOfRoundedCmdUnits * nbSaleUnitPerCmdStep;
|
|
243
|
+
roundedQuantities = {
|
|
244
|
+
qte1: value2 === 0
|
|
245
|
+
? 0
|
|
246
|
+
: (0, round_1.default)(nbOfRoundedSaleUnits, !!saleUnit && (0, exports.productUnitSupportsDecimals)(saleUnit.unit_slug) ? 2 : 0),
|
|
247
|
+
qte2: roundedValue
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
else if (!!commandStep && !!commandStep.fitting_unit && !!saleUnit && !!saleUnit.fitting_unit) {
|
|
252
|
+
const cmdStepFittingUnit = commandStep.fitting_unit;
|
|
253
|
+
const saleFittingUnit = saleUnit.fitting_unit;
|
|
254
|
+
const nbSaleUnitPerCmdStep = (0, round_1.default)(cmdStepFittingUnit / saleFittingUnit, (0, exports.productUnitSupportsDecimals)(saleUnit.unit_slug) ? 5 : 0);
|
|
255
|
+
const roundedValue = value === 0
|
|
256
|
+
? 0
|
|
257
|
+
: _roundNbUnitPerCmdStep(value, nbSaleUnitPerCmdStep, (0, exports.productUnitSupportsDecimals)(saleUnit.unit_slug) ? 2 : 0);
|
|
258
|
+
let commandUnitQty = undefined;
|
|
259
|
+
if (!!commandUnit && !!commandUnit.fitting_unit) {
|
|
260
|
+
if (value === 0) {
|
|
261
|
+
commandUnitQty = 0;
|
|
262
|
+
}
|
|
263
|
+
// ** NOTE - Commented section here to fix rounding bug - Commented on 10-09-2025, in relation to bug GR-I540
|
|
264
|
+
// if sell_unit has a fitting unit of 1, we can simply divide the command_unit from roundedValue to get result
|
|
265
|
+
// else if (saleFittingUnit == 1) {
|
|
266
|
+
// console.log('YO YO YO are we HERE&&????')
|
|
267
|
+
// commandUnitQty = round(
|
|
268
|
+
// roundedValue / commandUnit.fitting_unit,
|
|
269
|
+
// productUnitSupportsDecimals(commandUnit.unit_slug) ? 2 : 0
|
|
270
|
+
// )
|
|
271
|
+
// }
|
|
272
|
+
else {
|
|
273
|
+
// Calculate amount of current command steps by dividing roundedValue with saleUnitsPerCommandStep
|
|
274
|
+
// ** NOTE - Added round here on 10-09-2025 in relation to bug GR-I540
|
|
275
|
+
const nbOfCmdSteps = (0, round_1.default)(roundedValue / nbSaleUnitPerCmdStep, (0, exports.productUnitSupportsDecimals)(saleUnit.unit_slug) ? 5 : 0);
|
|
276
|
+
// Then multiply result by amount of command unit in one command step
|
|
277
|
+
commandUnitQty =
|
|
278
|
+
nbOfCmdSteps *
|
|
279
|
+
(0, round_1.default)(cmdStepFittingUnit / commandUnit.fitting_unit, (0, exports.productUnitSupportsDecimals)(commandUnit.unit_slug) ? 5 : 0);
|
|
280
|
+
commandUnitQty = (0, round_1.default)(commandUnitQty, (0, exports.productUnitSupportsDecimals)(commandUnit.unit_slug) ? 2 : 0);
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
roundedQuantities = {
|
|
284
|
+
qte1: roundedValue,
|
|
285
|
+
qte2: commandUnitQty
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
return roundedQuantities;
|
|
289
|
+
};
|
|
290
|
+
exports.getRoundedSellUnitProductQuantities = getRoundedSellUnitProductQuantities;
|
|
291
|
+
/**
|
|
292
|
+
* Returns rounded product quantities depending on current value per command step ratio found in product.
|
|
293
|
+
* @param value {number} - Current quantity as entered by user in first input
|
|
294
|
+
* @param otherUnits {IFilledDimensionUnits[] | undefined} - FilledDimensionUnits found in product (possibly undefined)
|
|
295
|
+
* @param type {'sale_unit' | 'inventory_unit'} - Quantity type for computing
|
|
296
|
+
*/
|
|
297
|
+
const getRoundedUnitProductQuantities = (value, otherUnits = [], type) => {
|
|
298
|
+
const unitToTest = type == 'sale_unit'
|
|
299
|
+
? otherUnits.find((unit) => unit.is_sale_unit)
|
|
300
|
+
: otherUnits.find((unit) => unit.is_inventory_unit);
|
|
301
|
+
const commandStep = otherUnits.find((unit) => unit.is_command_step);
|
|
302
|
+
let roundedQuantities = value;
|
|
303
|
+
if (!!commandStep && !!commandStep.fitting_unit && unitToTest && unitToTest.fitting_unit) {
|
|
304
|
+
const cmdStepFittingUnit = commandStep.fitting_unit;
|
|
305
|
+
const fittingUnit = unitToTest.fitting_unit;
|
|
306
|
+
const nbUnitPerCmdStep = cmdStepFittingUnit / fittingUnit;
|
|
307
|
+
const roundedValue = value === 0
|
|
308
|
+
? 0
|
|
309
|
+
: _roundNbUnitPerCmdStepV2(value, nbUnitPerCmdStep, (0, exports.productUnitSupportsDecimals)(unitToTest.unit_slug) ? 5 : 0);
|
|
310
|
+
roundedQuantities = roundedValue;
|
|
311
|
+
}
|
|
312
|
+
return roundedQuantities;
|
|
313
|
+
};
|
|
314
|
+
exports.getRoundedUnitProductQuantities = getRoundedUnitProductQuantities;
|
|
315
|
+
const _roundNbUnitPerCmdStepV2 = (value, nbUnitPerCmdStep, decimalsToCheck = 0) => {
|
|
316
|
+
const currentFittingValue = (0, floor_1.default)(value / nbUnitPerCmdStep, 5); // Rounds unsignificant quantities to lower value (ex. if result is 0.000007, we don't want it to round up to 1)
|
|
317
|
+
const roundedUp = (0, round_1.default)((0, ceil_1.default)(currentFittingValue) * nbUnitPerCmdStep, decimalsToCheck);
|
|
318
|
+
// retrun roundedUp as default value.
|
|
319
|
+
return roundedUp;
|
|
320
|
+
};
|
|
321
|
+
const _roundNbUnitPerCmdStep = (value, nbUnitPerCmdStep, decimalsToCheck = 0) => {
|
|
322
|
+
let numberBuffer = 0;
|
|
323
|
+
if (decimalsToCheck > 0) {
|
|
324
|
+
let buffer = '';
|
|
325
|
+
buffer = buffer.padStart(decimalsToCheck - 1, '0');
|
|
326
|
+
numberBuffer = (0, toNumber_1.default)(`0.${buffer}1`);
|
|
327
|
+
}
|
|
328
|
+
const rounded = (0, round_1.default)(value / nbUnitPerCmdStep, decimalsToCheck) * nbUnitPerCmdStep;
|
|
329
|
+
const roundedUp = Math.ceil(value / nbUnitPerCmdStep) * nbUnitPerCmdStep;
|
|
330
|
+
// if rounded value is 0, but roundedUp is > 0, return roundedUp
|
|
331
|
+
if (rounded == 0 && roundedUp > 0)
|
|
332
|
+
return roundedUp;
|
|
333
|
+
// ** NEW - Added on 10-09-2025 in relation to bug GR-I540
|
|
334
|
+
// if provided value is already a multiple of cmdStep, return value
|
|
335
|
+
if ((0, round_1.default)(value % nbUnitPerCmdStep, decimalsToCheck) == 0)
|
|
336
|
+
return rounded;
|
|
337
|
+
// if provided value is larger than rounded, and roundedUp is an exact multiple of rounded, return roundedUp
|
|
338
|
+
if ((0, round_1.default)(value, decimalsToCheck) > rounded + numberBuffer)
|
|
339
|
+
return roundedUp;
|
|
340
|
+
// if rounded value is an exact multiple of cmdStep, return rounded
|
|
341
|
+
if ((0, round_1.default)(rounded, decimalsToCheck) % nbUnitPerCmdStep <= numberBuffer)
|
|
342
|
+
return rounded;
|
|
343
|
+
// retrun roundedUp as default value.
|
|
344
|
+
return roundedUp;
|
|
345
|
+
};
|
|
346
|
+
/**
|
|
347
|
+
*
|
|
348
|
+
* @param {string} stringToSplit
|
|
349
|
+
* @param {string} dummyStringToReplace.currentValue, optionnal, default : '%%-%%'. Used to provide general replace values for a specific string. Is applied to both sections of the splitted string.
|
|
350
|
+
* @param {string} dummyStringToReplace.newValue, optionnal, default : ' - '. Used to provide general replace values for a specific string. Is applied to both sections of the splitted string.
|
|
351
|
+
* @returns {string[]}
|
|
352
|
+
*/
|
|
353
|
+
const splitOnDashes = (stringToSplit, dummyStringToReplace = { currentValue: '%%-%%', newValue: ' - ' }) => {
|
|
354
|
+
let splited = stringToSplit.split(' - ');
|
|
355
|
+
if (splited.length === 1)
|
|
356
|
+
splited = stringToSplit.split(' -');
|
|
357
|
+
if (splited.length === 1)
|
|
358
|
+
splited = stringToSplit.split('- ');
|
|
359
|
+
return [
|
|
360
|
+
splited[0].replace(dummyStringToReplace.currentValue, dummyStringToReplace.newValue),
|
|
361
|
+
...(!!splited[1]
|
|
362
|
+
? [splited.slice(1).join(' - ').replace(dummyStringToReplace.currentValue, dummyStringToReplace.newValue)]
|
|
363
|
+
: [])
|
|
364
|
+
];
|
|
365
|
+
};
|
|
366
|
+
exports.splitOnDashes = splitOnDashes;
|
|
367
|
+
/**
|
|
368
|
+
* Get product name as array. Array created mostly by splitting name on dash symbol (and variations).
|
|
369
|
+
* @param {IIndexedVariationAlgolia | IIndexedProduct} product
|
|
370
|
+
* @param {string | undefined} locale
|
|
371
|
+
* @returns {string[]} - Position 0 is the "commum section" of the name, and position 1 should contain all specifics (ex. color, size, etc...)
|
|
372
|
+
*/
|
|
373
|
+
const getProdName = (product, locale, platform, attributes) => {
|
|
374
|
+
var _a;
|
|
375
|
+
let name;
|
|
376
|
+
if (!!product.full_name) {
|
|
377
|
+
name = (0, locale_1.getLocaleOfDictionnary)(product.full_name, locale);
|
|
378
|
+
}
|
|
379
|
+
else {
|
|
380
|
+
name = (0, locale_1.getLocaleOfDictionnary)(product.name, locale);
|
|
381
|
+
if (!!product.use_parent && !!product.parent_name) {
|
|
382
|
+
if (typeof product.parent_name === 'string') {
|
|
383
|
+
name = product.parent_name;
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
let newNameArray = [];
|
|
388
|
+
const dashesToFind = [' - ', '- ', ' -'];
|
|
389
|
+
// If name includes parenthesis...
|
|
390
|
+
if (name.includes('(')) {
|
|
391
|
+
let newStr = '';
|
|
392
|
+
let strWithParenthesisToCheck = name;
|
|
393
|
+
// a. Replace all occurences of dashesToFind found between parenthesis with '-'
|
|
394
|
+
while (strWithParenthesisToCheck.includes('(')) {
|
|
395
|
+
let positionStart = strWithParenthesisToCheck.indexOf('(');
|
|
396
|
+
let positionEnd = strWithParenthesisToCheck.indexOf(')');
|
|
397
|
+
// When first string between paranthesis found, replace dashesToFind
|
|
398
|
+
let substrToCheck = strWithParenthesisToCheck.substring(positionStart, positionEnd + 1);
|
|
399
|
+
for (let dash of dashesToFind) {
|
|
400
|
+
substrToCheck = substrToCheck.replace(dash, '-');
|
|
401
|
+
}
|
|
402
|
+
// Add updated string to newStr from the beginning to the end of section with parenthesis
|
|
403
|
+
newStr += strWithParenthesisToCheck.substring(0, positionStart) + substrToCheck;
|
|
404
|
+
// Strip checked string to remove section added to newStr.
|
|
405
|
+
// This will mean next time we go through the loop, logic will check for next section with parenthesis. If not found, loop ends.
|
|
406
|
+
strWithParenthesisToCheck =
|
|
407
|
+
positionEnd === strWithParenthesisToCheck.length - 1 ? '' : strWithParenthesisToCheck.substring(positionEnd + 1);
|
|
408
|
+
}
|
|
409
|
+
// Add ending of string to newly formatted string after loop done (in case last parenthesis found was not at the end of the string)
|
|
410
|
+
newStr += strWithParenthesisToCheck;
|
|
411
|
+
// b. Isolate "first part" of string
|
|
412
|
+
const positionOfFirst = newStr.indexOf(')');
|
|
413
|
+
let firstPart = newStr.substring(0, positionOfFirst);
|
|
414
|
+
// If first closing parenthesis is not at end of string and firstPart contains dashesToFind, it means the ' - ' should be keep intact.
|
|
415
|
+
// Replace ' - ' found with uncommon string so we can put it back later, then call splitOnDashes function
|
|
416
|
+
if (positionOfFirst !== newStr.length - 1 && dashesToFind.some((str) => firstPart.includes(str))) {
|
|
417
|
+
const secondPart = newStr.substring(positionOfFirst);
|
|
418
|
+
for (let str of dashesToFind) {
|
|
419
|
+
firstPart.replace(str, '%%-%%');
|
|
420
|
+
}
|
|
421
|
+
newNameArray = (0, exports.splitOnDashes)(`${firstPart}${secondPart}`);
|
|
422
|
+
}
|
|
423
|
+
// Else, simply call splitOnDashes function
|
|
424
|
+
else {
|
|
425
|
+
newNameArray = (0, exports.splitOnDashes)(newStr);
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
// Else, no parenthesis found, call splitOnDashes function
|
|
429
|
+
else {
|
|
430
|
+
newNameArray = (0, exports.splitOnDashes)(name);
|
|
431
|
+
}
|
|
432
|
+
if (platform === 'pos' && !!attributes) {
|
|
433
|
+
for (const attribute of attributes) {
|
|
434
|
+
if (!!!attribute.id)
|
|
435
|
+
continue;
|
|
436
|
+
const productAttributeSlugs = (_a = product.attributes) === null || _a === void 0 ? void 0 : _a[attribute.id];
|
|
437
|
+
if (!!productAttributeSlugs) {
|
|
438
|
+
for (const attrValue of attribute.values) {
|
|
439
|
+
if (productAttributeSlugs.includes(attrValue.slug)) {
|
|
440
|
+
const label = (0, locale_1.getLocaleOfDictionnary)(attrValue.value, locale);
|
|
441
|
+
if (label) {
|
|
442
|
+
newNameArray[0] = newNameArray[0] + ` (${label})`;
|
|
443
|
+
}
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
}
|
|
449
|
+
return newNameArray;
|
|
450
|
+
};
|
|
451
|
+
exports.getProdName = getProdName;
|
|
452
|
+
/**
|
|
453
|
+
* Function getParentProductCategoryGroup
|
|
454
|
+
* @param prod - Product to check
|
|
455
|
+
*/
|
|
456
|
+
const getParentProductCategoryGroup = (prod) => {
|
|
457
|
+
let type = 'other';
|
|
458
|
+
if (!!prod.categories && !!prod.categories['lvl0']) {
|
|
459
|
+
const categorySlug = prod.categories['lvl0'];
|
|
460
|
+
switch (categorySlug) {
|
|
461
|
+
case 'gazon':
|
|
462
|
+
if (!!(0, exports.checkIfProductIsOfType)(prod, 'gazon')) {
|
|
463
|
+
type = 'gazon';
|
|
464
|
+
}
|
|
465
|
+
break;
|
|
466
|
+
case 'amenagement-paysager':
|
|
467
|
+
if (!!(0, exports.checkIfProductIsOfType)(prod, 'beton')) {
|
|
468
|
+
type = 'beton';
|
|
469
|
+
}
|
|
470
|
+
break;
|
|
471
|
+
default:
|
|
472
|
+
if (!!(0, exports.checkIfProductIsOfType)(prod, 'vrac')) {
|
|
473
|
+
type = 'vrac';
|
|
474
|
+
}
|
|
475
|
+
break;
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
return type;
|
|
479
|
+
};
|
|
480
|
+
exports.getParentProductCategoryGroup = getParentProductCategoryGroup;
|
|
481
|
+
/**
|
|
482
|
+
* Function getProductFormOptions - Returns all AttributeValues for product to construct options in add to cart form
|
|
483
|
+
* @param product - Product to check
|
|
484
|
+
* @param attributes - Array of IAttributes to fetch info from
|
|
485
|
+
*/
|
|
486
|
+
const getProductFormOptions = (product, attributes) => {
|
|
487
|
+
let allColorOptions = [];
|
|
488
|
+
let allDimensionOptions = [];
|
|
489
|
+
let allFormatOptions = [];
|
|
490
|
+
//Product Attributes
|
|
491
|
+
const product_attributes = (0, exports.getProductAttributes)(product);
|
|
492
|
+
//Overridden attr
|
|
493
|
+
let overridenAttributes = product.declinations
|
|
494
|
+
.map((declination) => declination.overriden_attributes)
|
|
495
|
+
.filter((ova) => !!ova);
|
|
496
|
+
overridenAttributes = (0, flatten_1.default)(overridenAttributes);
|
|
497
|
+
overridenAttributes = (0, uniqBy_1.default)(overridenAttributes, 'slug');
|
|
498
|
+
const getOverriddenValues = (prodAttributes, attrId) => {
|
|
499
|
+
const overridenOptions = !!overridenAttributes.length
|
|
500
|
+
? overridenAttributes.filter((attr) => attr.id === attrId)
|
|
501
|
+
: [];
|
|
502
|
+
let finalOptions = [];
|
|
503
|
+
for (const attr of prodAttributes) {
|
|
504
|
+
let isOverridden = false;
|
|
505
|
+
for (const ovOption of overridenOptions) {
|
|
506
|
+
if (!isOverridden) {
|
|
507
|
+
if (!!attr && attr.slug === ovOption.slug) {
|
|
508
|
+
isOverridden = true;
|
|
509
|
+
finalOptions = [
|
|
510
|
+
...finalOptions,
|
|
511
|
+
Object.assign(Object.assign({}, attr), { other_details: Object.assign(Object.assign({}, attr.other_details), { image: ovOption.overriden_values }) })
|
|
512
|
+
];
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
if (!isOverridden) {
|
|
517
|
+
finalOptions = [...finalOptions, attr];
|
|
518
|
+
}
|
|
519
|
+
}
|
|
520
|
+
return finalOptions;
|
|
521
|
+
};
|
|
522
|
+
// ----------------------------------------------------------
|
|
523
|
+
// #region colors
|
|
524
|
+
const subColorsAttr = attributes.find((attr) => attr.id === data_1.AttributesIdEnumGR.SUBCOLOR);
|
|
525
|
+
if (!!subColorsAttr) {
|
|
526
|
+
const subColors = subColorsAttr.values;
|
|
527
|
+
const colorsAttributes = subColors.filter((sub) => product_attributes.colors.includes(sub.slug));
|
|
528
|
+
const finalColors = getOverriddenValues(colorsAttributes, data_1.AttributesIdEnumGR.SUBCOLOR);
|
|
529
|
+
allColorOptions = (0, orderBy_1.default)(finalColors, (color) => product.declinations.findIndex((d) => d.attributes[data_1.AttributesIdEnumGR.SUBCOLOR].includes(color.slug)));
|
|
530
|
+
}
|
|
531
|
+
// #endregion
|
|
532
|
+
// ----------------------------------------------------------
|
|
533
|
+
// ----------------------------------------------------------
|
|
534
|
+
// #region dimensions
|
|
535
|
+
const dimensionsAttr = attributes.find((attr) => attr.id === data_1.AttributesIdEnumGR.DIMENSIONS);
|
|
536
|
+
if (!!dimensionsAttr) {
|
|
537
|
+
const dimensions = dimensionsAttr.values;
|
|
538
|
+
const dimensionsAttributes = dimensions.filter((d) => product_attributes.dimensions.includes(d.slug));
|
|
539
|
+
const finalDimensions = getOverriddenValues(dimensionsAttributes, data_1.AttributesIdEnumGR.DIMENSIONS);
|
|
540
|
+
allDimensionOptions = finalDimensions;
|
|
541
|
+
}
|
|
542
|
+
// #endregion
|
|
543
|
+
// ----------------------------------------------------------
|
|
544
|
+
// ----------------------------------------------------------
|
|
545
|
+
// #region formats
|
|
546
|
+
const formatsAttr = attributes.find((attr) => attr.id === data_1.AttributesIdEnumGR.FORMATS);
|
|
547
|
+
if (!!formatsAttr) {
|
|
548
|
+
const formats = formatsAttr.values;
|
|
549
|
+
allFormatOptions = formats.filter((f) => product_attributes.formats.includes(f.slug));
|
|
550
|
+
}
|
|
551
|
+
// #endregion
|
|
552
|
+
// ----------------------------------------------------------
|
|
553
|
+
return {
|
|
554
|
+
allColors: allColorOptions,
|
|
555
|
+
allDimensions: allDimensionOptions,
|
|
556
|
+
allFormats: allFormatOptions
|
|
557
|
+
};
|
|
558
|
+
};
|
|
559
|
+
exports.getProductFormOptions = getProductFormOptions;
|
|
560
|
+
/**
|
|
561
|
+
* @description Checks if product is of type by checking TYPE attribute value. Works with indexed product or cart item.
|
|
562
|
+
* @param product
|
|
563
|
+
* @param type
|
|
564
|
+
* @param excludeUndefined If excludeUndefined is true, products without the "type" attribute will return true
|
|
565
|
+
* @returns boolean
|
|
566
|
+
*/
|
|
567
|
+
const checkIfProductIsOfType = (product, type, excludeUndefined) => {
|
|
568
|
+
const attr = !!product && !!product.attributes ? product.attributes : {};
|
|
569
|
+
if (!!!attr[data_1.AttributesIdEnumGR.TYPE] && !!excludeUndefined)
|
|
570
|
+
return true;
|
|
571
|
+
return (!!attr[data_1.AttributesIdEnumGR.TYPE] &&
|
|
572
|
+
Array.isArray(attr[data_1.AttributesIdEnumGR.TYPE]) &&
|
|
573
|
+
attr[data_1.AttributesIdEnumGR.TYPE].includes(type));
|
|
574
|
+
};
|
|
575
|
+
exports.checkIfProductIsOfType = checkIfProductIsOfType;
|
|
576
|
+
// #endregion
|
|
577
|
+
// ----------------------------------------------------------------------------------------------------------
|
|
578
|
+
// ----------------------------------------------------------------------------------------------------------
|
|
579
|
+
// #region GRASS
|
|
580
|
+
/**
|
|
581
|
+
* Check if provided sku/slug corresponds to a non-speciality grass item
|
|
582
|
+
* @param sku Grass item's sku
|
|
583
|
+
* @param slug Grass item's parent product slug
|
|
584
|
+
* @param onlyBaseGrass Optionnal. If provided data should only be compared to base grass (aka Kentucky)
|
|
585
|
+
*/
|
|
586
|
+
const checkIfIsNonSpecialityGrass = (sku, slug, onlyBaseGrass) => {
|
|
587
|
+
const skusToCheck = [products_2.kentucky, ...(!onlyBaseGrass ? [products_2.prestige] : [])];
|
|
588
|
+
const slugsToCheck = ['kentucky', ...(!onlyBaseGrass ? ['prestige'] : [])];
|
|
589
|
+
return skusToCheck.includes(sku) || slugsToCheck.includes(slug);
|
|
590
|
+
};
|
|
591
|
+
exports.checkIfIsNonSpecialityGrass = checkIfIsNonSpecialityGrass;
|
|
592
|
+
const checkIfProductIsInstallation = (item) => {
|
|
593
|
+
return !!item.is_service && !!item.parent_slug && !!item.parent_slug.includes('installation');
|
|
594
|
+
};
|
|
595
|
+
exports.checkIfProductIsInstallation = checkIfProductIsInstallation;
|
|
596
|
+
/**
|
|
597
|
+
* Returns array of installation items found in provided array
|
|
598
|
+
* @param items - Array of cart items or IIndexedDeclinations to check
|
|
599
|
+
*/
|
|
600
|
+
const getAllInstallFromItems = (items) => {
|
|
601
|
+
return items.filter((i) => (!!i.parent_slug && products_2.installationProductsSlugs.includes(i.parent_slug)) ||
|
|
602
|
+
Object.values(products_2.installationProSpecSkus).includes(i.sku));
|
|
603
|
+
};
|
|
604
|
+
exports.getAllInstallFromItems = getAllInstallFromItems;
|
|
605
|
+
/**
|
|
606
|
+
* Function fuseGrassProducts
|
|
607
|
+
* @description - Returns items with only one apparent grass product (used for detail customers).
|
|
608
|
+
* ** FOR DISPLAY PURPOSES ONLY - Always save grass products separatly in ICart **
|
|
609
|
+
* @param recursiveItems - ICartItems with subitems (object created for display purposes)
|
|
610
|
+
*/
|
|
611
|
+
const fuseGrassProducts = (recursiveItems, isPro) => {
|
|
612
|
+
const specialityGrass = recursiveItems[0];
|
|
613
|
+
const kentuckyGrass = (specialityGrass.sub_items || []).find((sub) => sub.sku === products_2.kentucky || sub.parent_slug == 'kentucky');
|
|
614
|
+
let newItems = [];
|
|
615
|
+
if (!!kentuckyGrass) {
|
|
616
|
+
const kentuckyPrice = (0, products_1.getLowestPrice)(kentuckyGrass);
|
|
617
|
+
const regPriceKentucky = kentuckyGrass.regular_price.amount;
|
|
618
|
+
const newGrassRegPrice = !!kentuckyPrice.promo ? regPriceKentucky : kentuckyPrice.price.amount;
|
|
619
|
+
const newGrassDiscountPrice = (!!specialityGrass.discount_price
|
|
620
|
+
? specialityGrass.discount_price.amount
|
|
621
|
+
: specialityGrass.regular_price.amount) +
|
|
622
|
+
(!!kentuckyPrice.promo ? kentuckyPrice.price.amount : regPriceKentucky);
|
|
623
|
+
const getLowestPriceSpecialityGrass = (0, products_1.getLowestPrice)(specialityGrass);
|
|
624
|
+
newItems = [
|
|
625
|
+
Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, specialityGrass), { regular_price: Object.assign(Object.assign({}, specialityGrass.regular_price), { amount: newGrassRegPrice + specialityGrass.regular_price.amount }) }), (!!newGrassDiscountPrice
|
|
626
|
+
? {
|
|
627
|
+
discount_price: Object.assign(Object.assign({}, (specialityGrass.discount_price || { currency: 'CAD' })), { amount: newGrassDiscountPrice })
|
|
628
|
+
}
|
|
629
|
+
: {})), (!!specialityGrass.promo_price
|
|
630
|
+
? {
|
|
631
|
+
promo_price: Object.assign(Object.assign({}, specialityGrass.promo_price), { amount: specialityGrass.promo_price.amount + kentuckyPrice.price.amount })
|
|
632
|
+
}
|
|
633
|
+
: {})), (!!!isPro && !!kentuckyGrass.tier_pricing
|
|
634
|
+
? {
|
|
635
|
+
tier_pricing: kentuckyGrass.tier_pricing.map((t) => (Object.assign(Object.assign({}, t), { price: Object.assign(Object.assign({}, t.price), { amount: t.price.amount + getLowestPriceSpecialityGrass.price.amount }) })))
|
|
636
|
+
}
|
|
637
|
+
: {})), { sub_items: [
|
|
638
|
+
Object.assign(Object.assign({}, kentuckyGrass), { hide_from_summary: true }),
|
|
639
|
+
...(specialityGrass.sub_items || []).slice(1)
|
|
640
|
+
] }),
|
|
641
|
+
...recursiveItems.slice(1)
|
|
642
|
+
];
|
|
643
|
+
}
|
|
644
|
+
return newItems;
|
|
645
|
+
};
|
|
646
|
+
exports.fuseGrassProducts = fuseGrassProducts;
|
|
647
|
+
const isMinQtyFee = (slug) => {
|
|
648
|
+
return ['minimum-facturable-commande', 'frais-minimum-gazon-pour-installation'].includes(slug);
|
|
649
|
+
};
|
|
650
|
+
exports.isMinQtyFee = isMinQtyFee;
|
|
651
|
+
const getAllMinGrassQuantities = (grassProduct, isPro) => {
|
|
652
|
+
return {
|
|
653
|
+
pickup: (0, expedition_1.getMinGrassQte)(grassProduct, 'pickup', isPro),
|
|
654
|
+
shipping: (0, expedition_1.getMinGrassQte)(grassProduct, 'shipping', isPro),
|
|
655
|
+
install: (0, expedition_1.getMinQteInstall)(isPro)
|
|
656
|
+
};
|
|
657
|
+
};
|
|
658
|
+
exports.getAllMinGrassQuantities = getAllMinGrassQuantities;
|
|
659
|
+
const getMinQtyFeeText = (parent_slug = '', grassProduct, isPro, locale = 'fr', expeditionMethod, shortVersion) => {
|
|
660
|
+
const type = parent_slug === 'frais-minimum-gazon-pour-installation' ? 'install' : 'order';
|
|
661
|
+
const minQuantities = (0, exports.getAllMinGrassQuantities)(grassProduct, isPro);
|
|
662
|
+
const localeSellUnit = (0, locale_1.translateILang)(pluralSellUnits.p2, locale);
|
|
663
|
+
const localeStepUnit = (0, locale_1.translateILang)((0, inventories_1.getUnitShortDict)('roul'), locale).toLowerCase();
|
|
664
|
+
const localeMinUnit = (0, locale_1.translateILang)((0, inventories_1.getUnitShortDict)('pal'), locale).toLowerCase();
|
|
665
|
+
let str = '';
|
|
666
|
+
const endStr = (0, locale_1.translateILang)({
|
|
667
|
+
fr: ` Ce frais correspond au prix du gazon choisi multiplié par la différence entre la quantité choisie et le minimum.`,
|
|
668
|
+
en: ` Ce frais correspond au prix du gazon choisi multiplié par la différence entre la quantité choisie et le minimum.`
|
|
669
|
+
}, locale);
|
|
670
|
+
// If expedition method not chosen yet, and pickup & shipping quantities are different, show both
|
|
671
|
+
if (!!!expeditionMethod && type === 'order' && minQuantities.pickup !== minQuantities.shipping) {
|
|
672
|
+
const strMinShipping = `${minQuantities.shipping}${localeSellUnit} (${minQuantities.shipping / 740} ${localeMinUnit})`;
|
|
673
|
+
const strMinPickup = !!minQuantities.pickup
|
|
674
|
+
? `${minQuantities.pickup}${localeSellUnit} (${minQuantities.pickup / 740} ${localeMinUnit})`
|
|
675
|
+
: '';
|
|
676
|
+
str = (0, locale_1.translateILang)({
|
|
677
|
+
fr: `Les commandes de gazon sont disponibles à partir de 10${localeSellUnit} (1 ${localeStepUnit}), mais le minimum facturable pour la livraison est de ${strMinShipping}${!!strMinPickup ? ` et de ${strMinPickup} pour la cueillette.` : ``}`,
|
|
678
|
+
en: `Sod orders are available starting at 10${localeSellUnit} (1 ${localeStepUnit}), but the minimum chargeable for delivery is ${strMinShipping}${!!strMinPickup ? ` and ${strMinPickup} for pick-up.` : ``}`
|
|
679
|
+
}, locale);
|
|
680
|
+
if (!!!shortVersion) {
|
|
681
|
+
str += endStr;
|
|
682
|
+
}
|
|
683
|
+
return str;
|
|
684
|
+
}
|
|
685
|
+
// Show specific quantity for expedition type
|
|
686
|
+
const minBillableQty = type === 'install'
|
|
687
|
+
? minQuantities.install
|
|
688
|
+
: expeditionMethod === 'pickup'
|
|
689
|
+
? minQuantities.pickup
|
|
690
|
+
: minQuantities.shipping;
|
|
691
|
+
const minQtyPallets = minBillableQty !== 0 ? minBillableQty / 740 : 0;
|
|
692
|
+
const minBillableStr = `${minBillableQty}${localeSellUnit}${type === 'order' ? ' (' + minQtyPallets + ' ' + localeMinUnit + ')' : ''}`;
|
|
693
|
+
str = (0, locale_1.translateILang)({
|
|
694
|
+
fr: `${type === 'install'
|
|
695
|
+
? "L'installation"
|
|
696
|
+
: expeditionMethod === 'pickup'
|
|
697
|
+
? 'La cueillette'
|
|
698
|
+
: expeditionMethod === 'delivery'
|
|
699
|
+
? 'La livraison'
|
|
700
|
+
: 'La commande'} de gazon est disponible à partir de 10${localeSellUnit} (1 ${localeStepUnit}), mais le minimum facturable est de ${minBillableStr}.`,
|
|
701
|
+
en: `Sod ${type === 'install'
|
|
702
|
+
? 'installation'
|
|
703
|
+
: expeditionMethod === 'pickup'
|
|
704
|
+
? 'pick-up'
|
|
705
|
+
: expeditionMethod === 'delivery'
|
|
706
|
+
? 'delivery'
|
|
707
|
+
: 'ordering'} is available starting at 10${localeSellUnit} (1 ${localeStepUnit}), but the minimum billable is ${minBillableStr}.`
|
|
708
|
+
}, locale);
|
|
709
|
+
if (!!!shortVersion) {
|
|
710
|
+
str += endStr;
|
|
711
|
+
}
|
|
712
|
+
return str;
|
|
713
|
+
};
|
|
714
|
+
exports.getMinQtyFeeText = getMinQtyFeeText;
|
|
715
|
+
const getMinQtyFeeAmountText = (parent_slug = '', locale = 'fr', servicesFees, showMinFeeAmount = true) => {
|
|
716
|
+
const serviceOrFee = servicesFees.find((i) => i.parent_slug === parent_slug);
|
|
717
|
+
if (!!!serviceOrFee)
|
|
718
|
+
return '';
|
|
719
|
+
const amount = (0, toNumber_1.default)(serviceOrFee.regular_price.amount) * serviceOrFee.qte;
|
|
720
|
+
return (0, locale_1.translateILang)({
|
|
721
|
+
fr: `Une différence de ${!!showMinFeeAmount ? amount.toFixed(2) + '$' : '%LOADER%'}%BOLD% vous sera chargée si la quantité de gazon au panier est plus petite que le minimum requis.`,
|
|
722
|
+
en: `A difference of ${!!showMinFeeAmount ? amount.toFixed(2) + '$' : '%LOADER%'}%BOLD% will be charged if the quantity of sod in the cart is less than the minimum required.`
|
|
723
|
+
}, locale);
|
|
724
|
+
};
|
|
725
|
+
exports.getMinQtyFeeAmountText = getMinQtyFeeAmountText;
|
|
726
|
+
const getGrassQteText = (chosenDeclination, locale = 'fr') => {
|
|
727
|
+
let txt = '';
|
|
728
|
+
let nbRolls = 0;
|
|
729
|
+
let nbSquareFeet = 0;
|
|
730
|
+
const units = !!!chosenDeclination ? [] : chosenDeclination.other_units;
|
|
731
|
+
if (!!units && !!units.length) {
|
|
732
|
+
const itemRolls = units.find((measure) => measure.unit_slug === 'roul');
|
|
733
|
+
const itemSquareFeet = units.find((measure) => measure.unit_slug === 'pal');
|
|
734
|
+
if (!!itemSquareFeet && !!itemSquareFeet.fitting_unit) {
|
|
735
|
+
nbSquareFeet = itemSquareFeet.fitting_unit;
|
|
736
|
+
}
|
|
737
|
+
if (!!itemRolls && !!itemRolls.fitting_unit && nbSquareFeet !== 0) {
|
|
738
|
+
nbRolls = nbSquareFeet / itemRolls.fitting_unit;
|
|
739
|
+
}
|
|
740
|
+
}
|
|
741
|
+
txt = (0, locale_1.translateILang)({
|
|
742
|
+
fr: 'Pour ce produit, vous devez commander par pieds carrés. Une palette = *nbRolls* rouleaux (*nbSquareFeet*pi2)',
|
|
743
|
+
en: 'For this product, you have to order by square feet. A pallet = *nbRolls* rolls (*nbSquareFeet*pi2)'
|
|
744
|
+
}, locale);
|
|
745
|
+
txt = txt.replace('*nbRolls*', String(nbRolls));
|
|
746
|
+
txt = txt.replace('*nbSquareFeet*', String(nbSquareFeet));
|
|
747
|
+
return txt;
|
|
748
|
+
};
|
|
749
|
+
exports.getGrassQteText = getGrassQteText;
|
|
750
|
+
const getGrassServicesFees = async (grassProduct, isPro, useFees, expeditionMethod, fetchProduct, getIfAddressIsInsideZones, getDistanceFromAddress, locale, allStores, chosenGrass, baseGrass, customPriceList) => {
|
|
751
|
+
const installItems = await (0, exports.getInstallationArray)(grassProduct.qte, (!!baseGrass ? baseGrass : chosenGrass).product_upsells, fetchProduct, locale, isPro, chosenGrass.sku, customPriceList, { engrais: true, roulage: true });
|
|
752
|
+
const cart = Object.assign(Object.assign({}, (0, Cart_1.getDefaultCart)()), { items: [
|
|
753
|
+
chosenGrass,
|
|
754
|
+
...(!!baseGrass ? [baseGrass] : []),
|
|
755
|
+
...installItems.filter((item) => !!!(0, exports.isMinQtyFee)(item.parent_slug || ''))
|
|
756
|
+
] });
|
|
757
|
+
const applied = await (0, exports.fetchFeesBeforeCart)(!!useFees, cart, expeditionMethod, fetchProduct, getIfAddressIsInsideZones, getDistanceFromAddress, locale, allStores, isPro, grassProduct, undefined, { useStoreAddress: 'sainte-julie' }, customPriceList);
|
|
758
|
+
return [...installItems, ...applied.itemsToAdd];
|
|
759
|
+
};
|
|
760
|
+
exports.getGrassServicesFees = getGrassServicesFees;
|
|
761
|
+
const getGrassSubQuestionsByType = (type) => {
|
|
762
|
+
if (type === 'pro') {
|
|
763
|
+
return products_2.otherGrassSubQuestions.filter((sub) => !!sub.proOnly);
|
|
764
|
+
}
|
|
765
|
+
return products_2.otherGrassSubQuestions.filter((sub) => 'installation-gazon' === sub.associatedProductSlug || (!!sub.installOnly && !!!sub.proOnly));
|
|
766
|
+
};
|
|
767
|
+
exports.getGrassSubQuestionsByType = getGrassSubQuestionsByType;
|
|
768
|
+
/**
|
|
769
|
+
* @description For grass products. Over 1480pi2, if installation, quantities are rounded to rolls (10pi2) if pickup, and to half pal. if shipping
|
|
770
|
+
* @param grassProduct
|
|
771
|
+
* @param cartData
|
|
772
|
+
* @returns quantity rounded to rolls with items to change or undefined
|
|
773
|
+
*/
|
|
774
|
+
const handleGrassProductQtyRoundForShipping = (cartData, grassProduct) => {
|
|
775
|
+
if (!!!cartData || !!!grassProduct)
|
|
776
|
+
return;
|
|
777
|
+
const product = cartData.items.find((item) => item.sku === grassProduct.sku);
|
|
778
|
+
if (!!!product)
|
|
779
|
+
return;
|
|
780
|
+
const productOtherUnits = product.other_units;
|
|
781
|
+
if (!!!productOtherUnits)
|
|
782
|
+
return;
|
|
783
|
+
// get new rounded qte
|
|
784
|
+
const palUnit = productOtherUnits.find((u) => u.unit_slug === 'pal');
|
|
785
|
+
const rounded = (0, exports.roundGrassQte)(product.qte, !!!cartData.is_pickup, palUnit);
|
|
786
|
+
if (!!!rounded || rounded === grassProduct.qte)
|
|
787
|
+
return;
|
|
788
|
+
// ajust items with new quantity
|
|
789
|
+
let itemsToChange = [];
|
|
790
|
+
const recursiveGrassItem = (0, cart_1.getRecursiveItems)(cartData.items).find((item) => item.sku === grassProduct.sku);
|
|
791
|
+
const getItemsToChange = (item) => {
|
|
792
|
+
if (!!item.sub_items) {
|
|
793
|
+
item.sub_items.forEach((subItem) => getItemsToChange(subItem));
|
|
794
|
+
}
|
|
795
|
+
if (item.parent_slug === 'frais-de-mobilisation') {
|
|
796
|
+
const totalPallet = (0, expedition_1.getPalletQty)(cartData.items.map((i) => {
|
|
797
|
+
if ((0, exports.checkIfProductIsOfType)(i, 'gazon')) {
|
|
798
|
+
return Object.assign(Object.assign({}, i), { qte: rounded });
|
|
799
|
+
}
|
|
800
|
+
return i;
|
|
801
|
+
}), 'grass');
|
|
802
|
+
itemsToChange.push({
|
|
803
|
+
sku: item.sku,
|
|
804
|
+
qte: (0, ceil_1.default)(totalPallet / expedition_1.installationFeePalletTier)
|
|
805
|
+
});
|
|
806
|
+
return;
|
|
807
|
+
}
|
|
808
|
+
if (!!item.is_upsell_of_sku) {
|
|
809
|
+
const parentUpsellProd = cartData.items.find((i) => i.sku === item.is_upsell_of_sku);
|
|
810
|
+
if (!!parentUpsellProd) {
|
|
811
|
+
const sameUpsell = (parentUpsellProd.product_upsells || []).find((up) => up.recommendation_sku === item.sku);
|
|
812
|
+
if (!!sameUpsell) {
|
|
813
|
+
const anUpsellProduct = Object.assign(Object.assign(Object.assign(Object.assign({}, item), { parent_slug: sameUpsell.recommendation_parent_slug, recommended_qte: sameUpsell.recommendation_qty, recommended_sku: sameUpsell.recommendation_sku, matching_qte: !!sameUpsell.matching_qty, auto_add: sameUpsell.auto_add, auto_add_exceptions: sameUpsell.auto_add_exceptions, actual_qte: sameUpsell.actual_qty }), (!!sameUpsell.is_recommendation ? { is_recommendation: true } : {})), (!!sameUpsell.show_recommendation_msg ? { show_recommendation_msg: true } : {}));
|
|
814
|
+
const ratio = (0, upsells_1.calculateUpsellQte)(anUpsellProduct, rounded);
|
|
815
|
+
if (!!ratio) {
|
|
816
|
+
itemsToChange.push({
|
|
817
|
+
sku: item.sku,
|
|
818
|
+
qte: ratio
|
|
819
|
+
});
|
|
820
|
+
return;
|
|
821
|
+
}
|
|
822
|
+
}
|
|
823
|
+
}
|
|
824
|
+
}
|
|
825
|
+
itemsToChange.push({
|
|
826
|
+
sku: item.sku,
|
|
827
|
+
qte: rounded
|
|
828
|
+
});
|
|
829
|
+
return;
|
|
830
|
+
};
|
|
831
|
+
if (!!recursiveGrassItem) {
|
|
832
|
+
getItemsToChange(recursiveGrassItem);
|
|
833
|
+
}
|
|
834
|
+
return { rounded, itemsToChange };
|
|
835
|
+
};
|
|
836
|
+
exports.handleGrassProductQtyRoundForShipping = handleGrassProductQtyRoundForShipping;
|
|
837
|
+
/**
|
|
838
|
+
* Function roundGrassQte
|
|
839
|
+
* @description Returns rounded grass quantity depending on current qty, if customer selected installation and pallet unit (if defined)
|
|
840
|
+
* @param currentQte {number} - Current quantity as entered by user in input
|
|
841
|
+
* @param isShipping {boolean} - Whether customer has selected installation option
|
|
842
|
+
* @param palUnit {IFilledDimensionUnits | undefined} - Pallet FilledDimensionUnit (possibly undefined)
|
|
843
|
+
*/
|
|
844
|
+
const roundGrassQte = (currentQte, isShipping, palUnit) => {
|
|
845
|
+
let newQte = currentQte;
|
|
846
|
+
switch (true) {
|
|
847
|
+
case currentQte < 1480:
|
|
848
|
+
const rest1480 = currentQte % 10;
|
|
849
|
+
if (rest1480 !== 0) {
|
|
850
|
+
newQte = currentQte - rest1480 + 10;
|
|
851
|
+
}
|
|
852
|
+
break;
|
|
853
|
+
case currentQte >= 1480 && !!!isShipping:
|
|
854
|
+
const rest1480Install = currentQte % 10;
|
|
855
|
+
if (rest1480Install !== 0) {
|
|
856
|
+
newQte = currentQte - rest1480Install + 10;
|
|
857
|
+
}
|
|
858
|
+
break;
|
|
859
|
+
case currentQte >= 1480:
|
|
860
|
+
if (!!palUnit && !!palUnit.fitting_unit) {
|
|
861
|
+
let rest1480 = currentQte % palUnit.fitting_unit;
|
|
862
|
+
if (rest1480 !== 0 && !!((rest1480 - 400) % palUnit.fitting_unit)) {
|
|
863
|
+
newQte = currentQte - rest1480;
|
|
864
|
+
if (newQte + 400 > currentQte) {
|
|
865
|
+
newQte = newQte + 400;
|
|
866
|
+
}
|
|
867
|
+
else if (newQte + palUnit.fitting_unit > currentQte) {
|
|
868
|
+
newQte = newQte + palUnit.fitting_unit;
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
break;
|
|
873
|
+
}
|
|
874
|
+
return newQte;
|
|
875
|
+
};
|
|
876
|
+
exports.roundGrassQte = roundGrassQte;
|
|
877
|
+
/**
|
|
878
|
+
* Detects if customer has "Installation tout inclus".
|
|
879
|
+
* @param customPriceList - Customer custom price list
|
|
880
|
+
* @return All inclusive installation if exists, undefined otherwise
|
|
881
|
+
*/
|
|
882
|
+
const getInstallationAllInclusiveFromPriceList = (customPriceList) => {
|
|
883
|
+
if (!!!customPriceList || !!!customPriceList.length)
|
|
884
|
+
return;
|
|
885
|
+
const item = customPriceList.find((i) => i.sku === products_2.installationAllInclusiveSku);
|
|
886
|
+
const active = !!item && !!item.price;
|
|
887
|
+
if (!active)
|
|
888
|
+
return;
|
|
889
|
+
return item;
|
|
890
|
+
};
|
|
891
|
+
exports.getInstallationAllInclusiveFromPriceList = getInstallationAllInclusiveFromPriceList;
|
|
892
|
+
/**
|
|
893
|
+
* Checks if all-inclusive installation is active.
|
|
894
|
+
* @param hasInstallation - Whether the cart/form contains an installation
|
|
895
|
+
* @param isPro - Whether the customer is a pro
|
|
896
|
+
* @param customPriceList - Customer custom price list
|
|
897
|
+
* @returns true if all-inclusive installation is active
|
|
898
|
+
*/
|
|
899
|
+
const isInstallAllInclusiveActive = (hasInstallation, isPro, customPriceList) => {
|
|
900
|
+
return !!hasInstallation && !!isPro && !!(0, exports.getInstallationAllInclusiveFromPriceList)(customPriceList);
|
|
901
|
+
};
|
|
902
|
+
exports.isInstallAllInclusiveActive = isInstallAllInclusiveActive;
|
|
903
|
+
/**
|
|
904
|
+
* Force )$ to kentucky base grass and sod delivery fee if install all-inclusive.
|
|
905
|
+
* @param item - The cart item to potentially override
|
|
906
|
+
* @returns The item with zeroed price if applicable, or the original item
|
|
907
|
+
*/
|
|
908
|
+
const applyAllInclusiveOverrides = (item) => {
|
|
909
|
+
const isKentucky = item.parent_slug === 'kentucky' || item.sku === products_2.kentucky;
|
|
910
|
+
const isSodDelivery = item.parent_slug === 'livraison-gazon' && products_2.sodDeliverySkus.includes(item.sku);
|
|
911
|
+
if (isKentucky || isSodDelivery) {
|
|
912
|
+
return Object.assign(Object.assign({}, item), { regular_price: Object.assign(Object.assign({}, item.regular_price), { amount: 0 }), discount_price: null, promo_price: null, price_override: true });
|
|
913
|
+
}
|
|
914
|
+
return item;
|
|
915
|
+
};
|
|
916
|
+
exports.applyAllInclusiveOverrides = applyAllInclusiveOverrides;
|
|
917
|
+
// Determines if a cart item should be hidden from checkout display. Used for all-inclusive installation
|
|
918
|
+
const shouldHideItemInCheckout = (item, allItems) => {
|
|
919
|
+
const hasAllInclusive = allItems.some((i) => i.sku === products_2.installationAllInclusiveSku);
|
|
920
|
+
if (!hasAllInclusive)
|
|
921
|
+
return false;
|
|
922
|
+
if (item.regular_price.amount !== 0)
|
|
923
|
+
return false;
|
|
924
|
+
// Hide installation upsells at $0 (mobilisation, fertilisation, roulage, etc.)
|
|
925
|
+
const installationSkus = allItems.filter((i) => i.parent_slug === 'installation-gazon').map((i) => i.sku);
|
|
926
|
+
if (!!item.is_upsell_of_sku && installationSkus.includes(item.is_upsell_of_sku))
|
|
927
|
+
return true;
|
|
928
|
+
// Hide sod delivery at $0
|
|
929
|
+
if (item.parent_slug === 'livraison-gazon')
|
|
930
|
+
return true;
|
|
931
|
+
// Hide installation surcharges at $0 (e.g. surcharge mobilisation île de Montréal)
|
|
932
|
+
if (item.parent_slug === 'surcharges-installation-gazon')
|
|
933
|
+
return true;
|
|
934
|
+
return false;
|
|
935
|
+
};
|
|
936
|
+
exports.shouldHideItemInCheckout = shouldHideItemInCheckout;
|
|
937
|
+
// Check si la surcharge carburant match l'item
|
|
938
|
+
const matchesFuelSurchargeParent = (surchargeSku, item) => {
|
|
939
|
+
switch (surchargeSku) {
|
|
940
|
+
case products_2.fuelSurchargeGazonSku:
|
|
941
|
+
return item.sku === products_2.kentucky || item.parent_slug === 'kentucky';
|
|
942
|
+
case products_2.fuelSurchargeLivraisonSku:
|
|
943
|
+
return (!!item.parent_slug &&
|
|
944
|
+
['livraison-gazon', 'livraison-beton-accessoires'].includes(item.parent_slug));
|
|
945
|
+
case products_2.fuelSurchargeMobilisationSku:
|
|
946
|
+
return item.parent_slug === 'frais-de-mobilisation';
|
|
947
|
+
default:
|
|
948
|
+
return false;
|
|
949
|
+
}
|
|
950
|
+
};
|
|
951
|
+
exports.matchesFuelSurchargeParent = matchesFuelSurchargeParent;
|
|
952
|
+
const getInstallationArray = async (qte, baseGrassUpsells, fetchProduct, locale, isPro, chosenSku, customPriceList, returnOtherFees) => {
|
|
953
|
+
var _a;
|
|
954
|
+
const upsell = baseGrassUpsells;
|
|
955
|
+
if (!!!upsell)
|
|
956
|
+
return [];
|
|
957
|
+
const installation_upsell = upsell.filter((upsell) => upsell.recommendation_parent_slug === 'installation-gazon');
|
|
958
|
+
const installation_parent = await fetchProduct('installation-gazon', locale, true, true);
|
|
959
|
+
let installation_decli;
|
|
960
|
+
const minQteInstall = (0, expedition_1.getMinQteInstall)(isPro);
|
|
961
|
+
// Variable pour vérifier si une déclinaison d'installation existe déjà dans le cart
|
|
962
|
+
// ** Utile pour la modification des items du cart, vu que la props is_upsell_of_sku ne peut pas se modifier on update
|
|
963
|
+
let arrayFinal = [];
|
|
964
|
+
if (!!installation_parent && !!installation_upsell && !!installation_upsell.length) {
|
|
965
|
+
let installation_array = [];
|
|
966
|
+
if (!!isPro) {
|
|
967
|
+
installation_array = installation_parent.declinations.filter((decli) => !!decli.attributes &&
|
|
968
|
+
!!decli.attributes[data_1.AttributesIdEnumGR.CLIENT_TYPE] &&
|
|
969
|
+
!!decli.attributes[data_1.AttributesIdEnumGR.CLIENT_TYPE].includes('pro'));
|
|
970
|
+
}
|
|
971
|
+
else {
|
|
972
|
+
installation_array = installation_parent.declinations.filter((decli) => !!decli.attributes &&
|
|
973
|
+
!!decli.attributes[data_1.AttributesIdEnumGR.CLIENT_TYPE] &&
|
|
974
|
+
!!decli.attributes[data_1.AttributesIdEnumGR.CLIENT_TYPE].includes('au-detail'));
|
|
975
|
+
}
|
|
976
|
+
const installation_qte_array = installation_upsell.filter((upsell) => installation_array.find((decli) => decli.sku === upsell.recommendation_sku));
|
|
977
|
+
const closestQte = (0, maxBy_1.default)(installation_qte_array.filter((upsell) => {
|
|
978
|
+
return upsell.actual_qty <= qte;
|
|
979
|
+
}), 'actual_qty');
|
|
980
|
+
// MODIFS. FRAIS 2024 - On n'ajoute pas les frais au panier si leur prix régulier est de 0.00$
|
|
981
|
+
// Vérification faite à chaque ajout de déclinaison au arrayFinal
|
|
982
|
+
if (!!closestQte) {
|
|
983
|
+
installation_decli = installation_parent.declinations.find((decli) => decli.sku === closestQte.recommendation_sku);
|
|
984
|
+
// Check if customer has installation all-inclusive
|
|
985
|
+
const allInclusivePriceItem = !!isPro && !!customPriceList ? (0, exports.getInstallationAllInclusiveFromPriceList)(customPriceList) : undefined;
|
|
986
|
+
if (!!installation_decli) {
|
|
987
|
+
const allInclusiveDecli = !!allInclusivePriceItem && !!installation_parent
|
|
988
|
+
? installation_parent.declinations.find((d) => d.sku === allInclusivePriceItem.sku)
|
|
989
|
+
: undefined;
|
|
990
|
+
if (!!allInclusivePriceItem && !!allInclusiveDecli) {
|
|
991
|
+
const priceAmount = (_a = allInclusivePriceItem.price) !== null && _a !== void 0 ? _a : allInclusivePriceItem.reg;
|
|
992
|
+
installation_decli = Object.assign(Object.assign({}, allInclusiveDecli), { regular_price: Object.assign(Object.assign({}, allInclusiveDecli.regular_price), { amount: priceAmount }) });
|
|
993
|
+
}
|
|
994
|
+
else {
|
|
995
|
+
if (!!isPro && !!customPriceList) {
|
|
996
|
+
installation_decli = (0, g2_1.checkForCustomPriceEquivalent)(installation_decli, customPriceList);
|
|
997
|
+
}
|
|
998
|
+
}
|
|
999
|
+
// Add the correct installation option depending on whether the customer has "Installation tout inclus"
|
|
1000
|
+
if (!(0, exports.shouldHideItemIfRegPriceIs0)(installation_decli, installation_parent.slug)) {
|
|
1001
|
+
arrayFinal.push(Object.assign(Object.assign({}, installation_decli), { parent_slug: 'installation-gazon', qte: qte, is_upsell_of_sku: chosenSku, product_upsells: installation_parent.product_upsells }));
|
|
1002
|
+
}
|
|
1003
|
+
}
|
|
1004
|
+
// Frais minimum d'installation
|
|
1005
|
+
if (qte < minQteInstall) {
|
|
1006
|
+
const minimum_installation_fee = await fetchProduct('frais-minimum-gazon-pour-installation', locale, true, true);
|
|
1007
|
+
if (!!minimum_installation_fee) {
|
|
1008
|
+
let minInstallDecli = minimum_installation_fee.declinations[0];
|
|
1009
|
+
minInstallDecli = Object.assign(Object.assign({}, minInstallDecli), { regular_price: Object.assign(Object.assign({}, minInstallDecli.regular_price), { amount: installation_decli.regular_price.amount }) });
|
|
1010
|
+
if (!!isPro && !!customPriceList) {
|
|
1011
|
+
minInstallDecli = (0, g2_1.checkForCustomPriceEquivalent)(Object.assign(Object.assign({}, minInstallDecli), { price_override: true }), customPriceList);
|
|
1012
|
+
}
|
|
1013
|
+
if (!(0, exports.shouldHideItemIfRegPriceIs0)(minInstallDecli, minimum_installation_fee.slug)) {
|
|
1014
|
+
arrayFinal.push(Object.assign(Object.assign({}, minInstallDecli), { parent_slug: 'frais-minimum-gazon-pour-installation', qte: minQteInstall - qte, is_upsell_of_sku: installation_decli.sku, price_override: true }));
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
}
|
|
1018
|
+
// Frais de mobilisation (pour l'installation)
|
|
1019
|
+
const mobilisation_fee = await fetchProduct('frais-de-mobilisation', locale, true, true);
|
|
1020
|
+
if (!!mobilisation_fee && !!isPro) {
|
|
1021
|
+
let mobilisationDecli = mobilisation_fee.declinations[0];
|
|
1022
|
+
if (!!customPriceList) {
|
|
1023
|
+
mobilisationDecli = (0, g2_1.checkForCustomPriceEquivalent)(mobilisationDecli, customPriceList);
|
|
1024
|
+
}
|
|
1025
|
+
if (!(0, exports.shouldHideItemIfRegPriceIs0)(mobilisationDecli, mobilisation_fee.slug, true)) {
|
|
1026
|
+
arrayFinal.push(Object.assign(Object.assign({}, mobilisationDecli), { parent_slug: 'frais-de-mobilisation', qte: (0, ceil_1.default)(qte > minQteInstall
|
|
1027
|
+
? qte / (740 * expedition_1.installationFeePalletTier)
|
|
1028
|
+
: minQteInstall / (740 * expedition_1.installationFeePalletTier)), is_upsell_of_sku: installation_decli.sku, product_upsells: mobilisation_fee.product_upsells }));
|
|
1029
|
+
}
|
|
1030
|
+
}
|
|
1031
|
+
// -----------------------------------------------------------------------
|
|
1032
|
+
// AUTRES FRAIS CONNEXES
|
|
1033
|
+
if (!!returnOtherFees) {
|
|
1034
|
+
if (!!returnOtherFees.engrais) {
|
|
1035
|
+
// fertilisation
|
|
1036
|
+
const fertilisation = await fetchProduct('installation-fertilisation', locale, true, true);
|
|
1037
|
+
if (!!fertilisation) {
|
|
1038
|
+
let minFertilisationDecli = fertilisation.declinations[0];
|
|
1039
|
+
if (!!isPro && !!customPriceList) {
|
|
1040
|
+
minFertilisationDecli = (0, g2_1.checkForCustomPriceEquivalent)(minFertilisationDecli, customPriceList);
|
|
1041
|
+
}
|
|
1042
|
+
if (!(0, exports.shouldHideItemIfRegPriceIs0)(minFertilisationDecli, fertilisation.slug, true)) {
|
|
1043
|
+
arrayFinal.push(Object.assign(Object.assign({}, minFertilisationDecli), { parent_slug: fertilisation.slug, qte: qte < minQteInstall ? minQteInstall : qte, is_upsell_of_sku: installation_decli.sku, product_upsells: fertilisation.product_upsells }));
|
|
1044
|
+
}
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
if (returnOtherFees.roulage) {
|
|
1048
|
+
// roullage
|
|
1049
|
+
const roullage = await fetchProduct('installation-roulage', locale, true, true);
|
|
1050
|
+
if (!!roullage) {
|
|
1051
|
+
let minRoulageDecli = roullage.declinations[0];
|
|
1052
|
+
if (!!isPro && !!customPriceList) {
|
|
1053
|
+
minRoulageDecli = (0, g2_1.checkForCustomPriceEquivalent)(minRoulageDecli, customPriceList);
|
|
1054
|
+
}
|
|
1055
|
+
if (!(0, exports.shouldHideItemIfRegPriceIs0)(minRoulageDecli, roullage.slug, true)) {
|
|
1056
|
+
arrayFinal.push(Object.assign(Object.assign({}, minRoulageDecli), { parent_slug: roullage.slug, qte: qte < minQteInstall ? minQteInstall : qte, is_upsell_of_sku: installation_decli.sku, product_upsells: roullage.product_upsells }));
|
|
1057
|
+
}
|
|
1058
|
+
}
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
}
|
|
1062
|
+
}
|
|
1063
|
+
return arrayFinal;
|
|
1064
|
+
};
|
|
1065
|
+
exports.getInstallationArray = getInstallationArray;
|
|
1066
|
+
const getInstallItemPrice = (parentSlug, servicesFees) => {
|
|
1067
|
+
let price = 0;
|
|
1068
|
+
switch (parentSlug) {
|
|
1069
|
+
case 'installation-gazon':
|
|
1070
|
+
const itemsToUse = servicesFees.filter((i) => i.parent_slug && ['installation-gazon', 'frais-de-mobilisation'].includes(i.parent_slug));
|
|
1071
|
+
if (!!itemsToUse) {
|
|
1072
|
+
price = (0, sumBy_1.default)(itemsToUse, (item) => (0, products_1.getLowestPrice)(item).price.amount * item.qte);
|
|
1073
|
+
}
|
|
1074
|
+
break;
|
|
1075
|
+
default:
|
|
1076
|
+
const itemToUse = servicesFees.find((i) => i.parent_slug === parentSlug);
|
|
1077
|
+
if (!!itemToUse) {
|
|
1078
|
+
price = (0, products_1.getLowestPrice)(itemToUse).price.amount * itemToUse.qte;
|
|
1079
|
+
}
|
|
1080
|
+
break;
|
|
1081
|
+
}
|
|
1082
|
+
return price;
|
|
1083
|
+
};
|
|
1084
|
+
exports.getInstallItemPrice = getInstallItemPrice;
|
|
1085
|
+
// #endregion
|
|
1086
|
+
// ----------------------------------------------------------------------------------------------------------
|
|
1087
|
+
// ----------------------------------------------------------------------------------------------------------
|
|
1088
|
+
// #region CONCRETE
|
|
1089
|
+
const getConcreteQteText = (declination, locale = 'fr') => {
|
|
1090
|
+
let txt = '';
|
|
1091
|
+
if (!!!declination)
|
|
1092
|
+
return txt;
|
|
1093
|
+
let nbSaleUnitsPerCmdStep = 0;
|
|
1094
|
+
let nbUnitsPerPal = 0;
|
|
1095
|
+
const other_units = declination.other_units;
|
|
1096
|
+
if (!!!other_units || !!!other_units.length) {
|
|
1097
|
+
return '';
|
|
1098
|
+
}
|
|
1099
|
+
else {
|
|
1100
|
+
const commandStep = other_units.find((unit) => unit.is_command_step);
|
|
1101
|
+
const commandUnit = other_units.find((unit) => unit.is_command_unit);
|
|
1102
|
+
const saleUnit = other_units.find((unit) => unit.is_sale_unit);
|
|
1103
|
+
const unitsPerPal = other_units.find((unit) => unit.unit_slug === 'pal');
|
|
1104
|
+
if (!!commandStep &&
|
|
1105
|
+
!!commandStep.fitting_unit &&
|
|
1106
|
+
!!commandUnit &&
|
|
1107
|
+
!!commandUnit.fitting_unit &&
|
|
1108
|
+
!!saleUnit &&
|
|
1109
|
+
!!saleUnit.fitting_unit &&
|
|
1110
|
+
!!unitsPerPal &&
|
|
1111
|
+
!!unitsPerPal.fitting_unit) {
|
|
1112
|
+
const cmdSameAsSale = commandStep.unit_slug === saleUnit.unit_slug;
|
|
1113
|
+
const nbP2PerRgSlug = !!cmdSameAsSale ? commandUnit.unit_slug : saleUnit.unit_slug;
|
|
1114
|
+
nbSaleUnitsPerCmdStep = !!cmdSameAsSale
|
|
1115
|
+
? commandStep.fitting_unit / commandUnit.fitting_unit
|
|
1116
|
+
: commandStep.fitting_unit / saleUnit.fitting_unit;
|
|
1117
|
+
// Round at correct decimals for products where commandStep.fitting_unit is 1 (meaning value calculated before is correct sell units per step)
|
|
1118
|
+
nbUnitsPerPal =
|
|
1119
|
+
commandStep.fitting_unit == 1 && !!!commandStep.is_sale_unit
|
|
1120
|
+
? unitsPerPal.fitting_unit *
|
|
1121
|
+
(0, round_1.default)(nbSaleUnitsPerCmdStep, (0, exports.productUnitSupportsDecimals)(saleUnit.unit_slug) ? 5 : 0)
|
|
1122
|
+
: unitsPerPal.fitting_unit / saleUnit.fitting_unit;
|
|
1123
|
+
txt = (0, locale_1.translateILang)({
|
|
1124
|
+
fr: 'Pour ce produit, vous devez commander par *cmdStep* (*nbUnitsPerCmdStep*).',
|
|
1125
|
+
en: 'For this product, you have to order by *cmdStep* (*nbUnitsPerCmdStep*).'
|
|
1126
|
+
}, locale);
|
|
1127
|
+
if (unitsPerPal.unit_slug != commandStep.unit_slug) {
|
|
1128
|
+
txt += (0, locale_1.translateILang)({
|
|
1129
|
+
fr: ' Une palette = *nbUnitsPerPal*.',
|
|
1130
|
+
en: ' A pallet = *nbUnitsPerPal*.'
|
|
1131
|
+
}, locale);
|
|
1132
|
+
}
|
|
1133
|
+
txt = txt.replace('*cmdStep*', String(`${(0, locale_1.translateILang)(inventories_1.unitDict[commandStep.unit_slug], locale).toLowerCase()}`));
|
|
1134
|
+
txt = txt.replace('*nbUnitsPerCmdStep*', String(`${(0, round_1.default)(nbSaleUnitsPerCmdStep, 2)} ${(0, locale_1.translateILang)(inventories_1.unitDict[nbP2PerRgSlug], locale).toLowerCase()}`));
|
|
1135
|
+
txt = txt.replace('*nbUnitsPerPal*', String(`${(0, round_1.default)(nbUnitsPerPal, 2)} ${(0, locale_1.translateILang)(inventories_1.unitDict[saleUnit.unit_slug], locale).toLowerCase()}`));
|
|
1136
|
+
}
|
|
1137
|
+
else {
|
|
1138
|
+
return '';
|
|
1139
|
+
}
|
|
1140
|
+
}
|
|
1141
|
+
return txt;
|
|
1142
|
+
};
|
|
1143
|
+
exports.getConcreteQteText = getConcreteQteText;
|
|
1144
|
+
/**
|
|
1145
|
+
* @description returns all items in cart where attribute AVAILABILITY contains wanted type.
|
|
1146
|
+
* @param cartData
|
|
1147
|
+
* @param availabilityType
|
|
1148
|
+
*/
|
|
1149
|
+
const getConcreteItemsByAvailability = (cartData, availabilityType, returnTrueIfUndefined) => {
|
|
1150
|
+
return cartData.items.filter((i) => {
|
|
1151
|
+
return ((i.attributes[data_1.AttributesIdEnumGR.AVAILABILITY] &&
|
|
1152
|
+
i.attributes[data_1.AttributesIdEnumGR.AVAILABILITY][0] === availabilityType) ||
|
|
1153
|
+
!!returnTrueIfUndefined);
|
|
1154
|
+
});
|
|
1155
|
+
};
|
|
1156
|
+
exports.getConcreteItemsByAvailability = getConcreteItemsByAvailability;
|
|
1157
|
+
// #endregion
|
|
1158
|
+
// ----------------------------------------------------------------------------------------------------------
|
|
1159
|
+
// ----------------------------------------------------------------------------------------------------------
|
|
1160
|
+
// #region VRAC
|
|
1161
|
+
/**
|
|
1162
|
+
* Function getVracType - constructs vrac helper object is cart contains vrac or vrac associated items.
|
|
1163
|
+
* @param stores
|
|
1164
|
+
* @param cartData
|
|
1165
|
+
* @param getInventoryItemCallback
|
|
1166
|
+
* @param inventoryItemArray
|
|
1167
|
+
* @returns IVracType object containing vrac_type enum value and vrac_store_ids where vrac items are available
|
|
1168
|
+
*/
|
|
1169
|
+
const getVracType = async (stores, cartData, getInventoryItemCallback, inventoyItemArray) => {
|
|
1170
|
+
const items = cartData.items;
|
|
1171
|
+
// If cart does not contain vrac or vrac-agacent accessories (.is_other_type==='vrac)), return
|
|
1172
|
+
if (!!!items ||
|
|
1173
|
+
!!!items.length ||
|
|
1174
|
+
(!!!(0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.VRAC, cartData) &&
|
|
1175
|
+
!!!cartData.items.find((item) => !!item.is_other_type && item.is_other_type === 'vrac')))
|
|
1176
|
+
return;
|
|
1177
|
+
let allStoreIds = stores.map((store) => store.id);
|
|
1178
|
+
let itemFormat = '';
|
|
1179
|
+
await Promise.all(items.map(async (item) => {
|
|
1180
|
+
const productInventory = !!!item.is_service
|
|
1181
|
+
? !!inventoyItemArray && !!inventoyItemArray.length
|
|
1182
|
+
? inventoyItemArray.find((i) => i.sku === item.sku)
|
|
1183
|
+
: await getInventoryItemCallback(item.sku)
|
|
1184
|
+
: undefined;
|
|
1185
|
+
if (!!!productInventory)
|
|
1186
|
+
return;
|
|
1187
|
+
allStoreIds = allStoreIds.filter((id) => {
|
|
1188
|
+
const sameStoreInProdInventory = productInventory.inventories.find((i) => i.store_id === id);
|
|
1189
|
+
if (!!!sameStoreInProdInventory)
|
|
1190
|
+
return true;
|
|
1191
|
+
return !!!sameStoreInProdInventory.unavailable_in_store;
|
|
1192
|
+
});
|
|
1193
|
+
if (!!!itemFormat && !!item.attributes && !!item.attributes[data_1.AttributesIdEnumGR.FORMATS]) {
|
|
1194
|
+
itemFormat = item.attributes[data_1.AttributesIdEnumGR.FORMATS][0];
|
|
1195
|
+
}
|
|
1196
|
+
}));
|
|
1197
|
+
const onlySteJulieNobel = allStoreIds.length === 1 && allStoreIds[0] === 'sainte-julie-nobel';
|
|
1198
|
+
if (!!itemFormat.includes('sac')) {
|
|
1199
|
+
return {
|
|
1200
|
+
vrac_type: !!onlySteJulieNobel ? products_3.VracTypeEnum.NOBEL_SAC : products_3.VracTypeEnum.AUTRE_SAC,
|
|
1201
|
+
vrac_store_ids: allStoreIds
|
|
1202
|
+
};
|
|
1203
|
+
}
|
|
1204
|
+
else {
|
|
1205
|
+
return {
|
|
1206
|
+
vrac_type: !!onlySteJulieNobel ? products_3.VracTypeEnum.NOBEL_TONNE : products_3.VracTypeEnum.AUTRE_TONNE,
|
|
1207
|
+
vrac_store_ids: allStoreIds
|
|
1208
|
+
};
|
|
1209
|
+
}
|
|
1210
|
+
};
|
|
1211
|
+
exports.getVracType = getVracType;
|
|
1212
|
+
// #endregion
|
|
1213
|
+
// ----------------------------------------------------------------------------------------------------------
|
|
1214
|
+
// ----------------------------------------------------------------------------------------------------------
|
|
1215
|
+
// #region FEES
|
|
1216
|
+
/**
|
|
1217
|
+
* Get all possible fees for a cart with basic info, to show approx. fee total before all data is saved in cart
|
|
1218
|
+
*
|
|
1219
|
+
* @param useFees If local fee array should be used, to save database calls
|
|
1220
|
+
* @param newCart Current cart data
|
|
1221
|
+
* @param deliveryType If fees should be checked for a pick-up or shipping order
|
|
1222
|
+
* @param fetchProduct Callback function for product fetch
|
|
1223
|
+
* @param getIfAddressIsInsideZones Callback function for zone check
|
|
1224
|
+
* @param getDistanceFromAddress Callback function to check distance with provided address
|
|
1225
|
+
* @param locale User's locale (fr or en)
|
|
1226
|
+
* @param allStores Full store array for space
|
|
1227
|
+
* @param isPro If customer associated with cart is a pro customer
|
|
1228
|
+
* @param grassProduct Constructed grass product from cart (with extra data for checks)
|
|
1229
|
+
* @param concreteOrder Constructed concrete products from cart (with extra data for checks)
|
|
1230
|
+
* @param settings.addOnePalletToPickup Optionnal - If additionnal pal. should be added for order
|
|
1231
|
+
* @param settings.saveToShippingPayload Optional - If data collected should be saved to cart's shipping_payload
|
|
1232
|
+
* @param settings.useStoreAddress Optionnal - Provided store ID for which the address should be used for check
|
|
1233
|
+
* @param settings.useDeliveryAddress Optionnal - If current carts shipping address should be used for check
|
|
1234
|
+
* @param settings.useAvailableVracStores Optionnal - Provided array of store IDs available for vrac order
|
|
1235
|
+
* @param customPriceList Optionnal - If pro customer with G2 custom price list and custom prices should be checked
|
|
1236
|
+
*/
|
|
1237
|
+
const fetchFeesBeforeCart = async (useFees, newCart, deliveryType, fetchProduct, getIfAddressIsInsideZones, getDistanceFromAddress, locale, allStores, isPro, grassProduct, concreteOrder, settings, customPriceList) => {
|
|
1238
|
+
const cartContainsVrac = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.VRAC, newCart);
|
|
1239
|
+
const cartContainsInstallation = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.INSTALLATION, newCart);
|
|
1240
|
+
const cartContainsSample = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.SAMPLE, newCart);
|
|
1241
|
+
const cartContainsAccessoriesOnly = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.ONLY_ACCESSORIES, newCart);
|
|
1242
|
+
const storeToUse = !!settings && !!settings.useStoreAddress ? allStores.find((s) => s.id == settings.useStoreAddress) : undefined;
|
|
1243
|
+
const storeAddressToUse = !!storeToUse ? storeToUse.address : undefined;
|
|
1244
|
+
return await (0, expedition_1.applyFeesToCart)(fetchProduct, getIfAddressIsInsideZones, getDistanceFromAddress, newCart, deliveryType, grassProduct, concreteOrder, deliveryType === 'pickup' ? false : cartContainsInstallation, cartContainsVrac, (0, object_1.recursiveCheckObject)(settings, 'useAvailableVracStores'), isPro, deliveryType === 'pickup' ? !!settings && !!settings.addOnePalletToPickup : false, cartContainsSample, !!settings ? !!settings.saveToShippingPayload : false, !!!settings
|
|
1245
|
+
? undefined
|
|
1246
|
+
: !!settings.useStoreAddress && !!storeAddressToUse
|
|
1247
|
+
? storeAddressToUse
|
|
1248
|
+
: !!settings.useDeliveryAddress && !!newCart.shipping_address
|
|
1249
|
+
? newCart.shipping_address.address
|
|
1250
|
+
: undefined, locale, undefined, false, cartContainsAccessoriesOnly, undefined, allStores, customPriceList, !!useFees);
|
|
1251
|
+
};
|
|
1252
|
+
exports.fetchFeesBeforeCart = fetchFeesBeforeCart;
|
|
1253
|
+
// #endregion
|
|
1254
|
+
// ----------------------------------------------------------------------------------------------------------
|
|
1255
|
+
// ----------------------------------------------------------------------------------------------------------
|
|
1256
|
+
// #region PRO SPECIFICITIES
|
|
1257
|
+
/**
|
|
1258
|
+
* Check if pro custom promo info should be shown for customer for a specific product.
|
|
1259
|
+
* @param userData
|
|
1260
|
+
* @param isPro
|
|
1261
|
+
* @param product
|
|
1262
|
+
* @param customMinPrice
|
|
1263
|
+
*/
|
|
1264
|
+
const shouldShowProCustomPromo = (userData, isPro, product, customMinPrice) => {
|
|
1265
|
+
if (!!!product || !!!isPro || !!!userData)
|
|
1266
|
+
return false;
|
|
1267
|
+
// If customMinPrice is defined (meaning customer has custom price list), and the price type is not REG or has type NET, always return true
|
|
1268
|
+
if (!!customMinPrice) {
|
|
1269
|
+
if (customMinPrice.type === G2_1.CustomPriceItemTypeEnum.REG && customMinPrice.code2 !== 'NET')
|
|
1270
|
+
return false;
|
|
1271
|
+
return true;
|
|
1272
|
+
}
|
|
1273
|
+
// Check customer group. If promo exists and should apply for customer group, return true
|
|
1274
|
+
const customerGroup = (0, object_1.recursiveCheckObject)(userData, 'userData.basic_info.customer_professionnal_info.external_customer_group');
|
|
1275
|
+
const customerType = !!customerGroup ? (0, g2_1.getG2CustomerTypeFromCode)(customerGroup) : undefined;
|
|
1276
|
+
const prodPriceClass = !!product.price_classes_range
|
|
1277
|
+
? product.price_classes_range.find((range) => !!customerType && range.external_slug ? range.external_slug === customerType : range.class === 'aspirant')
|
|
1278
|
+
: !!product.prices_list
|
|
1279
|
+
? product.prices_list.find((range) => !!customerType && range.external_slug ? range.external_slug === customerType : range.group_id === 'aspirant')
|
|
1280
|
+
: undefined;
|
|
1281
|
+
return !!prodPriceClass && !!prodPriceClass.custom_promo_applies;
|
|
1282
|
+
};
|
|
1283
|
+
exports.shouldShowProCustomPromo = shouldShowProCustomPromo;
|
|
1284
|
+
const applyProCustomPromo = (decli, userData) => {
|
|
1285
|
+
const customerCode = userData.basic_info.customer_professionnal_info &&
|
|
1286
|
+
userData.basic_info.customer_professionnal_info.external_customer_group;
|
|
1287
|
+
if (!!!customerCode)
|
|
1288
|
+
return {};
|
|
1289
|
+
const customerCustomPromo = (0, g2_1.getG2DiscountFromCode)(customerCode);
|
|
1290
|
+
if (!!!customerCustomPromo)
|
|
1291
|
+
return {};
|
|
1292
|
+
const regPrice = decli.regular_price.amount;
|
|
1293
|
+
const newDiscountAmount = (0, toNumber_1.default)(regPrice) * ((100 - customerCustomPromo) / 100);
|
|
1294
|
+
let newPromoObj = (0, IDiscountRule_1.getDefaultDiscountRule)('product');
|
|
1295
|
+
newPromoObj = Object.assign(Object.assign({}, newPromoObj), { appliesTo: Object.assign(Object.assign({}, newPromoObj.appliesTo), { label: IDiscountRule_1.AppliesToEnum.PRODUCT, value: decli.sku }), rules: [
|
|
1296
|
+
{
|
|
1297
|
+
field: IDiscountRule_1.RuleFieldEnum.CUSTOMER,
|
|
1298
|
+
condition: IDiscountRule_1.RuleConditionEnum.AND,
|
|
1299
|
+
ruleDetails: [
|
|
1300
|
+
{
|
|
1301
|
+
operator: '==',
|
|
1302
|
+
value: [userData.id],
|
|
1303
|
+
condition: IDiscountRule_1.RuleConditionEnum.AND
|
|
1304
|
+
}
|
|
1305
|
+
]
|
|
1306
|
+
}
|
|
1307
|
+
], result: {
|
|
1308
|
+
action: IDiscountRule_1.ResultActionEnum.PERCENT,
|
|
1309
|
+
action_value: customerCustomPromo
|
|
1310
|
+
} });
|
|
1311
|
+
return {
|
|
1312
|
+
discount_rules: [newPromoObj],
|
|
1313
|
+
promo_price: {
|
|
1314
|
+
currency: 'CAD',
|
|
1315
|
+
amount: (0, round_1.default)(newDiscountAmount, 3)
|
|
1316
|
+
}
|
|
1317
|
+
};
|
|
1318
|
+
};
|
|
1319
|
+
exports.applyProCustomPromo = applyProCustomPromo;
|
|
1320
|
+
// Indexed products - Custom prices if pro
|
|
1321
|
+
const getFormattedProdGR = (decli, productSlug, isPro) => {
|
|
1322
|
+
const { promo_price, discount_price, tier_pricing } = decli, rest = __rest(decli, ["promo_price", "discount_price", "tier_pricing"]);
|
|
1323
|
+
return !!isPro ? Object.assign(Object.assign({}, rest), (productSlug !== 'kentucky' ? { tier_pricing } : {})) : decli;
|
|
1324
|
+
};
|
|
1325
|
+
exports.getFormattedProdGR = getFormattedProdGR;
|
|
1326
|
+
/**
|
|
1327
|
+
* Checks if a 0.00$ reg_price item should be considered "hidden" or not.
|
|
1328
|
+
* @param item - The indexedDecli or cartItem to check
|
|
1329
|
+
* @param productSlug - The parent product's slug (in case it is not found in item)
|
|
1330
|
+
* @param isUpsellOfInstallProd - Optionnal. If item is upsell of install product (additionnal fee for installation)
|
|
1331
|
+
*/
|
|
1332
|
+
const shouldHideItemIfRegPriceIs0 = (item, productSlug, isUpsellOfInstallProd) => {
|
|
1333
|
+
// A. Check if reg price is 0. If not, should not hide item
|
|
1334
|
+
const regPriceIs0 = item.regular_price.amount == 0;
|
|
1335
|
+
if (!regPriceIs0)
|
|
1336
|
+
return false;
|
|
1337
|
+
// B. Check if item is fee or service. If not, should not hide item
|
|
1338
|
+
if (!item.is_service)
|
|
1339
|
+
return false;
|
|
1340
|
+
// C. Check if item is an upsell of an installation product (additionnal install fees). If so, should not hide item
|
|
1341
|
+
if (!!isUpsellOfInstallProd)
|
|
1342
|
+
return false;
|
|
1343
|
+
// D. Check if item is a shipping fee. If so, should not hide item
|
|
1344
|
+
if (expedition_1.slugsToCheckFromExpeditionFees.shipping.includes(productSlug))
|
|
1345
|
+
return false;
|
|
1346
|
+
return true;
|
|
1347
|
+
};
|
|
1348
|
+
exports.shouldHideItemIfRegPriceIs0 = shouldHideItemIfRegPriceIs0;
|
|
1349
|
+
// #endregion
|
|
1350
|
+
// ----------------------------------------------------------------------------------------------------------
|
|
1351
1351
|
//# sourceMappingURL=products.js.map
|