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.
Files changed (575) hide show
  1. package/.babelrc +17 -17
  2. package/.claude/settings.local.json +7 -0
  3. package/.env +14 -0
  4. package/.env.dev +14 -14
  5. package/.github/workflows/run_unit_test.yaml +48 -48
  6. package/addio-sdk-doc.md +1473 -1473
  7. package/changelog.md +564 -564
  8. package/dist/Interfaces/Address/index.d.ts +21 -21
  9. package/dist/Interfaces/Address/index.js +16 -16
  10. package/dist/Interfaces/Algolia/index.d.ts +177 -177
  11. package/dist/Interfaces/Algolia/index.js +2 -2
  12. package/dist/Interfaces/Attachement/index.d.ts +5 -5
  13. package/dist/Interfaces/Attachement/index.js +2 -2
  14. package/dist/Interfaces/Attribute/index.d.ts +53 -53
  15. package/dist/Interfaces/Attribute/index.js +10 -10
  16. package/dist/Interfaces/BGJob/index.d.ts +56 -56
  17. package/dist/Interfaces/BGJob/index.js +25 -25
  18. package/dist/Interfaces/BaseClass/index.d.ts +8 -8
  19. package/dist/Interfaces/BaseClass/index.js +2 -2
  20. package/dist/Interfaces/Blog/IBlogArticle.d.ts +18 -18
  21. package/dist/Interfaces/Blog/IBlogArticle.js +2 -2
  22. package/dist/Interfaces/Blog/IBlogAuthor.d.ts +7 -7
  23. package/dist/Interfaces/Blog/IBlogAuthor.js +2 -2
  24. package/dist/Interfaces/Blog/IBlogCategory.d.ts +9 -9
  25. package/dist/Interfaces/Blog/IBlogCategory.js +2 -2
  26. package/dist/Interfaces/Blog/IBlogComment.d.ts +13 -13
  27. package/dist/Interfaces/Blog/IBlogComment.js +2 -2
  28. package/dist/Interfaces/Blog/IBlogKeywords.d.ts +9 -9
  29. package/dist/Interfaces/Blog/IBlogKeywords.js +2 -2
  30. package/dist/Interfaces/Booking/index.d.ts +74 -74
  31. package/dist/Interfaces/Booking/index.js +17 -17
  32. package/dist/Interfaces/Brand/index.d.ts +15 -15
  33. package/dist/Interfaces/Brand/index.js +2 -2
  34. package/dist/Interfaces/CMS/index.d.ts +28 -28
  35. package/dist/Interfaces/CMS/index.js +5 -5
  36. package/dist/Interfaces/Cart/IElavonPayload.d.ts +93 -93
  37. package/dist/Interfaces/Cart/IElavonPayload.js +17 -17
  38. package/dist/Interfaces/Cart/IPandaPayload.d.ts +64 -64
  39. package/dist/Interfaces/Cart/IPandaPayload.js +18 -18
  40. package/dist/Interfaces/Cart/IPaymentCard.d.ts +22 -22
  41. package/dist/Interfaces/Cart/IPaymentCard.js +44 -44
  42. package/dist/Interfaces/Cart/IPaypalPayload.d.ts +9 -9
  43. package/dist/Interfaces/Cart/IPaypalPayload.js +2 -2
  44. package/dist/Interfaces/Cart/IPaysafePayload.d.ts +72 -72
  45. package/dist/Interfaces/Cart/IPaysafePayload.js +2 -2
  46. package/dist/Interfaces/Cart/IStripePayload.d.ts +66 -66
  47. package/dist/Interfaces/Cart/IStripePayload.js +2 -2
  48. package/dist/Interfaces/Cart/index.d.ts +444 -444
  49. package/dist/Interfaces/Cart/index.js +197 -197
  50. package/dist/Interfaces/CartReservedQuantities/index.d.ts +10 -10
  51. package/dist/Interfaces/CartReservedQuantities/index.js +2 -2
  52. package/dist/Interfaces/CashDrawers/index.d.ts +37 -37
  53. package/dist/Interfaces/CashDrawers/index.js +19 -19
  54. package/dist/Interfaces/Catalogue/index.d.ts +68 -68
  55. package/dist/Interfaces/Catalogue/index.js +37 -37
  56. package/dist/Interfaces/Category/index.d.ts +33 -33
  57. package/dist/Interfaces/Category/index.js +2 -2
  58. package/dist/Interfaces/Chart/index.d.ts +11 -11
  59. package/dist/Interfaces/Chart/index.js +2 -2
  60. package/dist/Interfaces/Class/index.d.ts +8 -8
  61. package/dist/Interfaces/Class/index.js +2 -2
  62. package/dist/Interfaces/Consent/index.d.ts +6 -6
  63. package/dist/Interfaces/Consent/index.js +2 -2
  64. package/dist/Interfaces/Context/IContextProps.d.ts +4 -4
  65. package/dist/Interfaces/Context/IContextProps.js +2 -2
  66. package/dist/Interfaces/Context/IContextState.d.ts +15 -15
  67. package/dist/Interfaces/Context/IContextState.js +2 -2
  68. package/dist/Interfaces/Customer/ICustomerBadge.d.ts +2 -2
  69. package/dist/Interfaces/Customer/ICustomerBadge.js +2 -2
  70. package/dist/Interfaces/Customer/ICustomerRating.d.ts +10 -10
  71. package/dist/Interfaces/Customer/ICustomerRating.js +2 -2
  72. package/dist/Interfaces/Customer/IStoreCredit.d.ts +13 -13
  73. package/dist/Interfaces/Customer/IStoreCredit.js +2 -2
  74. package/dist/Interfaces/Customer/index.d.ts +104 -104
  75. package/dist/Interfaces/Customer/index.js +148 -148
  76. package/dist/Interfaces/Declination/index.d.ts +117 -117
  77. package/dist/Interfaces/Declination/index.js +66 -66
  78. package/dist/Interfaces/Document/index.d.ts +8 -8
  79. package/dist/Interfaces/Document/index.js +2 -2
  80. package/dist/Interfaces/Elastic/index.d.ts +89 -89
  81. package/dist/Interfaces/Elastic/index.js +2 -2
  82. package/dist/Interfaces/Email/CustomGR/I3DPrintEmail.d.ts +11 -11
  83. package/dist/Interfaces/Email/CustomGR/I3DPrintEmail.js +2 -2
  84. package/dist/Interfaces/Email/CustomGR/IBorrowToolsEmail.d.ts +15 -15
  85. package/dist/Interfaces/Email/CustomGR/IBorrowToolsEmail.js +2 -2
  86. package/dist/Interfaces/Email/CustomGR/IPickupMaterialsEmail.d.ts +12 -12
  87. package/dist/Interfaces/Email/CustomGR/IPickupMaterialsEmail.js +2 -2
  88. package/dist/Interfaces/Email/CustomGR/IPreMeetingFormEmail.d.ts +36 -36
  89. package/dist/Interfaces/Email/CustomGR/IPreMeetingFormEmail.js +2 -2
  90. package/dist/Interfaces/Email/CustomGR/ISponsorRequestEmail.d.ts +12 -12
  91. package/dist/Interfaces/Email/CustomGR/ISponsorRequestEmail.js +2 -2
  92. package/dist/Interfaces/Email/CustomGR/ITransportEmail.d.ts +12 -12
  93. package/dist/Interfaces/Email/CustomGR/ITransportEmail.js +2 -2
  94. package/dist/Interfaces/Email/CustomGR/ITransportQuoteEmail.d.ts +12 -12
  95. package/dist/Interfaces/Email/CustomGR/ITransportQuoteEmail.js +2 -2
  96. package/dist/Interfaces/Email/CustomGR/IVegetalsEmail.d.ts +16 -16
  97. package/dist/Interfaces/Email/CustomGR/IVegetalsEmail.js +2 -2
  98. package/dist/Interfaces/Email/CustomGR/IWishlistEmail.d.ts +15 -15
  99. package/dist/Interfaces/Email/CustomGR/IWishlistEmail.js +2 -2
  100. package/dist/Interfaces/Email/IAbandonnedCartEmail.d.ts +29 -29
  101. package/dist/Interfaces/Email/IAbandonnedCartEmail.js +2 -2
  102. package/dist/Interfaces/Email/IAccountConfirmationEmail.d.ts +22 -22
  103. package/dist/Interfaces/Email/IAccountConfirmationEmail.js +2 -2
  104. package/dist/Interfaces/Email/IApplicationEmail.d.ts +19 -19
  105. package/dist/Interfaces/Email/IApplicationEmail.js +2 -2
  106. package/dist/Interfaces/Email/IBackInStockEmail.d.ts +21 -21
  107. package/dist/Interfaces/Email/IBackInStockEmail.js +2 -2
  108. package/dist/Interfaces/Email/IContactEmail.d.ts +20 -20
  109. package/dist/Interfaces/Email/IContactEmail.js +2 -2
  110. package/dist/Interfaces/Email/ICustomerBookingAdminEmail.d.ts +15 -15
  111. package/dist/Interfaces/Email/ICustomerBookingAdminEmail.js +2 -2
  112. package/dist/Interfaces/Email/ICustomerBookingEmail.d.ts +14 -14
  113. package/dist/Interfaces/Email/ICustomerBookingEmail.js +2 -2
  114. package/dist/Interfaces/Email/IEmail.d.ts +20 -20
  115. package/dist/Interfaces/Email/IEmail.js +60 -60
  116. package/dist/Interfaces/Email/IOrderConfirmationEmail.d.ts +47 -47
  117. package/dist/Interfaces/Email/IOrderConfirmationEmail.js +2 -2
  118. package/dist/Interfaces/Email/IPasswordResetEmail.d.ts +17 -17
  119. package/dist/Interfaces/Email/IPasswordResetEmail.js +2 -2
  120. package/dist/Interfaces/Email/IPhotoShootEmail.d.ts +14 -14
  121. package/dist/Interfaces/Email/IPhotoShootEmail.js +2 -2
  122. package/dist/Interfaces/Email/IPickupConfirmation.d.ts +23 -23
  123. package/dist/Interfaces/Email/IPickupConfirmation.js +2 -2
  124. package/dist/Interfaces/Email/IShippingConfirmation.d.ts +23 -23
  125. package/dist/Interfaces/Email/IShippingConfirmation.js +2 -2
  126. package/dist/Interfaces/Email/IWelcomeEmail.d.ts +19 -19
  127. package/dist/Interfaces/Email/IWelcomeEmail.js +2 -2
  128. package/dist/Interfaces/ExportSchema/index.d.ts +7 -7
  129. package/dist/Interfaces/ExportSchema/index.js +2 -2
  130. package/dist/Interfaces/ExternalService/BaseExternalService.d.ts +12 -12
  131. package/dist/Interfaces/ExternalService/BaseExternalService.js +2 -2
  132. package/dist/Interfaces/ExternalService/ExternalProductsService.d.ts +4 -4
  133. package/dist/Interfaces/ExternalService/ExternalProductsService.js +2 -2
  134. package/dist/Interfaces/ExternalService/index.d.ts +9 -9
  135. package/dist/Interfaces/ExternalService/index.js +2 -2
  136. package/dist/Interfaces/FirstOrderTracking/index.d.ts +5 -5
  137. package/dist/Interfaces/FirstOrderTracking/index.js +2 -2
  138. package/dist/Interfaces/G2/index.d.ts +556 -556
  139. package/dist/Interfaces/G2/index.js +38 -38
  140. package/dist/Interfaces/Indexed/Product/IIndexedLastSavedProduct.d.ts +20 -20
  141. package/dist/Interfaces/Indexed/Product/IIndexedLastSavedProduct.js +2 -2
  142. package/dist/Interfaces/Indexed/Product/index.d.ts +105 -105
  143. package/dist/Interfaces/Indexed/Product/index.js +253 -253
  144. package/dist/Interfaces/Inventory/index.d.ts +19 -19
  145. package/dist/Interfaces/Inventory/index.js +8 -8
  146. package/dist/Interfaces/Invoice/index.d.ts +4 -4
  147. package/dist/Interfaces/Invoice/index.js +2 -2
  148. package/dist/Interfaces/MarketplacePublication/MarketplaceOrderData.d.ts +3 -3
  149. package/dist/Interfaces/MarketplacePublication/MarketplaceOrderData.js +2 -2
  150. package/dist/Interfaces/MarketplacePublication/index.d.ts +23 -23
  151. package/dist/Interfaces/MarketplacePublication/index.js +22 -22
  152. package/dist/Interfaces/Menu/index.d.ts +40 -40
  153. package/dist/Interfaces/Menu/index.js +16 -16
  154. package/dist/Interfaces/Note/index.d.ts +10 -10
  155. package/dist/Interfaces/Note/index.js +7 -7
  156. package/dist/Interfaces/Operations/ICreatedBy.d.ts +6 -6
  157. package/dist/Interfaces/Operations/ICreatedBy.js +2 -2
  158. package/dist/Interfaces/Operations/IUpdate.d.ts +5 -5
  159. package/dist/Interfaces/Operations/IUpdate.js +2 -2
  160. package/dist/Interfaces/Order/index.d.ts +4 -4
  161. package/dist/Interfaces/Order/index.js +2 -2
  162. package/dist/Interfaces/Org/IRelUser.d.ts +9 -9
  163. package/dist/Interfaces/Org/IRelUser.js +2 -2
  164. package/dist/Interfaces/Org/index.d.ts +29 -29
  165. package/dist/Interfaces/Org/index.js +12 -12
  166. package/dist/Interfaces/Payment/index.d.ts +26 -26
  167. package/dist/Interfaces/Payment/index.js +14 -14
  168. package/dist/Interfaces/Product/IAttributeFamily.d.ts +6 -6
  169. package/dist/Interfaces/Product/IAttributeFamily.js +2 -2
  170. package/dist/Interfaces/Product/IImportProduct.d.ts +42 -42
  171. package/dist/Interfaces/Product/IImportProduct.js +882 -882
  172. package/dist/Interfaces/Product/IInventoryItem.d.ts +74 -74
  173. package/dist/Interfaces/Product/IInventoryItem.js +38 -38
  174. package/dist/Interfaces/Product/IPricing.d.ts +177 -177
  175. package/dist/Interfaces/Product/IPricing.js +180 -180
  176. package/dist/Interfaces/Product/index.d.ts +138 -138
  177. package/dist/Interfaces/Product/index.js +64 -64
  178. package/dist/Interfaces/ProductAttribute/index.d.ts +11 -11
  179. package/dist/Interfaces/ProductAttribute/index.js +2 -2
  180. package/dist/Interfaces/PromiseToPurchase/BankType.d.ts +41 -41
  181. package/dist/Interfaces/PromiseToPurchase/BankType.js +41 -41
  182. package/dist/Interfaces/PromiseToPurchase/IIndexedBankUsed.d.ts +33 -33
  183. package/dist/Interfaces/PromiseToPurchase/IIndexedBankUsed.js +15 -15
  184. package/dist/Interfaces/PromiseToPurchase/IIndexedCustomerPromiseToPurchase.d.ts +19 -19
  185. package/dist/Interfaces/PromiseToPurchase/IIndexedCustomerPromiseToPurchase.js +2 -2
  186. package/dist/Interfaces/PromiseToPurchase/index.d.ts +50 -50
  187. package/dist/Interfaces/PromiseToPurchase/index.js +13 -13
  188. package/dist/Interfaces/PurchaseOrder/index.d.ts +17 -17
  189. package/dist/Interfaces/PurchaseOrder/index.js +2 -2
  190. package/dist/Interfaces/Query/IBrandQueryOptions.d.ts +11 -11
  191. package/dist/Interfaces/Query/IBrandQueryOptions.js +2 -2
  192. package/dist/Interfaces/Query/ICategoryQueryOptions.d.ts +11 -11
  193. package/dist/Interfaces/Query/ICategoryQueryOptions.js +2 -2
  194. package/dist/Interfaces/Query/IProductQueryOptions.d.ts +16 -16
  195. package/dist/Interfaces/Query/IProductQueryOptions.js +2 -2
  196. package/dist/Interfaces/Quote/index.d.ts +5 -5
  197. package/dist/Interfaces/Quote/index.js +2 -2
  198. package/dist/Interfaces/Refunds/index.d.ts +106 -106
  199. package/dist/Interfaces/Refunds/index.js +2 -2
  200. package/dist/Interfaces/Rules/IDiscountRule.d.ts +155 -155
  201. package/dist/Interfaces/Rules/IDiscountRule.js +114 -114
  202. package/dist/Interfaces/Schedule/index.d.ts +48 -48
  203. package/dist/Interfaces/Schedule/index.js +2 -2
  204. package/dist/Interfaces/Services/IAddServiceResponse.d.ts +4 -4
  205. package/dist/Interfaces/Services/IAddServiceResponse.js +2 -2
  206. package/dist/Interfaces/Services/IService.d.ts +16 -16
  207. package/dist/Interfaces/Services/IService.js +2 -2
  208. package/dist/Interfaces/Services/IServiceSecret.d.ts +8 -8
  209. package/dist/Interfaces/Services/IServiceSecret.js +2 -2
  210. package/dist/Interfaces/Shipping/Shipstation/carriers.d.ts +10 -10
  211. package/dist/Interfaces/Shipping/Shipstation/carriers.js +2 -2
  212. package/dist/Interfaces/Shipping/Shipstation/order.d.ts +227 -227
  213. package/dist/Interfaces/Shipping/Shipstation/order.js +2 -2
  214. package/dist/Interfaces/Shipping/Shipstation/quote.d.ts +31 -31
  215. package/dist/Interfaces/Shipping/Shipstation/quote.js +2 -2
  216. package/dist/Interfaces/Shipping/Shiptime/order.d.ts +54 -54
  217. package/dist/Interfaces/Shipping/Shiptime/order.js +71 -71
  218. package/dist/Interfaces/Shipping/Shiptime/quote.d.ts +111 -111
  219. package/dist/Interfaces/Shipping/Shiptime/quote.js +2 -2
  220. package/dist/Interfaces/Slider/GR.d.ts +114 -114
  221. package/dist/Interfaces/Slider/GR.js +271 -271
  222. package/dist/Interfaces/Slider/index.d.ts +30 -30
  223. package/dist/Interfaces/Slider/index.js +2 -2
  224. package/dist/Interfaces/Space/IExternalService.d.ts +53 -53
  225. package/dist/Interfaces/Space/IExternalService.js +44 -44
  226. package/dist/Interfaces/Space/IMember.d.ts +16 -16
  227. package/dist/Interfaces/Space/IMember.js +9 -9
  228. package/dist/Interfaces/Space/index.d.ts +407 -405
  229. package/dist/Interfaces/Space/index.js +174 -174
  230. package/dist/Interfaces/Space/index.js.map +1 -1
  231. package/dist/Interfaces/Specials/gr.d.ts +61 -61
  232. package/dist/Interfaces/Specials/gr.js +2 -2
  233. package/dist/Interfaces/StockNotification/index.d.ts +7 -7
  234. package/dist/Interfaces/StockNotification/index.js +2 -2
  235. package/dist/Interfaces/Store/index.d.ts +63 -63
  236. package/dist/Interfaces/Store/index.js +27 -27
  237. package/dist/Interfaces/Supplier/ICommand.d.ts +11 -11
  238. package/dist/Interfaces/Supplier/ICommand.js +2 -2
  239. package/dist/Interfaces/Supplier/index.d.ts +36 -36
  240. package/dist/Interfaces/Supplier/index.js +24 -24
  241. package/dist/Interfaces/TCG/index.d.ts +161 -161
  242. package/dist/Interfaces/TCG/index.js +54 -54
  243. package/dist/Interfaces/Tag/index.d.ts +18 -18
  244. package/dist/Interfaces/Tag/index.js +2 -2
  245. package/dist/Interfaces/Tax/index.d.ts +13 -13
  246. package/dist/Interfaces/Tax/index.js +2 -2
  247. package/dist/Interfaces/TransferRequest/index.d.ts +103 -103
  248. package/dist/Interfaces/TransferRequest/index.js +46 -46
  249. package/dist/Interfaces/Translation/index.d.ts +8 -8
  250. package/dist/Interfaces/Translation/index.js +5 -5
  251. package/dist/Interfaces/Update/index.d.ts +10 -10
  252. package/dist/Interfaces/Update/index.js +2 -2
  253. package/dist/Interfaces/User/IUser.d.ts +65 -65
  254. package/dist/Interfaces/User/IUser.js +8 -8
  255. package/dist/Interfaces/Version/index.d.ts +11 -11
  256. package/dist/Interfaces/Version/index.js +2 -2
  257. package/dist/Interfaces/Wishlist/index.d.ts +7 -7
  258. package/dist/Interfaces/Wishlist/index.js +2 -2
  259. package/dist/constants/Interfaces/IBaseApi.d.ts +15 -15
  260. package/dist/constants/Interfaces/IBaseApi.js +2 -2
  261. package/dist/constants/Interfaces/IEndpointResult.d.ts +9 -9
  262. package/dist/constants/Interfaces/IEndpointResult.js +2 -2
  263. package/dist/constants/enums.d.ts +6 -6
  264. package/dist/constants/enums.js +10 -10
  265. package/dist/constants/services.d.ts +2 -2
  266. package/dist/constants/services.js +117 -117
  267. package/dist/constants/version.d.ts +2 -2
  268. package/dist/constants/version.js +5 -5
  269. package/dist/index.d.ts +50 -50
  270. package/dist/index.js +266 -266
  271. package/dist/lib/Attribute/index.d.ts +14 -14
  272. package/dist/lib/Attribute/index.js +186 -186
  273. package/dist/lib/BGJob/index.d.ts +9 -9
  274. package/dist/lib/BGJob/index.js +216 -216
  275. package/dist/lib/BackgroundWorker/index.d.ts +34 -34
  276. package/dist/lib/BackgroundWorker/index.js +59 -59
  277. package/dist/lib/Blog/BlogArticle.d.ts +5 -5
  278. package/dist/lib/Blog/BlogArticle.js +10 -10
  279. package/dist/lib/Blog/BlogAuthor.d.ts +5 -5
  280. package/dist/lib/Blog/BlogAuthor.js +10 -10
  281. package/dist/lib/Blog/BlogCategory.d.ts +5 -5
  282. package/dist/lib/Blog/BlogCategory.js +10 -10
  283. package/dist/lib/Blog/BlogKeyword.d.ts +5 -5
  284. package/dist/lib/Blog/BlogKeyword.js +10 -10
  285. package/dist/lib/Booking/index.d.ts +85 -85
  286. package/dist/lib/Booking/index.js +596 -596
  287. package/dist/lib/Brand/index.d.ts +26 -26
  288. package/dist/lib/Brand/index.js +131 -131
  289. package/dist/lib/Cart/index.d.ts +335 -335
  290. package/dist/lib/Cart/index.js +3977 -3977
  291. package/dist/lib/CartReservedQuantities/index.d.ts +49 -49
  292. package/dist/lib/CartReservedQuantities/index.js +159 -159
  293. package/dist/lib/CashDrawerShift/index.d.ts +83 -83
  294. package/dist/lib/CashDrawerShift/index.js +205 -205
  295. package/dist/lib/Catalogue/index.d.ts +15 -15
  296. package/dist/lib/Catalogue/index.js +78 -78
  297. package/dist/lib/Category/index.d.ts +34 -34
  298. package/dist/lib/Category/index.js +230 -230
  299. package/dist/lib/Class/index.d.ts +16 -16
  300. package/dist/lib/Class/index.js +66 -66
  301. package/dist/lib/Consent/index.d.ts +4 -4
  302. package/dist/lib/Consent/index.js +29 -29
  303. package/dist/lib/Customer/index.d.ts +30 -30
  304. package/dist/lib/Customer/index.js +92 -92
  305. package/dist/lib/Declination/index.d.ts +9 -9
  306. package/dist/lib/Declination/index.js +26 -26
  307. package/dist/lib/Discount/index.d.ts +27 -27
  308. package/dist/lib/Discount/index.js +493 -493
  309. package/dist/lib/ElasticSearch/index.d.ts +13 -13
  310. package/dist/lib/ElasticSearch/index.js +50 -50
  311. package/dist/lib/Elavon/index.d.ts +18 -18
  312. package/dist/lib/Elavon/index.js +135 -135
  313. package/dist/lib/Email/AbandonedCartEmail.d.ts +16 -16
  314. package/dist/lib/Email/AbandonedCartEmail.js +24 -24
  315. package/dist/lib/Email/AccountConfirmationEmail.d.ts +19 -19
  316. package/dist/lib/Email/AccountConfirmationEmail.js +30 -30
  317. package/dist/lib/Email/AdminOrderConfirmationEmail.d.ts +16 -16
  318. package/dist/lib/Email/AdminOrderConfirmationEmail.js +24 -24
  319. package/dist/lib/Email/ApplicationEmail.d.ts +16 -16
  320. package/dist/lib/Email/ApplicationEmail.js +24 -24
  321. package/dist/lib/Email/BackInStockEmail.d.ts +16 -16
  322. package/dist/lib/Email/BackInStockEmail.js +24 -24
  323. package/dist/lib/Email/ContactEmail.d.ts +16 -16
  324. package/dist/lib/Email/ContactEmail.js +24 -24
  325. package/dist/lib/Email/CustomerBookingAdminEmail.d.ts +16 -16
  326. package/dist/lib/Email/CustomerBookingAdminEmail.js +24 -24
  327. package/dist/lib/Email/CustomerBookingEmail.d.ts +16 -16
  328. package/dist/lib/Email/CustomerBookingEmail.js +24 -24
  329. package/dist/lib/Email/OrderConfirmationEmail.d.ts +16 -16
  330. package/dist/lib/Email/OrderConfirmationEmail.js +24 -24
  331. package/dist/lib/Email/OrderDenounciationEmail.d.ts +16 -16
  332. package/dist/lib/Email/OrderDenounciationEmail.js +24 -24
  333. package/dist/lib/Email/OrderSampleEmail.d.ts +16 -16
  334. package/dist/lib/Email/OrderSampleEmail.js +24 -24
  335. package/dist/lib/Email/OtherTypeEmails.d.ts +16 -16
  336. package/dist/lib/Email/OtherTypeEmails.js +27 -27
  337. package/dist/lib/Email/PasswordResetEmail.d.ts +16 -16
  338. package/dist/lib/Email/PasswordResetEmail.js +24 -24
  339. package/dist/lib/Email/PhotoShootEmail.d.ts +16 -16
  340. package/dist/lib/Email/PhotoShootEmail.js +24 -24
  341. package/dist/lib/Email/PickUpConfirmation.d.ts +16 -16
  342. package/dist/lib/Email/PickUpConfirmation.js +24 -24
  343. package/dist/lib/Email/ShippingConfirmation.d.ts +16 -16
  344. package/dist/lib/Email/ShippingConfirmation.js +24 -24
  345. package/dist/lib/Email/WelcomeEmail.d.ts +16 -16
  346. package/dist/lib/Email/WelcomeEmail.js +24 -24
  347. package/dist/lib/Email/index.d.ts +16 -16
  348. package/dist/lib/Email/index.js +31 -31
  349. package/dist/lib/ExternalService/Ebay.d.ts +74 -74
  350. package/dist/lib/ExternalService/Ebay.js +124 -124
  351. package/dist/lib/ExternalService/index.d.ts +5 -5
  352. package/dist/lib/ExternalService/index.js +10 -10
  353. package/dist/lib/FirstOrderTracking/index.d.ts +5 -5
  354. package/dist/lib/FirstOrderTracking/index.js +10 -10
  355. package/dist/lib/Indexed/IndexedCart.d.ts +13 -13
  356. package/dist/lib/Indexed/IndexedCart.js +91 -91
  357. package/dist/lib/Indexed/Product.d.ts +17 -17
  358. package/dist/lib/Indexed/Product.js +98 -98
  359. package/dist/lib/Inventory/index.d.ts +112 -112
  360. package/dist/lib/Inventory/index.js +492 -492
  361. package/dist/lib/Invoice/index.d.ts +16 -16
  362. package/dist/lib/Invoice/index.js +21 -21
  363. package/dist/lib/MarketplacePublication/index.d.ts +9 -9
  364. package/dist/lib/MarketplacePublication/index.js +426 -426
  365. package/dist/lib/Menu/index.d.ts +11 -11
  366. package/dist/lib/Menu/index.js +107 -107
  367. package/dist/lib/MongoDB/BaseAPI.d.ts +18 -18
  368. package/dist/lib/MongoDB/BaseAPI.js +200 -200
  369. package/dist/lib/Note/index.d.ts +4 -4
  370. package/dist/lib/Note/index.js +6 -6
  371. package/dist/lib/Order/index.d.ts +27 -27
  372. package/dist/lib/Order/index.js +56 -56
  373. package/dist/lib/Org/index.d.ts +68 -68
  374. package/dist/lib/Org/index.js +216 -216
  375. package/dist/lib/PandaPay/index.d.ts +16 -16
  376. package/dist/lib/PandaPay/index.js +176 -176
  377. package/dist/lib/Paysafe/index.d.ts +11 -11
  378. package/dist/lib/Paysafe/index.js +41 -41
  379. package/dist/lib/Product/index.d.ts +182 -182
  380. package/dist/lib/Product/index.js +847 -847
  381. package/dist/lib/ProductAttribute/index.d.ts +15 -15
  382. package/dist/lib/ProductAttribute/index.js +45 -45
  383. package/dist/lib/PromiseToPurchase/index.d.ts +109 -109
  384. package/dist/lib/PromiseToPurchase/index.js +343 -343
  385. package/dist/lib/PurchaseOrder/index.d.ts +20 -20
  386. package/dist/lib/PurchaseOrder/index.js +28 -28
  387. package/dist/lib/Schedule/index.d.ts +5 -5
  388. package/dist/lib/Schedule/index.js +12 -12
  389. package/dist/lib/Service/Enum/ServiceEnum.d.ts +3 -3
  390. package/dist/lib/Service/Enum/ServiceEnum.js +7 -7
  391. package/dist/lib/Service/index.d.ts +13 -13
  392. package/dist/lib/Service/index.js +21 -21
  393. package/dist/lib/Shipment/index.d.ts +28 -28
  394. package/dist/lib/Shipment/index.js +370 -370
  395. package/dist/lib/Slider/index.d.ts +22 -22
  396. package/dist/lib/Slider/index.js +119 -119
  397. package/dist/lib/Space/index.d.ts +1150 -1150
  398. package/dist/lib/Space/index.js +5792 -5792
  399. package/dist/lib/StockNotification/index.d.ts +4 -4
  400. package/dist/lib/StockNotification/index.js +6 -6
  401. package/dist/lib/Store/index.d.ts +5 -5
  402. package/dist/lib/Store/index.js +12 -12
  403. package/dist/lib/Supplier/Command.d.ts +5 -5
  404. package/dist/lib/Supplier/Command.js +10 -10
  405. package/dist/lib/Supplier/index.d.ts +25 -25
  406. package/dist/lib/Supplier/index.js +27 -27
  407. package/dist/lib/Tags/index.d.ts +6 -6
  408. package/dist/lib/Tags/index.js +26 -26
  409. package/dist/lib/Tax/index.d.ts +8 -8
  410. package/dist/lib/Tax/index.js +54 -54
  411. package/dist/lib/TransferRequest/index.d.ts +290 -290
  412. package/dist/lib/TransferRequest/index.js +1026 -1026
  413. package/dist/lib/Update/index.d.ts +10 -10
  414. package/dist/lib/Update/index.js +22 -22
  415. package/dist/lib/User/index.d.ts +89 -89
  416. package/dist/lib/User/index.js +328 -328
  417. package/dist/lib/Wishlist/index.d.ts +5 -5
  418. package/dist/lib/Wishlist/index.js +10 -10
  419. package/dist/lib/base.d.ts +14 -14
  420. package/dist/lib/base.js +62 -62
  421. package/dist/lib/baseService.d.ts +17 -17
  422. package/dist/lib/baseService.js +69 -69
  423. package/dist/rules/GR/constants/data.d.ts +26 -26
  424. package/dist/rules/GR/constants/data.js +81 -81
  425. package/dist/rules/GR/constants/expedition.d.ts +4 -4
  426. package/dist/rules/GR/constants/expedition.js +9 -9
  427. package/dist/rules/GR/constants/products.d.ts +22 -22
  428. package/dist/rules/GR/constants/products.js +263 -263
  429. package/dist/rules/GR/interfaces/cart.d.ts +84 -84
  430. package/dist/rules/GR/interfaces/cart.js +41 -41
  431. package/dist/rules/GR/interfaces/data.d.ts +101 -101
  432. package/dist/rules/GR/interfaces/data.js +114 -114
  433. package/dist/rules/GR/interfaces/products.d.ts +61 -61
  434. package/dist/rules/GR/interfaces/products.js +10 -10
  435. package/dist/rules/GR/utils/cart.d.ts +95 -95
  436. package/dist/rules/GR/utils/cart.js +839 -836
  437. package/dist/rules/GR/utils/cart.js.map +1 -1
  438. package/dist/rules/GR/utils/data.d.ts +3 -3
  439. package/dist/rules/GR/utils/data.js +28 -28
  440. package/dist/rules/GR/utils/expedition.d.ts +140 -140
  441. package/dist/rules/GR/utils/expedition.js +2016 -2016
  442. package/dist/rules/GR/utils/g2.d.ts +209 -209
  443. package/dist/rules/GR/utils/g2.js +999 -999
  444. package/dist/rules/GR/utils/invoices.d.ts +51 -51
  445. package/dist/rules/GR/utils/invoices.js +215 -215
  446. package/dist/rules/GR/utils/products.d.ts +277 -277
  447. package/dist/rules/GR/utils/products.js +1350 -1350
  448. package/dist/rules/GR/utils/upsells.d.ts +111 -111
  449. package/dist/rules/GR/utils/upsells.js +215 -215
  450. package/dist/services/database/BaseProvider.d.ts +29 -29
  451. package/dist/services/database/BaseProvider.js +28 -28
  452. package/dist/services/database/BatchUtils.d.ts +14 -14
  453. package/dist/services/database/BatchUtils.js +43 -43
  454. package/dist/services/database/Config.d.ts +2 -2
  455. package/dist/services/database/Config.js +5 -5
  456. package/dist/services/database/DatabaseService.d.ts +125 -125
  457. package/dist/services/database/DatabaseService.js +237 -237
  458. package/dist/services/database/FirebaseProvider.d.ts +17 -17
  459. package/dist/services/database/FirebaseProvider.js +235 -235
  460. package/dist/services/database/NotFirebaseProvider.d.ts +49 -49
  461. package/dist/services/database/NotFirebaseProvider.js +262 -262
  462. package/dist/services/g2/G2OrderSlip.d.ts +49 -49
  463. package/dist/services/g2/G2OrderSlip.js +228 -228
  464. package/dist/services/g2/utils.d.ts +19 -19
  465. package/dist/services/g2/utils.js +953 -953
  466. package/dist/services/logs/index.d.ts +23 -23
  467. package/dist/services/logs/index.js +66 -66
  468. package/dist/services/marketplace/BaseMarketServiceClass.d.ts +52 -52
  469. package/dist/services/marketplace/BaseMarketServiceClass.js +111 -111
  470. package/dist/services/marketplace/CardtraderServiceClass.d.ts +17 -17
  471. package/dist/services/marketplace/CardtraderServiceClass.js +139 -139
  472. package/dist/services/marketplace/utils.d.ts +14 -14
  473. package/dist/services/marketplace/utils.js +29 -29
  474. package/dist/services/products/BaseClass.d.ts +50 -50
  475. package/dist/services/products/BaseClass.js +66 -66
  476. package/dist/services/products/TCGService.d.ts +32 -32
  477. package/dist/services/products/TCGService.js +555 -555
  478. package/dist/services/products/utils.d.ts +31 -31
  479. package/dist/services/products/utils.js +144 -144
  480. package/dist/utils/algolia.d.ts +46 -46
  481. package/dist/utils/algolia.js +21 -21
  482. package/dist/utils/anonymisation.d.ts +54 -54
  483. package/dist/utils/anonymisation.js +280 -280
  484. package/dist/utils/array.d.ts +5 -5
  485. package/dist/utils/array.js +14 -14
  486. package/dist/utils/aws.d.ts +36 -36
  487. package/dist/utils/aws.js +154 -154
  488. package/dist/utils/booking.d.ts +30 -30
  489. package/dist/utils/booking.js +127 -127
  490. package/dist/utils/cart.d.ts +259 -259
  491. package/dist/utils/cart.js +1145 -1145
  492. package/dist/utils/categories.d.ts +2 -2
  493. package/dist/utils/categories.js +54 -54
  494. package/dist/utils/cmv.d.ts +10 -10
  495. package/dist/utils/cmv.js +107 -107
  496. package/dist/utils/console.d.ts +6 -6
  497. package/dist/utils/console.js +59 -59
  498. package/dist/utils/context.d.ts +20 -20
  499. package/dist/utils/context.js +61 -61
  500. package/dist/utils/currency.d.ts +6 -6
  501. package/dist/utils/currency.js +91 -91
  502. package/dist/utils/data.d.ts +31 -31
  503. package/dist/utils/data.js +296 -296
  504. package/dist/utils/date.d.ts +1 -1
  505. package/dist/utils/date.js +16 -16
  506. package/dist/utils/dimensions.d.ts +3 -3
  507. package/dist/utils/dimensions.js +16 -16
  508. package/dist/utils/discount.d.ts +164 -164
  509. package/dist/utils/discount.js +1111 -1111
  510. package/dist/utils/errors.d.ts +113 -113
  511. package/dist/utils/errors.js +113 -113
  512. package/dist/utils/file-admin.d.ts +8 -8
  513. package/dist/utils/file-admin.js +39 -39
  514. package/dist/utils/file.d.ts +39 -39
  515. package/dist/utils/file.js +208 -208
  516. package/dist/utils/firebase-admin.d.ts +11 -11
  517. package/dist/utils/firebase-admin.js +73 -73
  518. package/dist/utils/firebase.d.ts +58 -58
  519. package/dist/utils/firebase.js +148 -148
  520. package/dist/utils/import.d.ts +1 -1
  521. package/dist/utils/import.js +21 -21
  522. package/dist/utils/inventories.d.ts +101 -101
  523. package/dist/utils/inventories.js +467 -467
  524. package/dist/utils/locale.d.ts +24 -24
  525. package/dist/utils/locale.js +89 -89
  526. package/dist/utils/mailchimp.d.ts +58 -58
  527. package/dist/utils/mailchimp.js +531 -531
  528. package/dist/utils/mathUtils.d.ts +17 -17
  529. package/dist/utils/mathUtils.js +324 -324
  530. package/dist/utils/mongodb.d.ts +1 -1
  531. package/dist/utils/mongodb.js +22 -22
  532. package/dist/utils/object.d.ts +32 -32
  533. package/dist/utils/object.js +133 -133
  534. package/dist/utils/payment.d.ts +10 -10
  535. package/dist/utils/payment.js +23 -23
  536. package/dist/utils/products.d.ts +39 -39
  537. package/dist/utils/products.js +195 -195
  538. package/dist/utils/promiseToPurchase.d.ts +88 -88
  539. package/dist/utils/promiseToPurchase.js +229 -229
  540. package/dist/utils/prosprsearch.d.ts +42 -42
  541. package/dist/utils/prosprsearch.js +216 -216
  542. package/dist/utils/refunds.d.ts +2 -2
  543. package/dist/utils/refunds.js +21 -21
  544. package/dist/utils/sdc.d.ts +10 -10
  545. package/dist/utils/sdc.js +1309 -1309
  546. package/dist/utils/searchIndexes.d.ts +58 -58
  547. package/dist/utils/searchIndexes.js +247 -247
  548. package/dist/utils/services.d.ts +42 -42
  549. package/dist/utils/services.js +409 -409
  550. package/dist/utils/shipment.d.ts +110 -110
  551. package/dist/utils/shipment.js +345 -345
  552. package/dist/utils/simpletexting.d.ts +2 -2
  553. package/dist/utils/simpletexting.js +45 -45
  554. package/dist/utils/sliders.d.ts +4 -4
  555. package/dist/utils/sliders.js +24 -24
  556. package/dist/utils/string.d.ts +16 -16
  557. package/dist/utils/string.js +192 -192
  558. package/dist/utils/tcgService.d.ts +74 -74
  559. package/dist/utils/tcgService.js +308 -308
  560. package/dist/utils/tools.d.ts +5 -5
  561. package/dist/utils/tools.js +13 -13
  562. package/dist/utils/transferRequests.d.ts +43 -43
  563. package/dist/utils/transferRequests.js +67 -67
  564. package/dist/utils/update.d.ts +7 -7
  565. package/dist/utils/update.js +137 -137
  566. package/dist/utils/weight.d.ts +3 -3
  567. package/dist/utils/weight.js +16 -16
  568. package/dist/utils/zones.d.ts +11 -11
  569. package/dist/utils/zones.js +218 -218
  570. package/package.json +107 -107
  571. package/publish.sh +143 -143
  572. package/readme.md +182 -182
  573. package/dist/lib/Queue/index.d.ts +0 -40
  574. package/dist/lib/Queue/index.js +0 -255
  575. package/dist/lib/Queue/index.js.map +0 -1
@@ -1,2017 +1,2017 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.checkIfNoDeliveryDateIsNormal = exports.checkIfCartExpired = exports.getStoresForVracProdShipping = exports.calculateShippingForVrac = exports.checkIfShouldRemoveSampleShippingFee = exports.applyFeesToCart = exports.installationFeePalletTier = exports.expeditionFeePalletTier = exports.checkForSameGrassDayFee = exports.checkIfShouldApplySameDayGrassFee = exports.getMinQteInstall = exports.getMinGrassQte = exports.calculatePalFeeForOtherThanGrass = exports.getPalletQtyPalletFee = exports.getGrassRoundedPickupPalletFees = exports.getPalletQty = exports.slugsToCheckFromExpeditionFees = exports.checkIfCartTypeHasBlockedDates = exports.dateIsClosedInSchedule = exports.shouldDisableDate = exports.getMinDateOffset = exports.getSamplesMinDateOffset = exports.getMinDatePicker = exports.getAvailableHours = exports.getDefaultTimeValues = void 0;
7
- const moment_1 = __importDefault(require("moment"));
8
- const ceil_1 = __importDefault(require("lodash/ceil"));
9
- const findIndex_1 = __importDefault(require("lodash/findIndex"));
10
- const floor_1 = __importDefault(require("lodash/floor"));
11
- const round_1 = __importDefault(require("lodash/round"));
12
- const sumBy_1 = __importDefault(require("lodash/sumBy"));
13
- const toNumber_1 = __importDefault(require("lodash/toNumber"));
14
- // Rule specific interfaces
15
- const products_1 = require("../interfaces/products");
16
- // Rule specific functions/constants
17
- const data_1 = require("./data");
18
- const products_2 = require("./products");
19
- const cart_1 = require("./cart");
20
- const g2_1 = require("./g2");
21
- const data_2 = require("../constants/data");
22
- const products_3 = require("../constants/products");
23
- // General interfaces
24
- const Cart_1 = require("../../../Interfaces/Cart");
25
- // General utils
26
- const data_3 = require("../../../utils/data");
27
- const products_4 = require("../../../utils/products");
28
- const cart_2 = require("../interfaces/cart");
29
- const data_4 = require("../interfaces/data");
30
- const object_1 = require("../../../utils/object");
31
- // ------------------------------------------------------------------------------------------
32
- // #region HOURS
33
- const getDefaultTimeValues = () => {
34
- let values = ['AM', 'PM'];
35
- return values.map((v) => ({ label: v, value: v }));
36
- };
37
- exports.getDefaultTimeValues = getDefaultTimeValues;
38
- const getAvailableHours = (minDeliveryDate, selectedDate, grassProduct, concreteOrder, expeditionMethod, selectedDeliveryTime, isPro, isSample, isAccessoriesOnly, testDate, keepHours) => {
39
- if (!!!minDeliveryDate)
40
- return { deliveryTimes: (0, exports.getDefaultTimeValues)() };
41
- let deliveryTimes = (0, exports.getDefaultTimeValues)().map((t) => t.value);
42
- const today = !!testDate
43
- ? !!keepHours
44
- ? (0, moment_1.default)(testDate).toDate()
45
- : (0, moment_1.default)(testDate).set('hours', (0, moment_1.default)().hours()).toDate()
46
- : (0, moment_1.default)().toDate();
47
- // If concreteOrder and product in stock and is pickup, can select 'now' (AM if before noon, PM if after)
48
- if (!!concreteOrder && !!concreteOrder.inStock && expeditionMethod === 'pickup') {
49
- const isPM = today.getHours() >= 12;
50
- if (!!isPM) {
51
- deliveryTimes = ['PM'];
52
- }
53
- return {
54
- deliveryTimes: deliveryTimes.map((t) => ({ label: t, value: t })),
55
- newSelectedDeliveryTime: !!isPM ? { label: 'PM', value: 'PM' } : undefined
56
- };
57
- }
58
- // ------------------------------------------------------------------------------------------------------
59
- // enable all hours in selection
60
- const resetHours = (d) => {
61
- d.setHours(0);
62
- d.setMinutes(0);
63
- d.setSeconds(0);
64
- d.setMilliseconds(0);
65
- };
66
- if (!!selectedDate)
67
- resetHours(selectedDate);
68
- resetHours(minDeliveryDate);
69
- let newSelectedDeliveryTime = undefined;
70
- const targetDateDay = minDeliveryDate.getDay();
71
- const selectedDateDay = !!selectedDate ? selectedDate.getDay() : targetDateDay;
72
- const isSelectedSameAsTarget = (0, moment_1.default)(minDeliveryDate).isSame(selectedDate) || !!!selectedDate;
73
- const todayDay = today.getDay();
74
- const isNonSpecialityGrass = !!grassProduct && (0, products_2.checkIfIsNonSpecialityGrass)(grassProduct.sku, grassProduct.slug);
75
- const onlyPm = () => {
76
- if (!!selectedDeliveryTime && selectedDeliveryTime === 'AM') {
77
- newSelectedDeliveryTime = { label: 'PM', value: 'PM' };
78
- }
79
- deliveryTimes = ['PM'];
80
- };
81
- // EDIT - Ajusted logic that excluded saturdays from time selection if not pro to make available if expeditionMethod = shipping [ 03-10-2022 ]
82
- if (selectedDateDay === 0 || (selectedDateDay === 6 && !!!isPro && expeditionMethod === 'pickup')) {
83
- deliveryTimes = [];
84
- newSelectedDeliveryTime = undefined;
85
- }
86
- else if (
87
- // Bug GR-I505 - AM / PM toujours disponnible pour Beton Vert en livraison
88
- // Bug GR-I511 - Pickup for concrete not in stock only change de available day
89
- !(!!concreteOrder && concreteOrder.type == 'green' && (!concreteOrder.inStock || expeditionMethod == 'delivery'))) {
90
- if (isSelectedSameAsTarget) {
91
- if (!!grassProduct || (!!concreteOrder && concreteOrder.type === 'green')) {
92
- let todayReset = !!testDate ? (0, moment_1.default)(testDate).toDate() : (0, moment_1.default)().toDate();
93
- resetHours(todayReset);
94
- // If today is either saturday of sunday
95
- if (!![6, 0].includes(todayReset.getDay())) {
96
- // Two options :
97
- // - is non-speciality grass OR [ concrete + type green + pickup + not in stock ] and target day is NOT a tuesday
98
- // - is any other kind of grass and target day is NOT a wednesday or thursday
99
- if ((![2].includes(targetDateDay) &&
100
- (!!isNonSpecialityGrass ||
101
- (!!concreteOrder && !concreteOrder.inStock && expeditionMethod === 'pickup'))) ||
102
- (![3, 4].includes(targetDateDay) && !!!isNonSpecialityGrass)) {
103
- // EDIT - Ajusted logic that excluded saturdays from time selection if not pro to make available if expeditionMethod = shipping [ 03-10-2022 ]
104
- if (targetDateDay === 6 && !!!isPro && expeditionMethod === 'pickup') {
105
- newSelectedDeliveryTime = undefined;
106
- deliveryTimes = [];
107
- }
108
- else {
109
- const amTimeToCheck = !!grassProduct && expeditionMethod == 'pickup' ? 12 : 10;
110
- // Logic ajusted on 08-05-2025 (task #GR-I377 in Sprint) - If grass & pickup, first check starts at noon. If not, at 10am.
111
- // Check if later than specific AM time
112
- if (today.getHours() >= amTimeToCheck) {
113
- onlyPm();
114
- }
115
- }
116
- }
117
- // If none of the above options are true, both time periods are available to the user
118
- }
119
- else {
120
- // Today is any other day than the weekend
121
- // Check if later than target hour
122
- // Logic updated on 08-05-2025, #GR-I377 in Sprint
123
- let targetHour = !!grassProduct && expeditionMethod == 'pickup' ? 12 : 10;
124
- // If grass or green concrete pickup, and today is Friday, AM stays available until after 16h
125
- // Logic updated on 17-02-2025, GR-I150 dans Zoho Sprint
126
- if (todayDay == 5 &&
127
- (!!grassProduct || (!!concreteOrder && concreteOrder.type == 'green' && expeditionMethod == 'pickup'))) {
128
- targetHour = 16;
129
- }
130
- if (today.getHours() >= targetHour) {
131
- onlyPm();
132
- }
133
- }
134
- }
135
- // If order contains samples or is of any other type than grass or concrete
136
- if ((!!!grassProduct && !!!concreteOrder) || !!isSample || !!isAccessoriesOnly) {
137
- // Check if later than 10 AM
138
- if (today.getHours() > 10) {
139
- onlyPm();
140
- }
141
- }
142
- }
143
- }
144
- return {
145
- deliveryTimes: deliveryTimes.map((t) => ({ label: t, value: t })),
146
- newSelectedDeliveryTime: newSelectedDeliveryTime ? newSelectedDeliveryTime : undefined
147
- };
148
- };
149
- exports.getAvailableHours = getAvailableHours;
150
- // Date de dégel (hardcodée, sera modifiée directement dans le code à la demande des clients)
151
- const isDegel = (dateToCheck) => {
152
- let date = !!dateToCheck ? (0, moment_1.default)(dateToCheck) : (0, moment_1.default)();
153
- return date.isBetween('2024-03-04 00:00:01', '2024-04-15 23:59:59', undefined, '[]');
154
- };
155
- /**
156
- * Function getMinDatePicker
157
- * @description Sets the minimum shipping day for delivery
158
- */
159
- const getMinDatePicker = (cartData, grassProduct, concreteOrder, expeditionMethod, isPro, testDate, blockedShippingDates, vracType, isPOS, spaceSchedule) => {
160
- const cartContainsInstallation = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.INSTALLATION, cartData);
161
- const cartContainsVrac = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.VRAC, cartData);
162
- const isAccessoriesOnly = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.ONLY_ACCESSORIES, cartData);
163
- let minDates = {};
164
- if (!!testDate && !isPOS) {
165
- testDate.setHours((0, moment_1.default)().hours());
166
- }
167
- let now = testDate || (0, moment_1.default)().toDate();
168
- let min_date = testDate || (0, moment_1.default)().toDate();
169
- // =======================================================================================
170
- // #region MIN DATE OFFSET
171
- const nbDaysOffset = (0, exports.getMinDateOffset)(now, cartContainsInstallation, cartContainsVrac, cartData, grassProduct, concreteOrder, isAccessoriesOnly, expeditionMethod, vracType);
172
- // #endregion
173
- // =======================================================================================
174
- // =======================================================================================
175
- // #region BLOCKED DAYS/DATES
176
- const typeToCheck = !!concreteOrder
177
- ? 'beton'
178
- : !!grassProduct
179
- ? 'gazon'
180
- : !!cartContainsVrac || (!!!isPro && !!vracType)
181
- ? 'vrac'
182
- : undefined;
183
- let dateToCheck = new Date(min_date);
184
- dateToCheck.setDate(min_date.getDate() + nbDaysOffset);
185
- let pickupDateSameAsNewDate = false;
186
- // ---------------------------------------------------------------------------------------
187
- // Check if space has blocked days
188
- // NEW!!! - For now, blocked days are hardcoded here. Will be moved to space eventually.
189
- const blockedDays = {
190
- vrac: [0],
191
- beton: [0],
192
- gazon: [0]
193
- };
194
- const getNextAvailableDay = (type) => {
195
- const dayToCheck = dateToCheck.getDay();
196
- if (!!blockedDays[type]) {
197
- // Right now we ignore blocked days on pickup because we check the schedules in the space. If days are added to the blockedDays dictionnary, validate that they still shouldn't apply on pickup
198
- if (blockedDays[type].includes(dayToCheck) && expeditionMethod !== 'pickup') {
199
- dateToCheck.setDate(dateToCheck.getDate() + 1);
200
- return getNextAvailableDay(type);
201
- }
202
- }
203
- if (!!spaceSchedule && expeditionMethod === 'pickup') {
204
- const storeId = (0, object_1.recursiveCheckObject)(cartData, 'shipping_payload.pickup_store.id');
205
- if (!!storeId && !!(0, exports.dateIsClosedInSchedule)(storeId, dateToCheck, spaceSchedule)) {
206
- dateToCheck.setDate(dateToCheck.getDate() + 1);
207
- return getNextAvailableDay(type);
208
- }
209
- }
210
- min_date = dateToCheck;
211
- min_date.setHours(0);
212
- min_date.setMinutes(0);
213
- min_date.setSeconds(0);
214
- };
215
- if (!!typeToCheck) {
216
- getNextAvailableDay(typeToCheck);
217
- if (typeToCheck === 'vrac') {
218
- pickupDateSameAsNewDate = true;
219
- }
220
- }
221
- // ---------------------------------------------------------------------------------------
222
- // Check if space has blocked dates
223
- if (!!blockedShippingDates && blockedShippingDates.length && !!typeToCheck && expeditionMethod === 'delivery') {
224
- const blockedDatesToCheck = blockedShippingDates.find((blockedDate) => blockedDate.cart_type === typeToCheck);
225
- if (!!blockedDatesToCheck && !!blockedDatesToCheck.dates && !!blockedDatesToCheck.dates.length) {
226
- const isInBlockedPeriod = blockedDatesToCheck.dates.find((blocked) => {
227
- return (!!blocked.start_date &&
228
- !!blocked.end_date &&
229
- (0, moment_1.default)(dateToCheck).isBetween((0, moment_1.default)((0, data_3.formatDate)(blocked.start_date)), (0, moment_1.default)((0, data_3.formatDate)(blocked.end_date)), 'date', '[]'));
230
- });
231
- if (!!isInBlockedPeriod) {
232
- dateToCheck = (0, moment_1.default)((0, data_3.formatDate)(isInBlockedPeriod.end_date)).add(1, 'days').toDate();
233
- getNextAvailableDay(typeToCheck);
234
- let pickup_date = !!pickupDateSameAsNewDate ? dateToCheck : (0, moment_1.default)(min_date).toDate();
235
- return {
236
- min_delivery: min_date,
237
- min_pickup: pickup_date
238
- };
239
- }
240
- }
241
- }
242
- // #endregion
243
- // =======================================================================================
244
- if (!!!concreteOrder || concreteOrder.type !== 'yellow') {
245
- min_date.setDate(dateToCheck.getDate());
246
- min_date.setHours(0);
247
- min_date.setMinutes(0);
248
- min_date.setSeconds(0);
249
- let pickup_date = (0, moment_1.default)(min_date).toDate();
250
- minDates = {
251
- min_delivery: min_date,
252
- min_pickup: pickup_date
253
- };
254
- }
255
- return minDates;
256
- };
257
- exports.getMinDatePicker = getMinDatePicker;
258
- const getSamplesMinDateOffset = () => {
259
- const now = new Date();
260
- const year = now.getFullYear();
261
- // December 1st
262
- const startWinterPeriod = new Date(year, 11, 1); // December == 11
263
- // March 1st
264
- const endWinterPeriod = new Date(year + 1, 2, 1); // March == 2
265
- const isWinterPeriod = (0, moment_1.default)().isBetween((0, moment_1.default)(startWinterPeriod), (0, moment_1.default)(endWinterPeriod), 'day', '[]');
266
- return isWinterPeriod ? 14 : 7;
267
- };
268
- exports.getSamplesMinDateOffset = getSamplesMinDateOffset;
269
- const getMinDateOffset = (now, cartContainsInstallation, cartContainsVrac, cartData, grassProduct, concreteOrder, isAccessoriesOnly, expeditionMethod, vracType) => {
270
- const current_hour = now.getHours();
271
- const current_day = now.getDay();
272
- let nb_days_offset = 1;
273
- // Variable to set all grass delays the same as non-speciality grasses (as of now, Kentucky and Prestige).
274
- // Use this instead of changing all values, in case our clients change their mind later!
275
- const allGrassDelaysSameAsNonSpecialityGrasses = true;
276
- // ========================
277
- // IF INSTALL
278
- // Install logic adjusted on 01-05-2024 (task #GR7-T429)
279
- if (!!cartContainsInstallation) {
280
- // --------------------
281
- // "Low staff" logic = 96hours delay for first available date
282
- // switch (current_day) {
283
- // case 3:
284
- // nb_days_offset = 5
285
- // break
286
- // default:
287
- // nb_days_offset = 4
288
- // break
289
- // }
290
- // --------------------
291
- // "Medium staff" logic = 48hours delay for first available date
292
- switch (current_day) {
293
- case 5:
294
- nb_days_offset = 3;
295
- break;
296
- default:
297
- nb_days_offset = 2;
298
- break;
299
- }
300
- // --------------------
301
- // Regular logic (if fee applies for current year) = 24 hour delay for first available date
302
- // switch (current_day) {
303
- // case 5:
304
- // nb_days_offset = current_hour < 10 ? 1 : 3
305
- // break
306
- // case 6:
307
- // case 0:
308
- // nb_days_offset = 2
309
- // break
310
- // default:
311
- // nb_days_offset = 1
312
- // break
313
- // }
314
- }
315
- // ========================
316
- // IF SAMPLE OR ACCESSORIES ONLY
317
- else if (cartData.items.find((item) => item.is_sample) || !!isAccessoriesOnly) {
318
- if (expeditionMethod === 'delivery') {
319
- nb_days_offset = !!isAccessoriesOnly ? 7 : (0, exports.getSamplesMinDateOffset)();
320
- }
321
- else {
322
- switch (current_day) {
323
- case 4:
324
- nb_days_offset = 4;
325
- break;
326
- case 5:
327
- nb_days_offset = current_hour < 10 ? 3 : 4;
328
- break;
329
- case 6:
330
- nb_days_offset = 4;
331
- break;
332
- case 0:
333
- nb_days_offset = 3;
334
- break;
335
- default:
336
- nb_days_offset = 2;
337
- }
338
- }
339
- }
340
- // ========================
341
- // IF VRAC PRODUCTS WITH DELIVERY
342
- else if (expeditionMethod === 'delivery' &&
343
- !!cartContainsVrac &&
344
- !!(0, object_1.recursiveCheckObject)(vracType, 'vrac_type') &&
345
- [products_1.VracTypeEnum.AUTRE_TONNE, products_1.VracTypeEnum.NOBEL_TONNE].includes(vracType.vrac_type)) {
346
- nb_days_offset = 1;
347
- }
348
- // ========================
349
- // IF BASE GRASS / ALL GRASSES ARE SAME
350
- else if (!!grassProduct &&
351
- ((0, products_2.checkIfIsNonSpecialityGrass)(grassProduct.sku, grassProduct.slug) || !!allGrassDelaysSameAsNonSpecialityGrasses)) {
352
- const amTimeToCheck = !!grassProduct && expeditionMethod == 'pickup' ? 12 : 10;
353
- // Logic ajusted on 08-05-2025 (task #GR-I377 in Sprint) - If grass & pickup, first check starts at noon. If not, at 10am.
354
- switch (current_day) {
355
- case 5:
356
- nb_days_offset = current_hour < amTimeToCheck ? 1 : current_hour < 16 ? 3 : 3; // earliest is tomorrow if before 10AM, else after tomorrow, not counting the weekend (on fridays)
357
- // Logic ajusted on 14-02-2025 (task #GR-I151 in Sprint) - New check for between 10h (or 12h if grass&pickup) and 16h
358
- break;
359
- case 6:
360
- nb_days_offset = 3; // earliest is after tomorrow, not counting the weekend (on fridays or saturdays)
361
- break;
362
- case 0:
363
- nb_days_offset = 2; // earliest is after tomorrow, not counting the weekend (on sundays)
364
- break;
365
- default:
366
- nb_days_offset = 1; // earliest is tomorrow
367
- }
368
- }
369
- // ========================
370
- // IF CONCRETE WITH PICKUP | UNAVAILABLE PRODUCT
371
- else if (!!concreteOrder &&
372
- concreteOrder.type === 'green' &&
373
- !concreteOrder.inStock &&
374
- expeditionMethod === 'pickup') {
375
- // 13-08-2025 : Bug GR-I511 - Pickup for concrete not in stock only change the available day
376
- const amTimeToCheck = 10;
377
- switch (current_day) {
378
- case 0:
379
- nb_days_offset = 2;
380
- break;
381
- case 4:
382
- nb_days_offset = current_hour < amTimeToCheck ? 1 : 4;
383
- break;
384
- case 5:
385
- nb_days_offset = 3;
386
- break;
387
- case 6:
388
- nb_days_offset = current_hour < amTimeToCheck ? 2 : 3;
389
- break;
390
- default:
391
- nb_days_offset = current_hour < amTimeToCheck ? 1 : 2;
392
- }
393
- }
394
- // ========================
395
- // IF CONCRETE WITH PICKUP | ONLY AVAILABLE PRODUCTS
396
- else if (!!concreteOrder &&
397
- concreteOrder.type === 'green' &&
398
- concreteOrder.inStock &&
399
- expeditionMethod === 'pickup') {
400
- nb_days_offset = 0;
401
- }
402
- // ========================
403
- // IF SPECIALITY GRASS
404
- else if (!!grassProduct && !!!(0, products_2.checkIfIsNonSpecialityGrass)(grassProduct.sku, grassProduct.slug)) {
405
- switch (current_day) {
406
- case 5:
407
- case 6:
408
- case 0:
409
- nb_days_offset = 4; // if we are on friday and it's earlier than 10
410
- break;
411
- default:
412
- nb_days_offset = 2; // earliest is after tomorrow
413
- }
414
- }
415
- // ========================
416
- // IF CONCRETE WITH DELIVERY | ONLY AVAILABLE PRODUCTS
417
- else if (!!concreteOrder && concreteOrder.type === 'green' && expeditionMethod === 'delivery') {
418
- switch (current_day) {
419
- case 0:
420
- nb_days_offset = 3;
421
- break;
422
- case 1:
423
- case 2:
424
- case 3:
425
- nb_days_offset = current_hour < 10 ? 2 : 3;
426
- break;
427
- case 4:
428
- nb_days_offset = current_hour < 10 ? 2 : current_hour < 16 ? 4 : 5;
429
- // Logic ajusted on 14-02-2025 (task #GR-I151 in Sprint) - New check for between 10h and 16h
430
- break;
431
- case 5:
432
- nb_days_offset = current_hour < 16 ? 4 : 5;
433
- // Logic ajusted on 14-02-2025 (task #GR-I151 in Sprint) - New check for 16h instead of 10h
434
- break;
435
- case 6:
436
- nb_days_offset = 4;
437
- break;
438
- default:
439
- break;
440
- }
441
- }
442
- // ========================
443
- // IF ANY PRODUCT WITH DELIVERY THAT DID NOT FIT IN PREVIOUS CATEGORIES
444
- else if (expeditionMethod === 'delivery') {
445
- switch (current_day) {
446
- case 0:
447
- nb_days_offset = 4;
448
- break;
449
- case 1:
450
- case 2:
451
- nb_days_offset = current_hour < 10 ? 3 : 4;
452
- break;
453
- case 3:
454
- nb_days_offset = current_hour < 10 ? 3 : 6;
455
- break;
456
- case 4:
457
- case 5:
458
- nb_days_offset = current_hour < 10 ? 5 : 6;
459
- break;
460
- case 6:
461
- nb_days_offset = 5;
462
- break;
463
- default:
464
- break;
465
- }
466
- }
467
- return nb_days_offset;
468
- };
469
- exports.getMinDateOffset = getMinDateOffset;
470
- /**
471
- * Function shouldDisableDate
472
- * @description compares date with blockedDates from DB and blocked days (currently hardcoded in function)
473
- * @param date - Date to check
474
- * @param blockedDates - Blocked dates from DB
475
- * @param expeditionMethod - pickup or shipping
476
- * @param cartData
477
- */
478
- const shouldDisableDate = (date, blockedDates, expeditionMethod, cartData, schedule, selectedStore) => {
479
- if (!!!cartData)
480
- return false;
481
- const typeToCheck = (0, cart_1.getCartType)(cartData);
482
- // ---------------------------------------------------------------------------------------
483
- // Blocked days check
484
- // NEW!!! - For now, blocked days are hardcoded here. Will be moved to space eventually.
485
- const blockedDays = {
486
- vrac: [0],
487
- beton: [0],
488
- gazon: [0],
489
- only_accessories: [0],
490
- sample: [0]
491
- };
492
- if (!!!typeToCheck ||
493
- (!!blockedDays[typeToCheck] && !!blockedDays[typeToCheck].includes(date.getDay()) && expeditionMethod !== 'pickup')) {
494
- return true;
495
- }
496
- // ---------------------------------------------------------------------------------------
497
- // Blocked dates checks
498
- if (expeditionMethod !== 'pickup' && !!typeToCheck && !!blockedDates) {
499
- const sameType = blockedDates.find((blocked) => blocked.cart_type === typeToCheck);
500
- if (!!sameType && !!sameType.dates) {
501
- for (let dates of sameType.dates) {
502
- if (!!dates.start_date &&
503
- !!dates.end_date &&
504
- (0, moment_1.default)(date).isBetween((0, moment_1.default)((0, data_3.formatDate)(dates.start_date)), (0, moment_1.default)((0, data_3.formatDate)(dates.end_date)), 'date', '[]'))
505
- return true;
506
- }
507
- }
508
- }
509
- const storeId = (0, object_1.recursiveCheckObject)(cartData, 'shipping_payload.pickup_store.id');
510
- if ((!!storeId || !!selectedStore) && expeditionMethod === 'pickup' && !!schedule) {
511
- return !!(0, exports.dateIsClosedInSchedule)(!!selectedStore ? selectedStore : storeId, date, schedule);
512
- }
513
- return false;
514
- };
515
- exports.shouldDisableDate = shouldDisableDate;
516
- const dateIsClosedInSchedule = (storeId, dateToCheck, spaceSchedule) => {
517
- var _a;
518
- const weekdayIndex = dateToCheck.getDay();
519
- const storeSchedules = spaceSchedule.store_schedules[storeId];
520
- let isExternal = false;
521
- // If store schedule exists, check it, if not, set min date to dateToCheck.
522
- if (!!storeSchedules) {
523
- let selectedDaySchedule;
524
- // If periods are activated for the space, check the specific period schedule, if not check the general schedule
525
- if (!!spaceSchedule.space_periods_active) {
526
- const year = dateToCheck.getFullYear().toString();
527
- const periods = (_a = spaceSchedule.year_periods[year]) !== null && _a !== void 0 ? _a : [];
528
- const matchingPeriod = periods.find((p) => new Date(p.starts_at) <= dateToCheck && dateToCheck <= new Date(p.ends_at));
529
- if (!!matchingPeriod) {
530
- const periodSchedule = storeSchedules[matchingPeriod.id];
531
- if (!!periodSchedule) {
532
- if (!!periodSchedule.external) {
533
- isExternal = true;
534
- }
535
- const daySchedule = periodSchedule.weekly_schedule[weekdayIndex];
536
- if (!!daySchedule) {
537
- selectedDaySchedule = daySchedule;
538
- }
539
- }
540
- }
541
- }
542
- // If no schedule found for that day in active period, or periods aren't activated for that space, fall back to general schedule
543
- // A closed day should NOT enter this if
544
- // A period with an external schedule should NOT enter this if
545
- if (!!!isExternal &&
546
- (!!!selectedDaySchedule ||
547
- (!!selectedDaySchedule.schedule &&
548
- !!selectedDaySchedule.open &&
549
- !!!selectedDaySchedule.schedule.closing_time &&
550
- !!!selectedDaySchedule.schedule.opening_time))) {
551
- const generalSchedule = storeSchedules['general'];
552
- if (!!generalSchedule) {
553
- if (!!generalSchedule.external) {
554
- isExternal = true;
555
- }
556
- selectedDaySchedule = generalSchedule.weekly_schedule[weekdayIndex];
557
- }
558
- }
559
- // NEW - Returns true here even if isExternal
560
- if (!!selectedDaySchedule && selectedDaySchedule.open === false) {
561
- return true;
562
- }
563
- }
564
- let allClosedDays = spaceSchedule.common_closed_days;
565
- // If schedule for period is external, filter out all common dates since they do not apply
566
- if (!!isExternal)
567
- allClosedDays = allClosedDays.filter((d) => d.type != 'common');
568
- const isClosed = allClosedDays.some((c) => {
569
- const start = new Date(c.start_date);
570
- const end = c.end_date ? new Date(c.end_date) : start;
571
- start.setFullYear(dateToCheck.getFullYear());
572
- start.setHours(0, 0, 0, 0);
573
- end.setFullYear(dateToCheck.getFullYear());
574
- end.setHours(0, 0, 0, 0);
575
- dateToCheck.setHours(0, 0, 0, 0);
576
- return c.open === false && dateToCheck >= start && dateToCheck <= end && !!c.associated_stores.includes(storeId);
577
- });
578
- return isClosed;
579
- };
580
- exports.dateIsClosedInSchedule = dateIsClosedInSchedule;
581
- /**
582
- * Function checkIfCartTypeHasBlockedDates
583
- * @description checks if type of cart corresponds to a blockedDates array and if array has dates defined
584
- * @param cartData
585
- * @param blockedDates
586
- */
587
- const checkIfCartTypeHasBlockedDates = (cartData, blockedDates) => {
588
- if (!!!cartData || !!!blockedDates || !!!blockedDates.length)
589
- return false;
590
- const cartType = (0, cart_1.getCartType)(cartData);
591
- const sameType = blockedDates.find((blocked) => blocked.cart_type === cartType);
592
- if (!!!sameType)
593
- return false;
594
- return !!sameType.dates && !!sameType.dates.length;
595
- };
596
- exports.checkIfCartTypeHasBlockedDates = checkIfCartTypeHasBlockedDates;
597
- // #endregion
598
- // ------------------------------------------------------------------------------------------
599
- // ------------------------------------------------------------------------------------------
600
- // #region FEES
601
- exports.slugsToCheckFromExpeditionFees = {
602
- pickup: ['frais-preparation-general-beton', 'frais-palette', 'minimum-facturable-commande'],
603
- shipping: [
604
- 'livraison-echantillons',
605
- 'livraison-accessoires',
606
- 'livraison-beton-accessoires',
607
- 'livraison-gazon',
608
- 'frais-de-livraison-vrac',
609
- 'minimum-facturable-commande'
610
- ]
611
- };
612
- const getPalletQty = (items, orderType, minQteGrassOrder = 0) => {
613
- const total = (0, sumBy_1.default)(items.map((item) => {
614
- if (!!!item.other_units ||
615
- !!item.is_service ||
616
- !!item.is_sample ||
617
- (!!orderType &&
618
- !!['grass'].includes(orderType) &&
619
- (0, products_2.checkIfIsNonSpecialityGrass)(item.sku, item.parent_slug || '', true) &&
620
- !!item.is_upsell_of_sku)) {
621
- return 0;
622
- }
623
- const paletteUnit = item.other_units.find((u) => u.unit_slug === 'pal');
624
- const sellUnitCheck = item.other_units.find((u) => !!u.is_sale_unit);
625
- let sellUnit = 1;
626
- if (!!sellUnitCheck) {
627
- sellUnit = !!sellUnitCheck.fitting_unit ? sellUnitCheck.fitting_unit : 1;
628
- }
629
- if (!!!paletteUnit || !!!paletteUnit.fitting_unit) {
630
- return 0;
631
- }
632
- const typeAttr = item.attributes[data_4.AttributesIdEnumGR.TYPE];
633
- if (!!!typeAttr || !!!typeAttr.length) {
634
- return 0;
635
- }
636
- // If item is an accessory
637
- if (!!typeAttr && !typeAttr.includes('gazon') && !typeAttr.includes('beton')) {
638
- return (0, floor_1.default)((item.qte * sellUnit) / paletteUnit.fitting_unit);
639
- }
640
- // If is grass and minQteGrassOrder is defined
641
- if (!!typeAttr.includes('gazon') && !!minQteGrassOrder && item.qte < minQteGrassOrder) {
642
- return minQteGrassOrder / paletteUnit.fitting_unit;
643
- }
644
- return (item.qte * sellUnit) / paletteUnit.fitting_unit;
645
- }));
646
- if (orderType === 'concrete') {
647
- return (0, ceil_1.default)(total);
648
- }
649
- return total;
650
- };
651
- exports.getPalletQty = getPalletQty;
652
- // Retourne un nombre de frais de palettes à ajouter au panier selon la vraie quantité de palettes calculées pour les produits de gazon
653
- const getGrassRoundedPickupPalletFees = (realPalletNumber) => {
654
- // More than 400 square feet of grass needs another pallet
655
- const ratio = (0, round_1.default)(400 / 740, 3);
656
- // Get only the decimals from the real calculated pallet number, if the decimal is bigger than 400 / 740, round up
657
- const fraction = (0, round_1.default)(realPalletNumber % 1, 3);
658
- if (fraction >= ratio)
659
- return (0, ceil_1.default)(realPalletNumber);
660
- return (0, floor_1.default)(realPalletNumber);
661
- };
662
- exports.getGrassRoundedPickupPalletFees = getGrassRoundedPickupPalletFees;
663
- const getPalletQtyPalletFee = (items, expeditionMethod, isGrass, isMixed) => {
664
- let totalPalletGrass = 0;
665
- let totalPalletOther = 0;
666
- // For this fee specifically, remove all accessories before calculating palQty
667
- items = items.filter((i) => !(0, products_2.checkIfProductIsOfType)(i, 'accessoire'));
668
- if (!!isGrass) {
669
- const grassItemsToCheck = !!isMixed ? items.filter((i) => !!(0, products_2.checkIfProductIsOfType)(i, 'gazon', true)) : items;
670
- const calculatedPalletsGrass = (0, exports.getPalletQty)(grassItemsToCheck, 'grass');
671
- totalPalletGrass =
672
- expeditionMethod === 'pickup'
673
- ? (0, exports.getGrassRoundedPickupPalletFees)(calculatedPalletsGrass)
674
- : (0, ceil_1.default)(calculatedPalletsGrass);
675
- }
676
- if (!!!isGrass || !!isMixed) {
677
- const otherItemsToCheck = !!isMixed ? items.filter((i) => !!!(0, products_2.checkIfProductIsOfType)(i, 'gazon', true)) : items;
678
- totalPalletOther = (0, exports.calculatePalFeeForOtherThanGrass)(otherItemsToCheck);
679
- }
680
- const totalPallet = totalPalletGrass + totalPalletOther;
681
- return totalPallet;
682
- };
683
- exports.getPalletQtyPalletFee = getPalletQtyPalletFee;
684
- const calculatePalFeeForOtherThanGrass = (items) => {
685
- const total = (0, sumBy_1.default)(items.map((item) => {
686
- if (!!!item.other_units || !!item.is_service || !!item.is_sample) {
687
- return 0;
688
- }
689
- const exceptions = [
690
- 'muret-supra-citadin-180',
691
- 'muret-m-100-serie-moderne-double-face',
692
- 'muret-ora-double-face',
693
- 'pas-japonais-grand',
694
- 'marche-nueva',
695
- 'marche-aria',
696
- 'marche-t-200',
697
- 'marche-solino',
698
- 'marche-caralina',
699
- 'marche-rio-15',
700
- 'marche-appalaches',
701
- 'marche-citadin',
702
- 'marche-laurentien',
703
- 'marche-m-100-serie-moderne',
704
- 'marche-citadin-180',
705
- 'marche-ora',
706
- 'marche-t-100-serie-traditionnelle',
707
- 'marche-prestige-180'
708
- ];
709
- const itemIsException = item.parent_slug && exceptions.includes(item.parent_slug);
710
- const palUnit = item.other_units.find((u) => u.unit_slug === 'pal');
711
- const rgUnit = item.other_units.find((u) => u.unit_slug === 'rg');
712
- const unitUnit = item.other_units.find((u) => !!u.fitting_unit && u.fitting_unit === 1);
713
- const sellUnitCheck = item.other_units.find((u) => !!u.is_sale_unit);
714
- let sellUnit = 1;
715
- if (!!sellUnitCheck) {
716
- sellUnit = !!sellUnitCheck.fitting_unit ? sellUnitCheck.fitting_unit : 1;
717
- }
718
- const typeAttr = item.attributes[data_4.AttributesIdEnumGR.TYPE];
719
- // --------------------------------------------------
720
- // 1. If not all units are defined
721
- // if no palUnit or no typeAttr
722
- if (!!!palUnit || !!!palUnit.fitting_unit || !!!typeAttr || !!!typeAttr.length) {
723
- if (!!itemIsException)
724
- return 1;
725
- // if no rgUnit, can't calculate pallet amount
726
- if (!!!rgUnit || !!!rgUnit.fitting_unit) {
727
- return 0;
728
- }
729
- else {
730
- const nbRang = (item.qte * sellUnit) / rgUnit.fitting_unit;
731
- // if has quantities but rang amount is lower than 1, return 0
732
- if (nbRang > 0 && nbRang <= 1) {
733
- return 0;
734
- }
735
- else {
736
- return 1;
737
- }
738
- }
739
- }
740
- // --------------------------------------------------
741
- // 2. If is accessory
742
- if (!!typeAttr && !typeAttr.includes('gazon') && !typeAttr.includes('beton')) {
743
- return (0, floor_1.default)((item.qte * sellUnit) / palUnit.fitting_unit);
744
- }
745
- const palQty = (item.qte * sellUnit) / (palUnit.fitting_unit || 1);
746
- const rgQty = !!rgUnit ? (item.qte * sellUnit) / (rgUnit.fitting_unit || 1) : 0;
747
- const unitQty = !!unitUnit ? (item.qte * sellUnit) / (unitUnit.fitting_unit || 1) : !!sellUnit ? item.qte : 0;
748
- // --------------------------------------------------
749
- // 3. Calculate pal quantities
750
- // RULES:
751
- // - 1 pal = 1 pal
752
- // - 1 pal + 1 rang = 1 pal
753
- // - 1 pal + 2 rang = 2 pal
754
- // - 1 pal + 1 rang + 1 unité = 2 pals
755
- // - 1 pal + 1 unité = 1 pal
756
- // - 0 pal :
757
- // - If less than or equals 1 rang (or equivalent in units) = 0 pal (excluding exceptions)
758
- // - More thant 1 rang (or equivalent in units) = 1 pal
759
- let totalPal = (0, floor_1.default)(palQty);
760
- const unitsInRg = !!rgUnit ? rgUnit.fitting_unit || 0 : 0;
761
- const unitsInPal = palUnit.fitting_unit || 0;
762
- // if qte gives round number of pallets, return totalPal
763
- if (item.qte / unitsInPal === totalPal)
764
- return totalPal;
765
- // if rgQty and rgUnit are defined
766
- if (!!rgQty && !!rgUnit) {
767
- const rgInPal = (palUnit.fitting_unit || 1) / (rgUnit.fitting_unit || 1);
768
- // if palQty is higher than 1 and at least 2 rang extra
769
- if (palQty >= 1 && (0, ceil_1.default)(rgQty % rgInPal) >= 2) {
770
- totalPal += 1;
771
- }
772
- else {
773
- if (palQty < 1) {
774
- if (!!unitQty) {
775
- // if item is in exception list and at least 1 unit extra
776
- if (!!itemIsException && unitQty % unitsInPal !== 0) {
777
- totalPal += 1;
778
- }
779
- else if (!!unitsInRg && unitQty > unitsInRg && unitQty / unitsInRg > 1) {
780
- // if unit count does not equal rang count and total unit count is higher than rang count
781
- totalPal += 1;
782
- }
783
- }
784
- }
785
- }
786
- }
787
- else {
788
- if (!!unitQty && !!itemIsException) {
789
- if (unitQty % unitsInPal !== 0) {
790
- totalPal += 1;
791
- }
792
- }
793
- }
794
- return totalPal;
795
- }));
796
- return total;
797
- };
798
- exports.calculatePalFeeForOtherThanGrass = calculatePalFeeForOtherThanGrass;
799
- const getMinGrassQte = (_grassProduct, expeditionMethod, _isPro) => {
800
- let minQteGrassOrder = 0;
801
- // if (!![kentucky, prestige].includes(grassProduct.sku)) {
802
- // if (expeditionMethod !== 'pickup') {
803
- // minQteGrassOrder = !!isPro ? 1480 : 740
804
- // }
805
- // } else {
806
- // // Grass product is Speciality Grass
807
- // if (expeditionMethod === 'pickup') {
808
- // minQteGrassOrder = 740
809
- // } else {
810
- // minQteGrassOrder = !!isPro ? 1480 : 740
811
- // }
812
- // }
813
- // MODIF AVEC FRAIS 2024 - Même minimum facturable pour tous les gazons, et tous les clients
814
- // Toujours 0 pour la cueillette (pas de minimum), et 740 en livraison
815
- if (expeditionMethod != 'pickup') {
816
- minQteGrassOrder = 740; // 1 pallet
817
- }
818
- return minQteGrassOrder;
819
- };
820
- exports.getMinGrassQte = getMinGrassQte;
821
- const getMinQteInstall = (_isPro) => {
822
- // return !!isPro ? 2220 : 740
823
- // MODIF AVEC FRAIS 2024 - Même minimum facturable pour tous les clients pour l'installation
824
- return 740;
825
- };
826
- exports.getMinQteInstall = getMinQteInstall;
827
- const resetAllFeesIfAccessoriesOnly = (currentItems) => {
828
- const slugsToDelete = [
829
- 'livraison-gazon',
830
- 'minimum-facturable-commande',
831
- 'surcharge-jour-meme-gazon',
832
- 'livraison-beton-accessoires',
833
- 'frais-preparation-general-beton',
834
- 'frais-commande-beton-pas-en-ligne',
835
- 'frais-preparation',
836
- 'surcharges-installation-gazon',
837
- 'surcharges-commandes-gazon',
838
- 'surcharges-commandes-gazon-debut-fin-saison',
839
- 'surcharge-gazon-ramassage-hors-ferme',
840
- 'frais-commande-gazon-pas-en-ligne',
841
- ...products_3.fuelSurchargeSlugs
842
- ];
843
- let itemsToDelete = [];
844
- for (let i of currentItems) {
845
- if (!!i.parent_slug && !!slugsToDelete.includes(i.parent_slug))
846
- itemsToDelete.push(i.sku);
847
- }
848
- return itemsToDelete;
849
- };
850
- const checkIfShouldApplySameDayGrassFee = (firstDayForExpedition, expeditionMethod, selectedExpeditionDate, testDate // for unit test. To test holiday + hour after 4PM
851
- ) => {
852
- // a. Check min date for expedition type (for POS carts)
853
- const dateToCheck = expeditionMethod === 'pickup' ? firstDayForExpedition.min_pickup : firstDayForExpedition.min_delivery;
854
- const dateSelectedIsBeforeFirstCalculatedDay = !!dateToCheck && (0, moment_1.default)((0, data_3.formatDate)(selectedExpeditionDate)).isBefore((0, moment_1.default)(dateToCheck), 'date');
855
- // b. Check if current day is a holiday
856
- const isHoliday = (0, data_1.getHolidays)().some((h) => (0, moment_1.default)(h).isSame(testDate ? (0, moment_1.default)(testDate) : (0, moment_1.default)(), 'date'));
857
- // c. Check if current time is after 4PM
858
- const isAfter4PM = (!!testDate ? (0, moment_1.default)(testDate) : (0, moment_1.default)()).hour() >= 16;
859
- // d. Check if date selected is tomorrow
860
- const dateSelectedForExpeditionIsTomorrowOrToday = (0, moment_1.default)(selectedExpeditionDate).isSameOrBefore((0, moment_1.default)().add(1, 'day'), 'date');
861
- // If date selected is before first calculated date for expedition,
862
- // or order was created after 4PM/on a holiday and selected date for expedition is the next day,
863
- // apply fees
864
- return (!!dateSelectedIsBeforeFirstCalculatedDay ||
865
- ((!!isHoliday || !!isAfter4PM) && !!dateSelectedForExpeditionIsTomorrowOrToday));
866
- };
867
- exports.checkIfShouldApplySameDayGrassFee = checkIfShouldApplySameDayGrassFee;
868
- const checkForSameGrassDayFee = (isPOS, isPro, totalPallet, grassProduct, selectedExepeditionDate, isReserved) => {
869
- if (!!isReserved)
870
- return false;
871
- return !!selectedExepeditionDate && !!grassProduct && totalPallet >= 4 && (!!isPOS || !!isPro);
872
- };
873
- exports.checkForSameGrassDayFee = checkForSameGrassDayFee;
874
- // Correspond to the qte after which the expedition or installation fee should be reapplied
875
- // Eg. For each group of 24 pallets of a product, an expedition fee is added to the cart
876
- exports.expeditionFeePalletTier = 24;
877
- exports.installationFeePalletTier = 48;
878
- /**
879
- * Calculates fees that should be applied to provided cart, and fetches them from database or fee array if provided.
880
- * Returns the items to add, update and delete, as well as other cart info to set after fees.
881
- * ** Optimized version possible, where address zones and distance are calculated before and properties are sent directly to function
882
- * ** Optimized version reverted, logic found in commit here : [#2087b32]{@link https://github.com/ciaoqc/gng-tb-admin-sdk/commit/2087b3207df9e5916a979b8bb255abc2a4c1dac6}
883
- * @async
884
- * @param fetchProduct
885
- * @param getIfAddressIsInsideZones
886
- * @param getDistanceFromAddress
887
- * @param cart
888
- * @param expeditionMethod
889
- * @param grassProduct
890
- * @param concreteOrder
891
- * @param cartContainsInstallation
892
- * @param cartContainsVrac
893
- * @param availableVracStoreIDs
894
- * @param isPro
895
- * @param addOnePalletToPickup
896
- * @param cartContainsSample
897
- * @param saveToShippingPayload
898
- * @param deliveryAddress
899
- * @param locale
900
- * @param expeditionDate
901
- * @param equipmentPickupOnSite
902
- * @param cartContainsOnlyAccessories
903
- * @param pickupStore
904
- * @param allStores
905
- * @param customPriceList
906
- * @param useFeeArray
907
- */
908
- const applyFeesToCart = async (fetchProduct, getIfAddressIsInsideZones, getDistanceFromAddress, cart, expeditionMethod, grassProduct, concreteOrder, cartContainsInstallation, cartContainsVrac, availableVracStoreIDs, isPro, addOnePalletToPickup, cartContainsSample, saveToShippingPayload, deliveryAddress, locale, expeditionDate, equipmentPickupOnSite, cartContainsOnlyAccessories, pickupStore, allStores, customPriceList, useFeeArray) => {
909
- let itemsToAdd = [];
910
- let itemsToDelete = [];
911
- let itemsToUpdate = [];
912
- let newShippingPayload = cart.shipping_payload || {};
913
- // Pour le minimum facturable de la livraison
914
- let minQteGrassOrder = 0;
915
- if (!!grassProduct) {
916
- minQteGrassOrder = (0, exports.getMinGrassQte)(grassProduct, expeditionMethod, isPro);
917
- }
918
- // Vérification du type du cart
919
- const isPOS = [Cart_1.CartTypeEnum.POS, Cart_1.CartTypeEnum.POS_TRANSACTIONNAL].includes(cart.cart_type);
920
- const isMixed = cart.cart_content_type === Cart_1.CartContentTypeEnum.MIXED;
921
- let totalPalletOther = 0;
922
- let totalPalletGrass = 0;
923
- if (!!concreteOrder) {
924
- const concreteItemsToCheck = !!isMixed
925
- ? cart.items.filter((i) => !!!(0, products_2.checkIfProductIsOfType)(i, 'gazon', true))
926
- : cart.items;
927
- totalPalletOther = (0, exports.getPalletQty)(concreteItemsToCheck, 'concrete');
928
- }
929
- if (!!grassProduct) {
930
- const grassItemsToCheck = !!isMixed && !!concreteOrder ? cart.items.filter((i) => !!(0, products_2.checkIfProductIsOfType)(i, 'gazon', true)) : cart.items;
931
- totalPalletGrass = (0, exports.getPalletQty)(grassItemsToCheck, 'grass');
932
- }
933
- const totalPallet = totalPalletGrass + totalPalletOther;
934
- const totalPalletMinQte = (0, exports.getPalletQty)(cart.items, !!concreteOrder ? 'concrete' : !!grassProduct ? 'grass' : undefined, minQteGrassOrder);
935
- // Pour le minimum facturable de l'installation
936
- const minQteInstall = (0, exports.getMinQteInstall)(!!isPro);
937
- // Type de cart (en ligne, en magasin, avec un commis, etc...)
938
- const cartType = !!isPOS ? 'in_store' : !!cart.clerk_id ? 'with_clerk' : 'online';
939
- const installAllInclusiveActive = (0, products_2.isInstallAllInclusiveActive)(cartContainsInstallation, isPro, customPriceList);
940
- // --------------------------------------------------------------------------------------------------
941
- // #region FRAIS PALETTE
942
- // --------------------------------------------------------------------------------------------------
943
- const shouldAddPaletFees = !!!cartContainsInstallation && !!!cartContainsSample && !!!cartContainsVrac;
944
- if ((!!isMixed || !!shouldAddPaletFees) && (!!isPro || !!!grassProduct) && !!!cartContainsOnlyAccessories) {
945
- let qtyOfSkuNeeded = (0, exports.getPalletQtyPalletFee)(cart.items, expeditionMethod, !!(0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.GRASS, cart), isMixed);
946
- if (!!addOnePalletToPickup && expeditionMethod === 'pickup') {
947
- qtyOfSkuNeeded += 1;
948
- }
949
- if (!!addOnePalletToPickup && !!!useFeeArray && !!saveToShippingPayload) {
950
- newShippingPayload = Object.assign(Object.assign({}, newShippingPayload), { addOnePalletToPickup: true });
951
- }
952
- const productToAdd = await fetchProduct('frais-palette', locale, !!useFeeArray, true);
953
- if (!!productToAdd && !!productToAdd.declinations) {
954
- const palletFeeDecli = productToAdd.declinations[0];
955
- if (!!qtyOfSkuNeeded) {
956
- itemsToAdd.push(Object.assign(Object.assign({}, productToAdd.declinations[0]), { qte: qtyOfSkuNeeded, parent_slug: productToAdd.slug, is_upsell_of_sku: 'summary', categories: productToAdd.categories }));
957
- }
958
- else if (cart.items.some((i) => i.sku === palletFeeDecli.sku)) {
959
- itemsToDelete.push(palletFeeDecli.sku);
960
- }
961
- }
962
- }
963
- // #endregion FRAIS PALETTE
964
- // --------------------------------------------------------------------------------------------------
965
- // #region COMMANDE GAZON - FRAIS DE LIVRAISON
966
- // --------------------------------------------------------------------------------------------------
967
- if (!!grassProduct) {
968
- if (expeditionMethod === 'delivery') {
969
- const parentProduct = await fetchProduct('livraison-gazon', locale, !!useFeeArray, true);
970
- const product3 = parentProduct
971
- ? parentProduct.declinations.find((decli) => ['17000000T'].includes(decli.sku))
972
- : undefined;
973
- const product4_15 = parentProduct
974
- ? parentProduct.declinations.find((decli) => decli.sku === '170000000')
975
- : undefined;
976
- const product16 = parentProduct
977
- ? parentProduct.declinations.find((decli) => decli.sku === '170000160')
978
- : undefined;
979
- const add = (product, qty) => {
980
- if (!!product) {
981
- const alreadyToAdd = (0, findIndex_1.default)(itemsToAdd, (i) => i.sku === product.sku);
982
- if (alreadyToAdd === -1) {
983
- itemsToAdd.push(Object.assign(Object.assign({}, product), { is_upsell_of_sku: 'summary', qte: qty, parent_slug: 'livraison-gazon' }));
984
- }
985
- else {
986
- itemsToAdd[alreadyToAdd] = Object.assign(Object.assign(Object.assign({}, itemsToAdd[alreadyToAdd]), { is_upsell_of_sku: 'summary', qte: itemsToAdd[alreadyToAdd].qte + qty, parent_slug: 'livraison-gazon' }), (!!parentProduct ? { categories: parentProduct.categories } : {}));
987
- }
988
- }
989
- };
990
- const addRestQty = (pallets) => {
991
- if (pallets > 0 && pallets < 4) {
992
- add(product3, 1);
993
- }
994
- if (pallets >= 4 && pallets < 16) {
995
- add(product4_15, 1);
996
- }
997
- if (pallets >= 16) {
998
- add(product16, 1);
999
- }
1000
- };
1001
- if (totalPalletMinQte <= exports.expeditionFeePalletTier) {
1002
- addRestQty(totalPalletMinQte);
1003
- }
1004
- else {
1005
- const qty4AndMore = (0, floor_1.default)(totalPalletMinQte / exports.expeditionFeePalletTier);
1006
- const rest = (0, ceil_1.default)(totalPalletMinQte % exports.expeditionFeePalletTier);
1007
- add(product16, qty4AndMore);
1008
- addRestQty(rest);
1009
- }
1010
- }
1011
- cart.items
1012
- .filter((i) => i.parent_slug === 'livraison-gazon')
1013
- .map((item) => {
1014
- if (!itemsToAdd.map((i) => i.sku).includes(item.sku) || expeditionMethod === 'pickup') {
1015
- itemsToDelete.push(item.sku);
1016
- }
1017
- return;
1018
- });
1019
- }
1020
- // #endregion COMMANDE GAZON - FRAIS DE LIVRAISON
1021
- // --------------------------------------------------------------------------------------------------
1022
- // #region COMMANDE BETON - FRAIS DE LIVRAISON
1023
- // --------------------------------------------------------------------------------------------------
1024
- if (!!!cartContainsVrac && !!!cartContainsSample && !!!grassProduct && !!!cartContainsOnlyAccessories) {
1025
- if (expeditionMethod === 'delivery') {
1026
- const parentProduct = await fetchProduct('livraison-beton-accessoires', locale, !!useFeeArray, true);
1027
- const product1To5 = parentProduct
1028
- ? parentProduct.declinations.find((decli) => decli.sku === '170060450')
1029
- : undefined;
1030
- const product6To11 = parentProduct
1031
- ? parentProduct.declinations.find((decli) => decli.sku === '170060650')
1032
- : undefined;
1033
- const product12AndMore = parentProduct
1034
- ? parentProduct.declinations.find((decli) => decli.sku === '170060000')
1035
- : undefined;
1036
- const add = (product, qty) => {
1037
- if (!!product) {
1038
- const alreadyToAdd = (0, findIndex_1.default)(itemsToAdd, (i) => i.sku === product.sku);
1039
- if (alreadyToAdd === -1) {
1040
- itemsToAdd.push(Object.assign(Object.assign({}, product), { is_upsell_of_sku: 'summary', parent_slug: 'livraison-beton-accessoires', qte: qty }));
1041
- }
1042
- else {
1043
- itemsToAdd[alreadyToAdd] = Object.assign(Object.assign(Object.assign({}, itemsToAdd[alreadyToAdd]), { is_upsell_of_sku: 'summary', qte: itemsToAdd[alreadyToAdd].qte + qty, parent_slug: 'livraison-beton-accessoires' }), (!!parentProduct ? { categories: parentProduct.categories } : {}));
1044
- }
1045
- }
1046
- };
1047
- const addRestQty = (pallets) => {
1048
- switch (true) {
1049
- case pallets > 0 && pallets <= 5:
1050
- add(product1To5, 1);
1051
- return;
1052
- case pallets > 5 && pallets < 12:
1053
- add(product6To11, 1);
1054
- return;
1055
- case pallets >= 12:
1056
- add(product12AndMore, 1);
1057
- return;
1058
- }
1059
- };
1060
- if (totalPalletOther <= exports.expeditionFeePalletTier) {
1061
- addRestQty(totalPalletOther);
1062
- }
1063
- else {
1064
- const qty4AndMore = (0, floor_1.default)(totalPalletMinQte / exports.expeditionFeePalletTier);
1065
- const rest = (0, ceil_1.default)(totalPalletOther) % exports.expeditionFeePalletTier;
1066
- add(product12AndMore, qty4AndMore);
1067
- addRestQty(rest);
1068
- }
1069
- }
1070
- cart.items
1071
- .filter((i) => i.parent_slug === 'livraison-beton-accessoires')
1072
- .map((item) => {
1073
- if (!itemsToAdd.map((i) => i.sku).includes(item.sku) || expeditionMethod === 'pickup') {
1074
- itemsToDelete.push(item.sku);
1075
- }
1076
- return;
1077
- });
1078
- }
1079
- // #endregion COMMANDE BETON - FRAIS DE LIVRAISON
1080
- // --------------------------------------------------------------------------------------------------
1081
- // #region COMMANDE GAZON - MINIMUM FACTURABLE
1082
- // --------------------------------------------------------------------------------------------------
1083
- if (!!grassProduct) {
1084
- // In this case, prestige is included in speciality grasses, since the fee must include kentucky price too
1085
- const isSpecialityGrass = !!grassProduct && !!!(0, products_2.checkIfIsNonSpecialityGrass)(grassProduct.sku, grassProduct.slug, true);
1086
- const qtyToAdd = minQteGrassOrder - grassProduct.qte;
1087
- if (qtyToAdd > 0) {
1088
- const product = await fetchProduct('minimum-facturable-commande', locale, !!useFeeArray, true);
1089
- if (!!product) {
1090
- const decli = product.declinations.find((d) => d.sku === '010010000-M');
1091
- if (!!decli) {
1092
- let price = grassProduct.price;
1093
- if (!!isSpecialityGrass) {
1094
- const isKentucky = cart.items.find((i) => (0, products_2.checkIfIsNonSpecialityGrass)(i.sku, i.parent_slug || '', true));
1095
- price = isKentucky ? price + (0, products_4.getLowestPrice)(isKentucky).price.amount : price;
1096
- }
1097
- let minGrassQteItem = Object.assign(Object.assign({}, decli), { regular_price: Object.assign(Object.assign({}, decli.regular_price), { amount: price }) });
1098
- if (!!isPro && !!customPriceList) {
1099
- minGrassQteItem = (0, g2_1.checkForCustomPriceEquivalent)(Object.assign(Object.assign({}, minGrassQteItem), { price_override: true }), customPriceList);
1100
- }
1101
- itemsToAdd.push(Object.assign(Object.assign({}, minGrassQteItem), { is_upsell_of_sku: 'summary', parent_slug: product.slug, price_override: true, qte: qtyToAdd, categories: product.categories }));
1102
- }
1103
- }
1104
- }
1105
- const minimumBillable = cart.items.find((i) => i.parent_slug === 'minimum-facturable-commande');
1106
- if (qtyToAdd <= 0 && !!minimumBillable) {
1107
- itemsToDelete.push(minimumBillable.sku);
1108
- }
1109
- }
1110
- // #endregion COMMANDE GAZON - MINIMUM FACTURABLE
1111
- // --------------------------------------------------------------------------------------------------
1112
- // #region COMMANDE GAZON - SURCHARGE JOUR MÊME
1113
- // --------------------------------------------------------------------------------------------------
1114
- const sameDayGrassFee = await fetchProduct('surcharge-jour-meme-gazon', locale, !!useFeeArray, true);
1115
- let decli;
1116
- if (!!sameDayGrassFee) {
1117
- decli = sameDayGrassFee.declinations.find((d) => d.sku === '000010990');
1118
- }
1119
- if (!!(0, exports.checkForSameGrassDayFee)(isPOS, isPro, totalPalletGrass, grassProduct, expeditionDate, (0, object_1.recursiveCheckObject)(cart.shipping_payload, 'is_reserved'))) {
1120
- // a. Fetch min date for expedition type (for POS carts)
1121
- const firstDayForExpedition = (0, exports.getMinDatePicker)(cart, grassProduct, undefined, expeditionMethod || 'delivery', !!isPro, !!cart.created_by ? (0, data_3.formatDate)(cart.created_by.date) : undefined, undefined, undefined, isPOS);
1122
- // b. Call function to get if fee should be applied
1123
- const shouldApplySameDayFee = (0, exports.checkIfShouldApplySameDayGrassFee)(firstDayForExpedition, expeditionMethod, expeditionDate);
1124
- if (!!sameDayGrassFee && !!decli) {
1125
- if (!!shouldApplySameDayFee) {
1126
- itemsToAdd.push(Object.assign(Object.assign({}, decli), { is_upsell_of_sku: 'summary', parent_slug: sameDayGrassFee.slug, price_override: true, qte: !!grassProduct ? grassProduct.qte : 1, categories: sameDayGrassFee.categories }));
1127
- }
1128
- }
1129
- }
1130
- if (!!sameDayGrassFee && !!decli) {
1131
- if (!!cart.items.some((i) => i.sku === decli.sku)) {
1132
- itemsToDelete.push(decli.sku);
1133
- }
1134
- }
1135
- // #endregion COMMANDE GAZON - SURCHARGE JOUR MÊME
1136
- // --------------------------------------------------------------------------------------------------
1137
- // #region LIVRAISON ÉCHANTILLONS
1138
- // --------------------------------------------------------------------------------------------------
1139
- if (!!cartContainsSample) {
1140
- let removeShippingFee = false;
1141
- if (expeditionMethod === 'delivery') {
1142
- let productToAdd = await fetchProduct('livraison-echantillons', locale, !!useFeeArray, true);
1143
- try {
1144
- removeShippingFee = await (0, exports.checkIfShouldRemoveSampleShippingFee)(fetchProduct, cart, locale, !!useFeeArray);
1145
- }
1146
- catch (e) {
1147
- console.log('error on checking if should remove sample shipping fee: ', e.toString());
1148
- }
1149
- if (!!removeShippingFee) {
1150
- productToAdd = undefined;
1151
- }
1152
- if (!!productToAdd && !!productToAdd.declinations) {
1153
- itemsToAdd.push(Object.assign(Object.assign({}, productToAdd.declinations[0]), { qte: 1, is_upsell_of_sku: 'summary', parent_slug: productToAdd.slug, categories: productToAdd.categories }));
1154
- }
1155
- }
1156
- const sampleDeliveryFee = cart.items.find((i) => i.parent_slug === 'livraison-echantillons');
1157
- if ((expeditionMethod === 'pickup' || !!removeShippingFee) && !!sampleDeliveryFee) {
1158
- itemsToDelete.push(sampleDeliveryFee.sku);
1159
- }
1160
- }
1161
- // #endregion LIVRAISON ÉCHANTILLONS
1162
- // --------------------------------------------------------------------------------------------------
1163
- // #region LIVRAISON ACCESSOIRES
1164
- // --------------------------------------------------------------------------------------------------
1165
- const cartAccessoriesDeliveryFee = cart.items.find((i) => i.parent_slug === 'livraison-accessoires');
1166
- if (!!cartContainsOnlyAccessories) {
1167
- // reset all service fees associated to grass or beton carts, if found
1168
- itemsToDelete = resetAllFeesIfAccessoriesOnly(cart.items);
1169
- // check to add delivery fee
1170
- if (expeditionMethod === 'delivery') {
1171
- const productToAdd = await fetchProduct('livraison-accessoires', locale, !!useFeeArray, true);
1172
- if (!!productToAdd && !!productToAdd.declinations) {
1173
- itemsToAdd.push(Object.assign(Object.assign({}, productToAdd.declinations[0]), { qte: 1, is_upsell_of_sku: 'summary', parent_slug: productToAdd.slug, categories: productToAdd.categories }));
1174
- }
1175
- }
1176
- if (expeditionMethod === 'pickup' && !!cartAccessoriesDeliveryFee) {
1177
- itemsToDelete.push(cartAccessoriesDeliveryFee.sku);
1178
- }
1179
- }
1180
- else {
1181
- if (!!cartAccessoriesDeliveryFee) {
1182
- itemsToDelete.push(cartAccessoriesDeliveryFee.sku);
1183
- }
1184
- }
1185
- // #endregion LIVRAISON ACCESSOIRES
1186
- // --------------------------------------------------------------------------------------------------
1187
- // #region COMMANDE GAZON - SURCHARGE DE PRIX DE GAZON
1188
- // --------------------------------------------------------------------------------------------------
1189
- // Les surcharges sur le gazon s'appliquent toujours pour les pros, ou juste dans le cas de commandes d'une palette ou plus pour les clients au détail
1190
- const shouldApplyFees = !!isPro || totalPalletGrass >= 1;
1191
- if (!!grassProduct) {
1192
- const feesToAdd = [];
1193
- let orderDate = expeditionDate;
1194
- let pickupStoreId = '';
1195
- if (!!pickupStore && !!pickupStore.id) {
1196
- pickupStoreId = pickupStore.id;
1197
- }
1198
- else {
1199
- const shipping_address = cart.shipping_address;
1200
- if (!!shipping_address) {
1201
- const pickupStore = allStores.find((store) => store.address.postal_code === shipping_address.address.postal_code);
1202
- if (!!pickupStore && !!pickupStore.id) {
1203
- pickupStoreId = pickupStore.id;
1204
- }
1205
- }
1206
- }
1207
- let surchargesCommandesGazon = undefined;
1208
- let surchargesCommandesGazonDebutFinSaison = undefined;
1209
- let surchargesInstallationGazon = undefined;
1210
- let surchargesInstallationGazonDebutFinSaison = undefined;
1211
- let surchargesGazonPickupHorsFerme = undefined;
1212
- let fraisSiCommandePasEnLigne = undefined;
1213
- try {
1214
- surchargesCommandesGazon = await fetchProduct('surcharges-commandes-gazon', locale, !!useFeeArray, true);
1215
- }
1216
- catch (e) {
1217
- console.log('error on fetching product: ', e.toString());
1218
- }
1219
- try {
1220
- surchargesCommandesGazonDebutFinSaison = await fetchProduct('surcharges-commandes-gazon-debut-fin-saison', locale, !!useFeeArray, true);
1221
- }
1222
- catch (e) {
1223
- console.log('error on fetching product: ', e.toString());
1224
- }
1225
- try {
1226
- surchargesInstallationGazon = await fetchProduct('surcharges-installation-gazon', locale, !!useFeeArray, true);
1227
- }
1228
- catch (e) {
1229
- console.log('error on fetching product: ', e.toString());
1230
- }
1231
- try {
1232
- surchargesInstallationGazonDebutFinSaison = await fetchProduct('surcharges-installation-gazon-debut-fin-saison', locale, useFeeArray, true);
1233
- }
1234
- catch (e) {
1235
- console.log('error on fetching product: ', e.toString());
1236
- }
1237
- try {
1238
- surchargesGazonPickupHorsFerme = await fetchProduct('surcharge-gazon-ramassage-hors-ferme', locale, !!useFeeArray, true);
1239
- }
1240
- catch (e) {
1241
- console.log('error on fetching product: ', e.toString());
1242
- }
1243
- try {
1244
- fraisSiCommandePasEnLigne =
1245
- cartType === 'online' || expeditionMethod === 'pickup'
1246
- ? undefined
1247
- : await fetchProduct('frais-commande-gazon-pas-en-ligne', locale, !!useFeeArray, true);
1248
- }
1249
- catch (e) {
1250
- console.log('error on fetching product: ', e.toString());
1251
- }
1252
- if (!!orderDate) {
1253
- const addSku = (sku, product) => {
1254
- const decli = product.declinations.find((i) => i.sku === sku);
1255
- if (!!decli) {
1256
- feesToAdd.push(Object.assign(Object.assign({}, decli), { qte: !!product.slug.includes('installation') && grassProduct.qte < minQteInstall
1257
- ? minQteInstall
1258
- : (!!product.slug.includes('commandes-gazon') ||
1259
- ['frais-commande-gazon-pas-en-ligne', 'surcharge-gazon-ramassage-hors-ferme'].includes(product.slug)) &&
1260
- grassProduct.qte < minQteGrassOrder
1261
- ? minQteGrassOrder
1262
- : grassProduct.qte, is_upsell_of_sku: 'summary', parent_slug: product.slug, other_units: decli.other_units }));
1263
- }
1264
- };
1265
- let allOrderFees = [];
1266
- let allInstallationFees = [];
1267
- if (!!shouldApplyFees) {
1268
- // ---------------------------------------------------
1269
- // #region Si la date de la commande est ...
1270
- if (!!surchargesCommandesGazon) {
1271
- // ... un samedi et que la commande est en livraison OU en pickup dans un magasin qui n'est pas rattaché à uen gazonnière
1272
- if (orderDate.getDay() === 6) {
1273
- if (expeditionMethod === 'delivery') {
1274
- allOrderFees.push(['000010400', surchargesCommandesGazon]);
1275
- }
1276
- else {
1277
- if (!!!data_2.grassFarmStores.includes(pickupStoreId)) {
1278
- allOrderFees.push(['000010400', surchargesCommandesGazon]);
1279
- }
1280
- }
1281
- }
1282
- // ... un dimanche ou jours fériés officiels
1283
- // NOTE: seulement pour le frais gazon, celui d'installation s'applique indépendemment plus bas dans la logique
1284
- if ((0, moment_1.default)(orderDate).day() === 0 ||
1285
- (0, data_1.getHolidays)().some((date) => (0, moment_1.default)(date).isSame((0, moment_1.default)(orderDate), 'day'))) {
1286
- allOrderFees = [...allOrderFees, ['000010850', surchargesCommandesGazon]];
1287
- }
1288
- // ... dans les vacances de construction
1289
- const cd = (0, data_1.getContructionHolidays)();
1290
- if ((0, moment_1.default)(orderDate).isBetween((0, moment_1.default)(cd[0]), (0, moment_1.default)(cd[1]), 'day', '[]')) {
1291
- allOrderFees = [...allOrderFees, ['000010860', surchargesCommandesGazon]];
1292
- }
1293
- // ... en été
1294
- const summer = (0, data_1.getSummerDate)();
1295
- if ((0, moment_1.default)(orderDate).isBetween((0, moment_1.default)(summer[0]), (0, moment_1.default)(summer[1]), 'day', '[]')) {
1296
- allOrderFees = [...allOrderFees, ['000010300', surchargesCommandesGazon]];
1297
- }
1298
- }
1299
- // #endregion
1300
- // ---------------------------------------------------
1301
- // ---------------------------------------------------
1302
- // #region Si la date de commande se trouve entre (inclusif)...
1303
- // NOTE : les frais d'installation ne doivent seulement s'appliquer pour les clients pros (POS et WEB)
1304
- const shouldAddGrassSeasonFee = !!surchargesCommandesGazonDebutFinSaison;
1305
- const shouldAddInstallSeasonFee = !!cartContainsInstallation && !!isPro && !!surchargesInstallationGazonDebutFinSaison;
1306
- // ...début de la saison au 30 avril
1307
- if ((0, moment_1.default)(orderDate).isBetween(`${(0, moment_1.default)().format('YYYY')}-03-01`, `${(0, moment_1.default)().format('YYYY')}-04-30`, 'day', '[]')) {
1308
- if (shouldAddGrassSeasonFee)
1309
- allOrderFees = [...allOrderFees, ['000010100', surchargesCommandesGazonDebutFinSaison]];
1310
- if (shouldAddInstallSeasonFee)
1311
- allInstallationFees.push(['000010600', surchargesInstallationGazonDebutFinSaison]);
1312
- }
1313
- // ...15 oct. au 31 oct.
1314
- if ((0, moment_1.default)(orderDate).isBetween(`${(0, moment_1.default)().format('YYYY')}-10-15`, `${(0, moment_1.default)().format('YYYY')}-10-31`, 'day', '[]')) {
1315
- if (shouldAddGrassSeasonFee)
1316
- allOrderFees = [...allOrderFees, ['000010840', surchargesCommandesGazonDebutFinSaison]];
1317
- if (shouldAddInstallSeasonFee)
1318
- allInstallationFees.push(['000010940', surchargesInstallationGazonDebutFinSaison]);
1319
- }
1320
- //...1er nov. au 14 nov.
1321
- if ((0, moment_1.default)(orderDate).isBetween(`${(0, moment_1.default)().format('YYYY')}-11-01`, `${(0, moment_1.default)().format('YYYY')}-11-14`, 'day', '[]')) {
1322
- if (shouldAddGrassSeasonFee)
1323
- allOrderFees = [...allOrderFees, ['000010700', surchargesCommandesGazonDebutFinSaison]];
1324
- if (shouldAddInstallSeasonFee)
1325
- allInstallationFees.push(['000010800', surchargesInstallationGazonDebutFinSaison]);
1326
- }
1327
- // ...15 nov. à la fin de la saison
1328
- if ((0, moment_1.default)(orderDate).isBetween(`${(0, moment_1.default)().format('YYYY')}-11-15`, `${(0, moment_1.default)().format('YYYY')}-12-31`, 'day', '[]')) {
1329
- if (shouldAddGrassSeasonFee)
1330
- allOrderFees = [...allOrderFees, ['000010900', surchargesCommandesGazonDebutFinSaison]];
1331
- if (shouldAddInstallSeasonFee)
1332
- allInstallationFees.push(['000010950', surchargesInstallationGazonDebutFinSaison]);
1333
- }
1334
- // #endregion
1335
- // ---------------------------------------------------
1336
- // Si la commande est en pick-up et le magazin n'est pas une gazonnière
1337
- if (expeditionMethod === 'pickup' && !!surchargesGazonPickupHorsFerme) {
1338
- if (!!!data_2.grassFarmStores.includes(pickupStoreId)) {
1339
- allOrderFees = [...allOrderFees, ['000012500', surchargesGazonPickupHorsFerme]];
1340
- }
1341
- }
1342
- }
1343
- // Si la commande a de l'installation et la date de la commande est un dimanche ou un jour férié
1344
- if (!!surchargesInstallationGazon &&
1345
- !!cartContainsInstallation &&
1346
- ((0, moment_1.default)(orderDate).day() === 0 ||
1347
- (0, data_1.getHolidays)().some((date) => (0, moment_1.default)(date).isSame((0, moment_1.default)(orderDate), 'day')))) {
1348
- allInstallationFees.push(['000010750', surchargesInstallationGazon]);
1349
- }
1350
- // Si la commande a été faite autrement qu'en ligne ET ne contient pas d'installation (PROS ONLY)
1351
- if (!!fraisSiCommandePasEnLigne && !!!cartContainsInstallation && !!isPro) {
1352
- allOrderFees = [...allOrderFees, ['FRSGAZON', fraisSiCommandePasEnLigne]];
1353
- }
1354
- allOrderFees.map((fee) => {
1355
- addSku(fee[0], fee[1]);
1356
- });
1357
- allInstallationFees.map((fee) => {
1358
- addSku(fee[0], fee[1]);
1359
- });
1360
- }
1361
- itemsToAdd = [...itemsToAdd, ...feesToAdd];
1362
- }
1363
- if (!!grassProduct || !!isMixed) {
1364
- cart.items.forEach((i) => {
1365
- if (!!i.parent_slug &&
1366
- [
1367
- 'surcharges-commandes-gazon',
1368
- 'surcharges-commandes-gazon-debut-fin-saison',
1369
- 'surcharges-installation-gazon',
1370
- 'surcharges-installation-gazon-debut-fin-saison',
1371
- 'surcharge-gazon-ramassage-hors-ferme',
1372
- 'frais-commande-gazon-pas-en-ligne'
1373
- ].includes(i.parent_slug)) {
1374
- itemsToDelete.push(i.sku);
1375
- }
1376
- });
1377
- }
1378
- // #endregion SURCHARGE DE PRIX DE GAZON
1379
- // --------------------------------------------------------------------------------------------------
1380
- // #region SURCHARGE CARBURANT TEMPORAIRE - COÛTS DE PRODUCTION GAZON
1381
- // 1¢/pi² sur gazon Kentucky, livraison ET cueillette, pro seulement
1382
- // La surcharge s'applique dès que du Kentucky est présent (directement ou comme gazon base)
1383
- const isGrassEligibleForFuelSurcharge = cart.items.some((i) => (0, products_2.checkIfIsNonSpecialityGrass)(i.sku, i.parent_slug || '', true));
1384
- // L'activation/désactivation est contrôlée par l'état draft du produit
1385
- const fuelGazonProd = !!grassProduct && isGrassEligibleForFuelSurcharge && isPro && !!!cart.is_booking
1386
- ? await fetchProduct(products_3.fuelSurchargeGazonSlug, locale, !!useFeeArray, true)
1387
- : undefined;
1388
- if (!!fuelGazonProd && !!grassProduct) {
1389
- let fuelGazonDecli = fuelGazonProd.declinations.find((d) => d.sku === products_3.fuelSurchargeGazonSku);
1390
- if (!!fuelGazonDecli) {
1391
- if (!!customPriceList) {
1392
- fuelGazonDecli = (0, g2_1.checkForCustomPriceEquivalent)(fuelGazonDecli, customPriceList);
1393
- }
1394
- if (!(0, products_2.shouldHideItemIfRegPriceIs0)(fuelGazonDecli, fuelGazonProd.slug, false)) {
1395
- itemsToAdd.push(Object.assign(Object.assign({}, fuelGazonDecli), { qte: grassProduct.qte < minQteGrassOrder ? minQteGrassOrder : grassProduct.qte, is_upsell_of_sku: 'summary', parent_slug: fuelGazonProd.slug, categories: fuelGazonProd.categories }));
1396
- }
1397
- }
1398
- }
1399
- else {
1400
- cart.items
1401
- .filter((i) => i.sku === products_3.fuelSurchargeGazonSku)
1402
- .forEach((i) => itemsToDelete.push(i.sku));
1403
- }
1404
- // #endregion SURCHARGE CARBURANT TEMPORAIRE - COÛTS DE PRODUCTION GAZON
1405
- // --------------------------------------------------------------------------------------------------
1406
- // #region COMMANDE BÉTON - FRAIS DE PRÉPARATION
1407
- // --------------------------------------------------------------------------------------------------
1408
- if (!!concreteOrder && !!!cartContainsSample && !!!cartContainsOnlyAccessories) {
1409
- // ----------------------------------------------------------------------------------------------
1410
- // Frais de préparation général
1411
- // MODIF FRAIS 2024 - Ajout du frais FP-1 seulement si le panier contient un minimum de 1 palette de produits de béton
1412
- // Vérifie vraiment que les produits de béton pour la quantité
1413
- const fraisPreparationGeneralBeton = await fetchProduct('frais-preparation-general-beton', locale, !!useFeeArray, true);
1414
- const onlyConcretePalQty = (0, exports.getPalletQty)(cart.items.filter((i) => (0, products_2.checkIfProductIsOfType)(i, 'beton', true)));
1415
- if (!!fraisPreparationGeneralBeton && onlyConcretePalQty >= 1) {
1416
- const decli = fraisPreparationGeneralBeton.declinations.find((i) => i.sku === 'FP-1');
1417
- if (!!decli) {
1418
- itemsToAdd.push(Object.assign(Object.assign({}, decli), { qte: 1, is_upsell_of_sku: 'summary', parent_slug: fraisPreparationGeneralBeton.slug, categories: fraisPreparationGeneralBeton.categories }));
1419
- }
1420
- }
1421
- // ----------------------------------------------------------------------------------------------
1422
- // Frais si commande pas en ligne/par un commis
1423
- if (expeditionMethod !== 'pickup' && cartType !== 'online' && !!isPro) {
1424
- const getFeeAmount = (decli) => {
1425
- // fee is a percentage of price for each item that isn't a service or fee
1426
- // percentage is determined by FRSBETON regular_price.value
1427
- const percent = (0, toNumber_1.default)(decli.regular_price.amount);
1428
- let amount = 0;
1429
- for (let item of cart.items) {
1430
- if (!!item.is_service)
1431
- continue;
1432
- if (!!customPriceList) {
1433
- item = (0, g2_1.checkForCustomPriceEquivalent)(item, customPriceList);
1434
- }
1435
- const itemPrice = (0, products_4.getLowestPrice)(item).price.amount;
1436
- amount += itemPrice * item.qte * percent;
1437
- }
1438
- return (0, round_1.default)(amount, 3);
1439
- };
1440
- const feeProd = await fetchProduct('frais-commande-beton-pas-en-ligne', locale, !!useFeeArray, true);
1441
- if (!!feeProd) {
1442
- const skuToAdd = (feeProd.declinations || []).find((d) => d.sku === 'FRSBETON');
1443
- if (!!skuToAdd) {
1444
- itemsToAdd.push(Object.assign(Object.assign({}, skuToAdd), { qte: 1, parent_slug: feeProd.slug, is_upsell_of_sku: 'summary', regular_price: Object.assign(Object.assign({}, skuToAdd.regular_price), { amount: getFeeAmount(skuToAdd), price_type: (0, round_1.default)((0, toNumber_1.default)(skuToAdd.regular_price.amount) * 100, 2).toString() }), price_override: true, categories: feeProd.categories }));
1445
- }
1446
- }
1447
- }
1448
- else {
1449
- if (cart.items.some((item) => item.sku === 'FRSBETON')) {
1450
- itemsToDelete.push('FRSBETON');
1451
- }
1452
- }
1453
- // ----------------------------------------------------------------------------------------------
1454
- // Frais de préparation si commande contient 4 palettes incomplètes
1455
- const concreteItems = cart.items.filter((i) => i.attributes[data_4.AttributesIdEnumGR.TYPE] && i.attributes[data_4.AttributesIdEnumGR.TYPE].includes('beton'));
1456
- let numberOfIncompletePallets = 0;
1457
- for (const item of concreteItems) {
1458
- if (!!!item.other_units)
1459
- continue;
1460
- const saleUnit = item.other_units.find((unit) => unit.is_sale_unit);
1461
- const palUnit = item.other_units.find((unit) => unit.unit_slug === 'pal');
1462
- if (!!!saleUnit || !!!saleUnit.fitting_unit || !!!palUnit || !!!palUnit.fitting_unit)
1463
- continue;
1464
- const calculatedPal = saleUnit.fitting_unit * item.qte;
1465
- const rest = (0, round_1.default)(calculatedPal, 3) % (0, round_1.default)(palUnit.fitting_unit, 3);
1466
- if (!!rest) {
1467
- numberOfIncompletePallets++;
1468
- }
1469
- }
1470
- if (numberOfIncompletePallets >= 4) {
1471
- const surchargesCommandesBeton = await fetchProduct('frais-preparation', locale, !!useFeeArray, true);
1472
- if (!!surchargesCommandesBeton) {
1473
- const decli = surchargesCommandesBeton.declinations.find((i) => i.sku === 'FP4');
1474
- if (!!decli) {
1475
- itemsToAdd.push(Object.assign(Object.assign({}, decli), { qte: 1, is_upsell_of_sku: 'summary', parent_slug: surchargesCommandesBeton.slug, categories: surchargesCommandesBeton.categories }));
1476
- }
1477
- }
1478
- }
1479
- else {
1480
- const prepItem = cart.items.find((item) => item.parent_slug === 'frais-preparation');
1481
- if (!!prepItem) {
1482
- itemsToDelete.push(prepItem.sku);
1483
- }
1484
- }
1485
- }
1486
- else {
1487
- if (cart.items.some((item) => item.sku === 'FP-1')) {
1488
- itemsToDelete.push('FP-1');
1489
- }
1490
- if (cart.items.some((item) => item.sku === 'FRSBETON')) {
1491
- itemsToDelete.push('FRSBETON');
1492
- }
1493
- }
1494
- // #endregion COMMANDE BÉTON - FRAIS DE PRÉPARATION
1495
- // --------------------------------------------------------------------------------------------------
1496
- // #region FRAIS LIVRAISON SELON L'EMPLACEMENT
1497
- // --------------------------------------------------------------------------------------------------
1498
- let isOutOfArea = false;
1499
- if (expeditionMethod === 'delivery' && !!deliveryAddress) {
1500
- let insideZones = undefined;
1501
- try {
1502
- insideZones = await getIfAddressIsInsideZones(deliveryAddress);
1503
- }
1504
- catch (e) {
1505
- console.log('error on fetching zones for address: ', e.toString());
1506
- }
1507
- if (!!insideZones && !!Array.isArray(insideZones)) {
1508
- if (!!insideZones.length && insideZones.includes('zone-gr')) {
1509
- // =============================================================================================
1510
- // TOUS TYPES DE COMMANDE
1511
- // Si une ou plusieurs zones correspondent
1512
- let productInstallToAdd;
1513
- if (!!grassProduct) {
1514
- productInstallToAdd = !!cartContainsInstallation
1515
- ? await fetchProduct('surcharges-installation-gazon', locale, !!useFeeArray, true)
1516
- : undefined;
1517
- }
1518
- const productToAdd = await fetchProduct('surcharges-commandes-gazon', locale, !!useFeeArray, true);
1519
- if (insideZones.includes('zone-mtl')) {
1520
- if (!!productToAdd) {
1521
- const mtl = productToAdd.declinations.find((i) => i.sku === '170050000');
1522
- if (!!mtl) {
1523
- itemsToAdd.push(Object.assign(Object.assign({}, mtl), { qte: (0, ceil_1.default)((0, ceil_1.default)(totalPallet) / exports.expeditionFeePalletTier), is_upsell_of_sku: 'summary', parent_slug: 'surcharges-commandes-gazon', categories: productToAdd.categories }));
1524
- }
1525
- }
1526
- // If Installation ...
1527
- if (!!grassProduct && !!productInstallToAdd) {
1528
- const mtlInstall = productInstallToAdd.declinations.find((i) => i.sku === '170055500');
1529
- if (!!mtlInstall) {
1530
- itemsToAdd.push(Object.assign(Object.assign({}, mtlInstall), { qte: (0, ceil_1.default)(totalPalletGrass / exports.installationFeePalletTier), is_upsell_of_sku: 'summary', parent_slug: 'surcharges-installation-gazon', categories: productInstallToAdd.categories }));
1531
- }
1532
- }
1533
- }
1534
- if (insideZones.includes('zone-ontario')) {
1535
- if (!!productToAdd) {
1536
- const ontario = productToAdd.declinations.find((i) => i.sku === '170000ONT');
1537
- if (!!ontario) {
1538
- itemsToAdd.push(Object.assign(Object.assign({}, ontario), { qte: (0, ceil_1.default)((0, ceil_1.default)(totalPallet) / exports.expeditionFeePalletTier), is_upsell_of_sku: 'summary', parent_slug: 'surcharges-commandes-gazon', categories: productToAdd.categories }));
1539
- }
1540
- }
1541
- // If Installation ...
1542
- if (!!grassProduct && !!productInstallToAdd) {
1543
- const ontarioInstall = productInstallToAdd.declinations.find((i) => i.sku === '170033ONT');
1544
- if (!!ontarioInstall) {
1545
- itemsToAdd.push(Object.assign(Object.assign({}, ontarioInstall), { qte: (0, ceil_1.default)(totalPalletGrass / exports.installationFeePalletTier), is_upsell_of_sku: 'summary', parent_slug: 'surcharges-installation-gazon', categories: productInstallToAdd.categories }));
1546
- }
1547
- }
1548
- }
1549
- if (insideZones.includes('zone-ile-orleans')) {
1550
- if (!!productToAdd) {
1551
- const ileOrleans = productToAdd.declinations.find((i) => i.sku === '170000418');
1552
- if (!!ileOrleans) {
1553
- itemsToAdd.push(Object.assign(Object.assign({}, ileOrleans), { qte: (0, ceil_1.default)((0, ceil_1.default)(totalPallet) / exports.expeditionFeePalletTier), is_upsell_of_sku: 'summary', parent_slug: 'surcharges-commandes-gazon', categories: productToAdd.categories }));
1554
- }
1555
- }
1556
- }
1557
- // }
1558
- // =============================================================================================
1559
- // COMMANDES VRAC
1560
- // Infos pour la livraison du vrac, vérification faite maintenant dans deux zones
1561
- if (!!cartContainsVrac) {
1562
- if (insideZones.includes('zone-vrac') || insideZones.includes('zone-vrac-les-coteaux')) {
1563
- const deliveryTruckProduct = await fetchProduct('frais-de-livraison-vrac', locale, !!useFeeArray, true);
1564
- // Fetch de l'adresse du magasin de la zone concernée, pour calculer le prix du frais de livraison
1565
- const storeIDToCheck = insideZones.includes('zone-vrac') ? 'sainte-julie-nobel' : 'default';
1566
- const storeAddress = getStoreAddressByID(allStores, storeIDToCheck);
1567
- // Si le magasin de la zone ne se trouve pas dans le array de magasins disponibles pour les produits de vrac de la commande,
1568
- // mettre la commande comme hors-zone automatiquement
1569
- if (!!availableVracStoreIDs && !availableVracStoreIDs.includes(storeIDToCheck)) {
1570
- isOutOfArea = true;
1571
- }
1572
- else if (!!deliveryTruckProduct && !!storeAddress) {
1573
- let distance = null;
1574
- try {
1575
- distance = await getDistanceFromAddress(storeAddress, deliveryAddress);
1576
- }
1577
- catch (_) {
1578
- console.log(_);
1579
- }
1580
- if (distance === null) {
1581
- isOutOfArea = true;
1582
- }
1583
- else {
1584
- itemsToAdd = [
1585
- ...itemsToAdd,
1586
- ...(0, exports.calculateShippingForVrac)(distance, cart.items, deliveryTruckProduct, itemsToAdd, expeditionDate)
1587
- ];
1588
- }
1589
- }
1590
- }
1591
- else {
1592
- isOutOfArea = true;
1593
- }
1594
- }
1595
- }
1596
- else {
1597
- isOutOfArea = true;
1598
- }
1599
- }
1600
- }
1601
- cart.items.forEach((i) => {
1602
- if (!!i.parent_slug && ['frais-de-livraison-vrac', 'surcharges-commandes-gazon'].includes(i.parent_slug)) {
1603
- itemsToDelete.push(i.sku);
1604
- }
1605
- });
1606
- // #endregion FRAIS LIVRAISON SELON L'EMPLACEMENT
1607
- // --------------------------------------------------------------------------------------------------
1608
- // #region RAMASSAGE D'ÉQUIPEMENT SUR LE CHANTIER
1609
- // --------------------------------------------------------------------------------------------------
1610
- if (!!equipmentPickupOnSite) {
1611
- // consoleLog({ equipmentPickupOnSite: 'true' })
1612
- }
1613
- // #endregion RAMASSAGE D'ÉQUIPEMENT SUR LE CHANTIER
1614
- // --------------------------------------------------------------------------------------------------
1615
- // #region FRAIS EXTRA LIVRAISON EN PÉRIODE DE DÉGEL
1616
- const degelFeeSku = '170000018';
1617
- if (!!isPro &&
1618
- expeditionMethod === 'delivery' &&
1619
- !!!cartContainsSample &&
1620
- !!!cartContainsVrac &&
1621
- !!expeditionDate &&
1622
- !!isDegel(expeditionDate)) {
1623
- const degelFeeProd = await fetchProduct('frais-livraison-periode-degel', locale, !!useFeeArray, true);
1624
- if (!!degelFeeProd) {
1625
- const degelFeeDecli = degelFeeProd.declinations.find((d) => d.sku === degelFeeSku);
1626
- if (!!degelFeeDecli) {
1627
- itemsToAdd.push(Object.assign(Object.assign({}, degelFeeDecli), { qte: 1, is_upsell_of_sku: 'summary', parent_slug: degelFeeProd.slug, categories: degelFeeProd.categories }));
1628
- }
1629
- }
1630
- }
1631
- else {
1632
- if (!!cart.items.some((i) => i.sku === degelFeeSku)) {
1633
- itemsToDelete.push(degelFeeSku);
1634
- }
1635
- }
1636
- // #endregion
1637
- // --------------------------------------------------------------------------------------------------
1638
- // #region SURCHARGE CARBURANT TEMPORAIRE - LIVRAISON
1639
- // 95$ par tranche de 24 palettes, pro seulement, pas de booking
1640
- const fuelLivraisonProd = isPro &&
1641
- !!!cart.is_booking &&
1642
- itemsToAdd.some((i) => !!i.parent_slug &&
1643
- ['livraison-gazon', 'livraison-beton-accessoires'].includes(i.parent_slug))
1644
- ? await fetchProduct(products_3.fuelSurchargeLivraisonSlug, locale, !!useFeeArray, true)
1645
- : undefined;
1646
- if (!!fuelLivraisonProd) {
1647
- let fuelLivraisonDecli = fuelLivraisonProd.declinations.find((d) => d.sku === products_3.fuelSurchargeLivraisonSku);
1648
- if (!!fuelLivraisonDecli) {
1649
- if (!!customPriceList) {
1650
- fuelLivraisonDecli = (0, g2_1.checkForCustomPriceEquivalent)(fuelLivraisonDecli, customPriceList);
1651
- }
1652
- if (!(0, products_2.shouldHideItemIfRegPriceIs0)(fuelLivraisonDecli, fuelLivraisonProd.slug, false)) {
1653
- itemsToAdd.push(Object.assign(Object.assign({}, fuelLivraisonDecli), { qte: (0, ceil_1.default)(totalPallet / exports.expeditionFeePalletTier) || 1, is_upsell_of_sku: 'summary', parent_slug: fuelLivraisonProd.slug, categories: fuelLivraisonProd.categories }));
1654
- }
1655
- }
1656
- }
1657
- else {
1658
- cart.items
1659
- .filter((i) => i.sku === products_3.fuelSurchargeLivraisonSku)
1660
- .forEach((i) => itemsToDelete.push(i.sku));
1661
- }
1662
- // #endregion SURCHARGE CARBURANT TEMPORAIRE - LIVRAISON
1663
- // --------------------------------------------------------------------------------------------------
1664
- // #region SURCHARGE CARBURANT TEMPORAIRE - MOBILISATION
1665
- // 95$ par tranche de 48 palettes, pro seulement
1666
- const fuelMobilisationProd = isPro &&
1667
- cartContainsInstallation &&
1668
- !!!cart.is_booking &&
1669
- cart.items.some((i) => i.parent_slug === 'frais-de-mobilisation')
1670
- ? await fetchProduct(products_3.fuelSurchargeMobilisationSlug, locale, !!useFeeArray, true)
1671
- : undefined;
1672
- if (!!fuelMobilisationProd) {
1673
- let fuelMobilisationDecli = fuelMobilisationProd.declinations.find((d) => d.sku === products_3.fuelSurchargeMobilisationSku);
1674
- if (!!fuelMobilisationDecli) {
1675
- if (!!customPriceList) {
1676
- fuelMobilisationDecli = (0, g2_1.checkForCustomPriceEquivalent)(fuelMobilisationDecli, customPriceList);
1677
- }
1678
- if (!(0, products_2.shouldHideItemIfRegPriceIs0)(fuelMobilisationDecli, fuelMobilisationProd.slug, false)) {
1679
- // Utiliser getPalletQtyPalletFee pour aligner sur le même calcul que les autres frais
1680
- // (gère l'arrondi spécifique livraison vs cueillette de gazon)
1681
- const palletQtyForFee = (0, exports.getPalletQtyPalletFee)(cart.items, expeditionMethod, true, isMixed);
1682
- itemsToAdd.push(Object.assign(Object.assign({}, fuelMobilisationDecli), { qte: (0, ceil_1.default)(Math.max(palletQtyForFee, 1) / exports.installationFeePalletTier) || 1, is_upsell_of_sku: 'summary', parent_slug: fuelMobilisationProd.slug, categories: fuelMobilisationProd.categories }));
1683
- }
1684
- }
1685
- }
1686
- else {
1687
- cart.items
1688
- .filter((i) => i.sku === products_3.fuelSurchargeMobilisationSku)
1689
- .forEach((i) => itemsToDelete.push(i.sku));
1690
- }
1691
- // #endregion SURCHARGE CARBURANT TEMPORAIRE - MOBILISATION
1692
- // --------------------------------------------------------------------------------------------------
1693
- // #region Gestion d'ajout / delete des frais
1694
- itemsToDelete = itemsToDelete.filter((i) => !itemsToAdd.map((add) => add.sku).includes(i));
1695
- itemsToAdd = itemsToAdd
1696
- .map((item) => {
1697
- const cartItem = cart.items.find((i) => i.sku === item.sku);
1698
- if (!!cartItem) {
1699
- if (cartItem.qte !== item.qte) {
1700
- itemsToUpdate.push({ sku: item.sku, qte: item.qte });
1701
- return;
1702
- }
1703
- else {
1704
- return;
1705
- }
1706
- }
1707
- else {
1708
- // If fee regular price is 0.00$ and item fits criteria, do not add to cart
1709
- if (!!item.parent_slug &&
1710
- (0, products_2.shouldHideItemIfRegPriceIs0)(item, item.parent_slug, !!item.is_upsell_of_sku && item.parent_slug.includes('installation'))) {
1711
- return;
1712
- }
1713
- }
1714
- // When installation all-inclusive, force frais de livraison to 0$
1715
- return installAllInclusiveActive ? (0, products_2.applyAllInclusiveOverrides)(item) : item;
1716
- })
1717
- .filter((i) => !!i);
1718
- // #endregion Gestion d'ajout / delete des frais
1719
- return {
1720
- newCart: Object.assign(Object.assign({}, cart), { shipping_payload: newShippingPayload }),
1721
- itemsToDelete,
1722
- itemsToUpdate,
1723
- itemsToAdd,
1724
- totalPallet,
1725
- isOutOfArea
1726
- };
1727
- };
1728
- exports.applyFeesToCart = applyFeesToCart;
1729
- // #endregion
1730
- // ------------------------------------------------------------------------------------------
1731
- // ------------------------------------------------------------------------------------------
1732
- // #region SHIPPING
1733
- /**
1734
- * Checks if sample shipping fee should be removed from cart depending on cart items found in cart.
1735
- * ** Optimized version possible using brand name instead of brand id, removing async check.
1736
- * ** Optimized version reverted, logic found in commit here : [#2087b32]{@link https://github.com/ciaoqc/gng-tb-admin-sdk/commit/2087b3207df9e5916a979b8bb255abc2a4c1dac6}
1737
- * @param fetchProduct
1738
- * @param cart
1739
- * @param locale
1740
- * @param useFeeArray
1741
- */
1742
- const checkIfShouldRemoveSampleShippingFee = async (fetchProduct, cart, locale, useFeeArray) => {
1743
- if (!!!cart.items)
1744
- return false;
1745
- const currentItems = cart.items.filter((i) => i.is_sample);
1746
- let currentItemsChecked = [];
1747
- for (let item of currentItems) {
1748
- if (!!!item.parent_slug)
1749
- continue;
1750
- // 1. Get parent product for brand ID
1751
- const parentProd = await fetchProduct(item.parent_slug, locale, !!useFeeArray, true);
1752
- if (!!!parentProd)
1753
- continue;
1754
- const brand = parentProd.brand;
1755
- // 2. Check if item.attributes contains FAMILY attribute with value Tena
1756
- const isTena = !!item.attributes &&
1757
- !!item.attributes[data_4.AttributesIdEnumGR.FAMILY] &&
1758
- !!item.attributes[data_4.AttributesIdEnumGR.FAMILY].includes('tena');
1759
- // 3. Check if item.attributes.TYPE is grass and is not Kentucky or Prestige (both non-speciality grasses)
1760
- // const excludedGrass = [`kentucky`, `prestige`]
1761
- const hasGrassType = (0, products_2.checkIfProductIsOfType)(item, 'gazon');
1762
- const isExcludedGrass = (0, products_2.checkIfIsNonSpecialityGrass)(item.sku, item.parent_slug);
1763
- const isGrass = !!hasGrassType && !!!isExcludedGrass;
1764
- const valuesToCheck = {
1765
- brand: !!brand ? brand : '',
1766
- isTena: isTena,
1767
- isGrass: isGrass
1768
- };
1769
- currentItemsChecked.push(valuesToCheck);
1770
- }
1771
- if (!!currentItemsChecked.length) {
1772
- const allIncludedBrandsNoTena = currentItemsChecked.filter((item) => !!item.brand && !!data_2.includedFreeShippingBrands.includes(item.brand) && !!!item.isTena);
1773
- const allGrass = currentItemsChecked.filter((item) => !!item.isGrass);
1774
- // 3. count all items with included brands and check if length === currentItems.length
1775
- // if true, remove shipping cost (set productToAdd undefined)
1776
- if (currentItems.length === allIncludedBrandsNoTena.length || currentItems.length === allGrass.length) {
1777
- return true;
1778
- }
1779
- else {
1780
- // 4. add IncludedBrandsNoTena + isGrass lengths and check if equals currentItems.length
1781
- // if true, remove shipping cost (set productToAdd undefined)
1782
- const added = allIncludedBrandsNoTena.length + allGrass.length;
1783
- if (added === currentItems.length) {
1784
- return true;
1785
- }
1786
- }
1787
- }
1788
- return false;
1789
- };
1790
- exports.checkIfShouldRemoveSampleShippingFee = checkIfShouldRemoveSampleShippingFee;
1791
- const calculateShippingForVrac = (distance = 0, cartItems, deliveryTruckProduct, currentItemsToAdd, deliveryDate) => {
1792
- let itemsToAdd = [...currentItemsToAdd];
1793
- const allVracItems = cartItems.filter((i) => (0, products_2.checkIfProductIsOfType)(i, 'vrac'));
1794
- for (const vracItem of allVracItems) {
1795
- const totalTons = vracItem.qte;
1796
- const isInDegelPeriod = !!isDegel(deliveryDate);
1797
- const volumeTons = [
1798
- {
1799
- min: 1,
1800
- max: 4
1801
- },
1802
- {
1803
- min: 4,
1804
- max: isInDegelPeriod ? 11 : 15
1805
- },
1806
- {
1807
- min: isInDegelPeriod ? 11 : 15,
1808
- max: isInDegelPeriod ? 16 : 20
1809
- },
1810
- {
1811
- min: isInDegelPeriod ? 16 : 20,
1812
- max: isInDegelPeriod ? 19 : 24
1813
- },
1814
- {
1815
- min: isInDegelPeriod ? 19 : 24,
1816
- max: isInDegelPeriod ? 24 : 30
1817
- }
1818
- ];
1819
- const checkTons = (tons) => {
1820
- let skuToAdd = '';
1821
- switch (true) {
1822
- case tons <= volumeTons[0].max:
1823
- switch (true) {
1824
- case distance >= 0 && distance < 15:
1825
- skuToAdd = '170000615';
1826
- break;
1827
- case distance >= 15 && distance < 30:
1828
- skuToAdd = '170000630';
1829
- break;
1830
- case distance >= 30:
1831
- skuToAdd = '170000660';
1832
- break;
1833
- }
1834
- tons = -1;
1835
- break;
1836
- case tons > volumeTons[1].min && tons <= volumeTons[1].max:
1837
- switch (true) {
1838
- case distance >= 0 && distance < 15:
1839
- skuToAdd = '170001015';
1840
- break;
1841
- case distance >= 15 && distance < 30:
1842
- skuToAdd = '170001030';
1843
- break;
1844
- case distance >= 30:
1845
- skuToAdd = '170001060';
1846
- break;
1847
- }
1848
- tons = -1;
1849
- break;
1850
- case tons > volumeTons[2].min && tons <= volumeTons[2].max:
1851
- switch (true) {
1852
- case distance >= 0 && distance < 15:
1853
- skuToAdd = '170001215';
1854
- break;
1855
- case distance >= 15 && distance < 30:
1856
- skuToAdd = '170001230';
1857
- break;
1858
- case distance >= 30:
1859
- skuToAdd = '170001260';
1860
- break;
1861
- }
1862
- tons = -1;
1863
- break;
1864
- case tons > volumeTons[3].min && tons <= volumeTons[3].max:
1865
- switch (true) {
1866
- case distance >= 0 && distance < 15:
1867
- skuToAdd = '170002015';
1868
- break;
1869
- case distance >= 15 && distance < 30:
1870
- skuToAdd = '170002030';
1871
- break;
1872
- case distance >= 30:
1873
- skuToAdd = '170002060';
1874
- break;
1875
- }
1876
- tons = -1;
1877
- break;
1878
- case tons > volumeTons[4].min:
1879
- switch (true) {
1880
- case distance >= 0 && distance < 15:
1881
- skuToAdd = '170003015';
1882
- break;
1883
- case distance >= 15 && distance < 30:
1884
- skuToAdd = '170003030';
1885
- break;
1886
- case distance >= 30:
1887
- skuToAdd = '170003060';
1888
- break;
1889
- }
1890
- tons = tons - volumeTons[4].max;
1891
- break;
1892
- default:
1893
- tons = -1;
1894
- }
1895
- const decliToAdd = deliveryTruckProduct.declinations.find((d) => d.sku === skuToAdd);
1896
- if (!!decliToAdd) {
1897
- if (!!itemsToAdd.find((item) => item.sku === decliToAdd.sku)) {
1898
- const index = itemsToAdd.findIndex((item) => item.sku === decliToAdd.sku);
1899
- itemsToAdd[index] = Object.assign(Object.assign({}, itemsToAdd[index]), { qte: itemsToAdd[index].qte + 1 });
1900
- }
1901
- else {
1902
- itemsToAdd.push(Object.assign(Object.assign({}, decliToAdd), { parent_slug: 'frais-de-livraison-vrac', qte: 1, is_upsell_of_sku: 'summary', categories: deliveryTruckProduct.categories }));
1903
- }
1904
- }
1905
- if (tons > 0) {
1906
- checkTons(tons);
1907
- }
1908
- };
1909
- checkTons(totalTons);
1910
- }
1911
- return itemsToAdd;
1912
- };
1913
- exports.calculateShippingForVrac = calculateShippingForVrac;
1914
- const getStoresForVracProdShipping = (inventoryItem) => {
1915
- let availability = {};
1916
- for (let vracStore of data_2.vracShippingStores) {
1917
- const sameInInventory = inventoryItem.inventories.find((i) => i.store_id == vracStore);
1918
- availability[vracStore] = !!sameInInventory && !!!sameInInventory.unavailable_in_store;
1919
- }
1920
- return availability;
1921
- };
1922
- exports.getStoresForVracProdShipping = getStoresForVracProdShipping;
1923
- const getStoreAddressByID = (allStores, storeID) => {
1924
- const sameStore = allStores.find((s) => s.id == storeID);
1925
- return !!sameStore ? sameStore.address : undefined;
1926
- };
1927
- // #endregion
1928
- // ------------------------------------------------------------------------------------------
1929
- // ------------------------------------------------------------------------------------------
1930
- // #region VALIDATION
1931
- /**
1932
- * Function checkIfCartExpired
1933
- * @description checks if cart expired using the updated_at date stored in the shipping_payload
1934
- * @param cartData
1935
- * @param grassProduct
1936
- * @param concreteOrder
1937
- * @param isPro
1938
- * @param options.blocked_shipping_dates
1939
- * @param options.vracType
1940
- * @param options.chosenPaymentType
1941
- * @param options.forceCheckForCartTypes
1942
- */
1943
- const checkIfCartExpired = (cartData, grassProduct, concreteOrder, isPro, options = {}) => {
1944
- // ######################################################################################
1945
- // #region TESTS
1946
- // ----------------------------------------------------------
1947
- // 1) Is same day after 10
1948
- // const test1 = {
1949
- // now: moment().set('hours', 11).toDate(),
1950
- // updated_last: moment().set('hours', 9).toDate(),
1951
- // time: 'AM',
1952
- // selected_date: moment().add(4, 'day').toDate()
1953
- // }
1954
- // 2) Is same day after 10 but with AM still possible
1955
- // const test2 = {
1956
- // now: moment().set({ day: 6, hours: 11 }).toDate(),
1957
- // updated_last: moment().set({ day: 6, hours: 9 }).toDate(),
1958
- // time: 'AM',
1959
- // selected_date: moment().set('day', 9).toDate()
1960
- // }
1961
- // const now = test2.now
1962
- // const updated_last = test2.updated_last
1963
- // const time = test2.time
1964
- // const selected_date = test2.selected_date
1965
- //
1966
- // #endregion
1967
- // ######################################################################################
1968
- const isPOS = Cart_1.CartTypeEnum.WEB != cartData.cart_type;
1969
- const isSample = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.SAMPLE, cartData);
1970
- const isAccessoriesOnly = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.ONLY_ACCESSORIES, cartData);
1971
- // const cartContainsInstallation = checkIfCartContainsType(CartGeneralTypeEnum.INSTALLATION, cartData)
1972
- // 1. Check if it is normal for selected date to be undefined / expired
1973
- const selectedDate = !!cartData.shipping_payload && !!cartData.shipping_payload.delivery_or_pickup_date
1974
- ? (0, data_3.formatDate)(cartData.shipping_payload.delivery_or_pickup_date)
1975
- : undefined;
1976
- const noDeliveryDateIsNormal = (0, exports.checkIfNoDeliveryDateIsNormal)(cartData, concreteOrder) ||
1977
- (!!options.chosenPaymentType && ['depot'].includes(options.chosenPaymentType));
1978
- const shouldForceCheck = (options.forceCheckForCartTypes || []).some((t) => (0, cart_1.checkIfCartContainsType)(t, cartData));
1979
- // If force check property sent, check event if !!noDeliveryDateIsNormal
1980
- if (!!noDeliveryDateIsNormal && !shouldForceCheck) {
1981
- return false;
1982
- }
1983
- else if (!!!selectedDate) {
1984
- return true;
1985
- }
1986
- // 2. Check date depending on when cart was last updated
1987
- const now = (0, moment_1.default)().toDate();
1988
- const updated_last = !!cartData.shipping_payload && !!cartData.shipping_payload.updated_at
1989
- ? (0, data_3.formatDate)(cartData.shipping_payload.updated_at)
1990
- : (0, moment_1.default)().toDate();
1991
- const time = !!cartData.shipping_payload && !!cartData.shipping_payload.delivery_period
1992
- ? cartData.shipping_payload.delivery_period
1993
- : 'PM';
1994
- const minDates = (0, exports.getMinDatePicker)(cartData, grassProduct, concreteOrder, !!cartData.is_pickup ? 'pickup' : 'delivery', !!isPro, updated_last, options.blocked_shipping_dates, options.vracType, isPOS);
1995
- const currentMinDate = !!cartData.is_pickup ? minDates.min_pickup : minDates.min_delivery;
1996
- const ok_hours = (0, exports.getAvailableHours)(currentMinDate, selectedDate, grassProduct, concreteOrder, (!!cartData.is_pickup ? 'pickup' : 'delivery'), time, isPro, isSample, isAccessoriesOnly, updated_last);
1997
- return (!!updated_last &&
1998
- (((0, moment_1.default)(selectedDate).isSameOrBefore(now, 'day') && !!!(0, moment_1.default)(currentMinDate).isSame(now, 'day')) ||
1999
- (0, moment_1.default)(now).isAfter(updated_last, 'day') ||
2000
- (0, moment_1.default)(currentMinDate).isAfter(selectedDate, 'day') ||
2001
- (updated_last.getHours() < 10 &&
2002
- now.getHours() >= 10 &&
2003
- time === 'AM' &&
2004
- !!ok_hours.deliveryTimes.every((d) => d.value == 'PM'))));
2005
- };
2006
- exports.checkIfCartExpired = checkIfCartExpired;
2007
- const checkIfNoDeliveryDateIsNormal = (cartData, concreteOrder, checkForInputShown) => {
2008
- const isAccessoriesOnly = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.ONLY_ACCESSORIES, cartData);
2009
- const isSample = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.SAMPLE, cartData);
2010
- return ((!!!checkForInputShown && !!cartData.shipping_payload && !!cartData.shipping_payload.isOutOfArea) ||
2011
- (!!concreteOrder && concreteOrder.type !== 'green') ||
2012
- ((!!isAccessoriesOnly || !!isSample) && !!!cartData.is_pickup));
2013
- };
2014
- exports.checkIfNoDeliveryDateIsNormal = checkIfNoDeliveryDateIsNormal;
2015
- // #endregion
2016
- // ------------------------------------------------------------------------------------------
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.checkIfNoDeliveryDateIsNormal = exports.checkIfCartExpired = exports.getStoresForVracProdShipping = exports.calculateShippingForVrac = exports.checkIfShouldRemoveSampleShippingFee = exports.applyFeesToCart = exports.installationFeePalletTier = exports.expeditionFeePalletTier = exports.checkForSameGrassDayFee = exports.checkIfShouldApplySameDayGrassFee = exports.getMinQteInstall = exports.getMinGrassQte = exports.calculatePalFeeForOtherThanGrass = exports.getPalletQtyPalletFee = exports.getGrassRoundedPickupPalletFees = exports.getPalletQty = exports.slugsToCheckFromExpeditionFees = exports.checkIfCartTypeHasBlockedDates = exports.dateIsClosedInSchedule = exports.shouldDisableDate = exports.getMinDateOffset = exports.getSamplesMinDateOffset = exports.getMinDatePicker = exports.getAvailableHours = exports.getDefaultTimeValues = void 0;
7
+ const moment_1 = __importDefault(require("moment"));
8
+ const ceil_1 = __importDefault(require("lodash/ceil"));
9
+ const findIndex_1 = __importDefault(require("lodash/findIndex"));
10
+ const floor_1 = __importDefault(require("lodash/floor"));
11
+ const round_1 = __importDefault(require("lodash/round"));
12
+ const sumBy_1 = __importDefault(require("lodash/sumBy"));
13
+ const toNumber_1 = __importDefault(require("lodash/toNumber"));
14
+ // Rule specific interfaces
15
+ const products_1 = require("../interfaces/products");
16
+ // Rule specific functions/constants
17
+ const data_1 = require("./data");
18
+ const products_2 = require("./products");
19
+ const cart_1 = require("./cart");
20
+ const g2_1 = require("./g2");
21
+ const data_2 = require("../constants/data");
22
+ const products_3 = require("../constants/products");
23
+ // General interfaces
24
+ const Cart_1 = require("../../../Interfaces/Cart");
25
+ // General utils
26
+ const data_3 = require("../../../utils/data");
27
+ const products_4 = require("../../../utils/products");
28
+ const cart_2 = require("../interfaces/cart");
29
+ const data_4 = require("../interfaces/data");
30
+ const object_1 = require("../../../utils/object");
31
+ // ------------------------------------------------------------------------------------------
32
+ // #region HOURS
33
+ const getDefaultTimeValues = () => {
34
+ let values = ['AM', 'PM'];
35
+ return values.map((v) => ({ label: v, value: v }));
36
+ };
37
+ exports.getDefaultTimeValues = getDefaultTimeValues;
38
+ const getAvailableHours = (minDeliveryDate, selectedDate, grassProduct, concreteOrder, expeditionMethod, selectedDeliveryTime, isPro, isSample, isAccessoriesOnly, testDate, keepHours) => {
39
+ if (!!!minDeliveryDate)
40
+ return { deliveryTimes: (0, exports.getDefaultTimeValues)() };
41
+ let deliveryTimes = (0, exports.getDefaultTimeValues)().map((t) => t.value);
42
+ const today = !!testDate
43
+ ? !!keepHours
44
+ ? (0, moment_1.default)(testDate).toDate()
45
+ : (0, moment_1.default)(testDate).set('hours', (0, moment_1.default)().hours()).toDate()
46
+ : (0, moment_1.default)().toDate();
47
+ // If concreteOrder and product in stock and is pickup, can select 'now' (AM if before noon, PM if after)
48
+ if (!!concreteOrder && !!concreteOrder.inStock && expeditionMethod === 'pickup') {
49
+ const isPM = today.getHours() >= 12;
50
+ if (!!isPM) {
51
+ deliveryTimes = ['PM'];
52
+ }
53
+ return {
54
+ deliveryTimes: deliveryTimes.map((t) => ({ label: t, value: t })),
55
+ newSelectedDeliveryTime: !!isPM ? { label: 'PM', value: 'PM' } : undefined
56
+ };
57
+ }
58
+ // ------------------------------------------------------------------------------------------------------
59
+ // enable all hours in selection
60
+ const resetHours = (d) => {
61
+ d.setHours(0);
62
+ d.setMinutes(0);
63
+ d.setSeconds(0);
64
+ d.setMilliseconds(0);
65
+ };
66
+ if (!!selectedDate)
67
+ resetHours(selectedDate);
68
+ resetHours(minDeliveryDate);
69
+ let newSelectedDeliveryTime = undefined;
70
+ const targetDateDay = minDeliveryDate.getDay();
71
+ const selectedDateDay = !!selectedDate ? selectedDate.getDay() : targetDateDay;
72
+ const isSelectedSameAsTarget = (0, moment_1.default)(minDeliveryDate).isSame(selectedDate) || !!!selectedDate;
73
+ const todayDay = today.getDay();
74
+ const isNonSpecialityGrass = !!grassProduct && (0, products_2.checkIfIsNonSpecialityGrass)(grassProduct.sku, grassProduct.slug);
75
+ const onlyPm = () => {
76
+ if (!!selectedDeliveryTime && selectedDeliveryTime === 'AM') {
77
+ newSelectedDeliveryTime = { label: 'PM', value: 'PM' };
78
+ }
79
+ deliveryTimes = ['PM'];
80
+ };
81
+ // EDIT - Ajusted logic that excluded saturdays from time selection if not pro to make available if expeditionMethod = shipping [ 03-10-2022 ]
82
+ if (selectedDateDay === 0 || (selectedDateDay === 6 && !!!isPro && expeditionMethod === 'pickup')) {
83
+ deliveryTimes = [];
84
+ newSelectedDeliveryTime = undefined;
85
+ }
86
+ else if (
87
+ // Bug GR-I505 - AM / PM toujours disponnible pour Beton Vert en livraison
88
+ // Bug GR-I511 - Pickup for concrete not in stock only change de available day
89
+ !(!!concreteOrder && concreteOrder.type == 'green' && (!concreteOrder.inStock || expeditionMethod == 'delivery'))) {
90
+ if (isSelectedSameAsTarget) {
91
+ if (!!grassProduct || (!!concreteOrder && concreteOrder.type === 'green')) {
92
+ let todayReset = !!testDate ? (0, moment_1.default)(testDate).toDate() : (0, moment_1.default)().toDate();
93
+ resetHours(todayReset);
94
+ // If today is either saturday of sunday
95
+ if (!![6, 0].includes(todayReset.getDay())) {
96
+ // Two options :
97
+ // - is non-speciality grass OR [ concrete + type green + pickup + not in stock ] and target day is NOT a tuesday
98
+ // - is any other kind of grass and target day is NOT a wednesday or thursday
99
+ if ((![2].includes(targetDateDay) &&
100
+ (!!isNonSpecialityGrass ||
101
+ (!!concreteOrder && !concreteOrder.inStock && expeditionMethod === 'pickup'))) ||
102
+ (![3, 4].includes(targetDateDay) && !!!isNonSpecialityGrass)) {
103
+ // EDIT - Ajusted logic that excluded saturdays from time selection if not pro to make available if expeditionMethod = shipping [ 03-10-2022 ]
104
+ if (targetDateDay === 6 && !!!isPro && expeditionMethod === 'pickup') {
105
+ newSelectedDeliveryTime = undefined;
106
+ deliveryTimes = [];
107
+ }
108
+ else {
109
+ const amTimeToCheck = !!grassProduct && expeditionMethod == 'pickup' ? 12 : 10;
110
+ // Logic ajusted on 08-05-2025 (task #GR-I377 in Sprint) - If grass & pickup, first check starts at noon. If not, at 10am.
111
+ // Check if later than specific AM time
112
+ if (today.getHours() >= amTimeToCheck) {
113
+ onlyPm();
114
+ }
115
+ }
116
+ }
117
+ // If none of the above options are true, both time periods are available to the user
118
+ }
119
+ else {
120
+ // Today is any other day than the weekend
121
+ // Check if later than target hour
122
+ // Logic updated on 08-05-2025, #GR-I377 in Sprint
123
+ let targetHour = !!grassProduct && expeditionMethod == 'pickup' ? 12 : 10;
124
+ // If grass or green concrete pickup, and today is Friday, AM stays available until after 16h
125
+ // Logic updated on 17-02-2025, GR-I150 dans Zoho Sprint
126
+ if (todayDay == 5 &&
127
+ (!!grassProduct || (!!concreteOrder && concreteOrder.type == 'green' && expeditionMethod == 'pickup'))) {
128
+ targetHour = 16;
129
+ }
130
+ if (today.getHours() >= targetHour) {
131
+ onlyPm();
132
+ }
133
+ }
134
+ }
135
+ // If order contains samples or is of any other type than grass or concrete
136
+ if ((!!!grassProduct && !!!concreteOrder) || !!isSample || !!isAccessoriesOnly) {
137
+ // Check if later than 10 AM
138
+ if (today.getHours() > 10) {
139
+ onlyPm();
140
+ }
141
+ }
142
+ }
143
+ }
144
+ return {
145
+ deliveryTimes: deliveryTimes.map((t) => ({ label: t, value: t })),
146
+ newSelectedDeliveryTime: newSelectedDeliveryTime ? newSelectedDeliveryTime : undefined
147
+ };
148
+ };
149
+ exports.getAvailableHours = getAvailableHours;
150
+ // Date de dégel (hardcodée, sera modifiée directement dans le code à la demande des clients)
151
+ const isDegel = (dateToCheck) => {
152
+ let date = !!dateToCheck ? (0, moment_1.default)(dateToCheck) : (0, moment_1.default)();
153
+ return date.isBetween('2024-03-04 00:00:01', '2024-04-15 23:59:59', undefined, '[]');
154
+ };
155
+ /**
156
+ * Function getMinDatePicker
157
+ * @description Sets the minimum shipping day for delivery
158
+ */
159
+ const getMinDatePicker = (cartData, grassProduct, concreteOrder, expeditionMethod, isPro, testDate, blockedShippingDates, vracType, isPOS, spaceSchedule) => {
160
+ const cartContainsInstallation = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.INSTALLATION, cartData);
161
+ const cartContainsVrac = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.VRAC, cartData);
162
+ const isAccessoriesOnly = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.ONLY_ACCESSORIES, cartData);
163
+ let minDates = {};
164
+ if (!!testDate && !isPOS) {
165
+ testDate.setHours((0, moment_1.default)().hours());
166
+ }
167
+ let now = testDate || (0, moment_1.default)().toDate();
168
+ let min_date = testDate || (0, moment_1.default)().toDate();
169
+ // =======================================================================================
170
+ // #region MIN DATE OFFSET
171
+ const nbDaysOffset = (0, exports.getMinDateOffset)(now, cartContainsInstallation, cartContainsVrac, cartData, grassProduct, concreteOrder, isAccessoriesOnly, expeditionMethod, vracType);
172
+ // #endregion
173
+ // =======================================================================================
174
+ // =======================================================================================
175
+ // #region BLOCKED DAYS/DATES
176
+ const typeToCheck = !!concreteOrder
177
+ ? 'beton'
178
+ : !!grassProduct
179
+ ? 'gazon'
180
+ : !!cartContainsVrac || (!!!isPro && !!vracType)
181
+ ? 'vrac'
182
+ : undefined;
183
+ let dateToCheck = new Date(min_date);
184
+ dateToCheck.setDate(min_date.getDate() + nbDaysOffset);
185
+ let pickupDateSameAsNewDate = false;
186
+ // ---------------------------------------------------------------------------------------
187
+ // Check if space has blocked days
188
+ // NEW!!! - For now, blocked days are hardcoded here. Will be moved to space eventually.
189
+ const blockedDays = {
190
+ vrac: [0],
191
+ beton: [0],
192
+ gazon: [0]
193
+ };
194
+ const getNextAvailableDay = (type) => {
195
+ const dayToCheck = dateToCheck.getDay();
196
+ if (!!blockedDays[type]) {
197
+ // Right now we ignore blocked days on pickup because we check the schedules in the space. If days are added to the blockedDays dictionnary, validate that they still shouldn't apply on pickup
198
+ if (blockedDays[type].includes(dayToCheck) && expeditionMethod !== 'pickup') {
199
+ dateToCheck.setDate(dateToCheck.getDate() + 1);
200
+ return getNextAvailableDay(type);
201
+ }
202
+ }
203
+ if (!!spaceSchedule && expeditionMethod === 'pickup') {
204
+ const storeId = (0, object_1.recursiveCheckObject)(cartData, 'shipping_payload.pickup_store.id');
205
+ if (!!storeId && !!(0, exports.dateIsClosedInSchedule)(storeId, dateToCheck, spaceSchedule)) {
206
+ dateToCheck.setDate(dateToCheck.getDate() + 1);
207
+ return getNextAvailableDay(type);
208
+ }
209
+ }
210
+ min_date = dateToCheck;
211
+ min_date.setHours(0);
212
+ min_date.setMinutes(0);
213
+ min_date.setSeconds(0);
214
+ };
215
+ if (!!typeToCheck) {
216
+ getNextAvailableDay(typeToCheck);
217
+ if (typeToCheck === 'vrac') {
218
+ pickupDateSameAsNewDate = true;
219
+ }
220
+ }
221
+ // ---------------------------------------------------------------------------------------
222
+ // Check if space has blocked dates
223
+ if (!!blockedShippingDates && blockedShippingDates.length && !!typeToCheck && expeditionMethod === 'delivery') {
224
+ const blockedDatesToCheck = blockedShippingDates.find((blockedDate) => blockedDate.cart_type === typeToCheck);
225
+ if (!!blockedDatesToCheck && !!blockedDatesToCheck.dates && !!blockedDatesToCheck.dates.length) {
226
+ const isInBlockedPeriod = blockedDatesToCheck.dates.find((blocked) => {
227
+ return (!!blocked.start_date &&
228
+ !!blocked.end_date &&
229
+ (0, moment_1.default)(dateToCheck).isBetween((0, moment_1.default)((0, data_3.formatDate)(blocked.start_date)), (0, moment_1.default)((0, data_3.formatDate)(blocked.end_date)), 'date', '[]'));
230
+ });
231
+ if (!!isInBlockedPeriod) {
232
+ dateToCheck = (0, moment_1.default)((0, data_3.formatDate)(isInBlockedPeriod.end_date)).add(1, 'days').toDate();
233
+ getNextAvailableDay(typeToCheck);
234
+ let pickup_date = !!pickupDateSameAsNewDate ? dateToCheck : (0, moment_1.default)(min_date).toDate();
235
+ return {
236
+ min_delivery: min_date,
237
+ min_pickup: pickup_date
238
+ };
239
+ }
240
+ }
241
+ }
242
+ // #endregion
243
+ // =======================================================================================
244
+ if (!!!concreteOrder || concreteOrder.type !== 'yellow') {
245
+ min_date.setDate(dateToCheck.getDate());
246
+ min_date.setHours(0);
247
+ min_date.setMinutes(0);
248
+ min_date.setSeconds(0);
249
+ let pickup_date = (0, moment_1.default)(min_date).toDate();
250
+ minDates = {
251
+ min_delivery: min_date,
252
+ min_pickup: pickup_date
253
+ };
254
+ }
255
+ return minDates;
256
+ };
257
+ exports.getMinDatePicker = getMinDatePicker;
258
+ const getSamplesMinDateOffset = () => {
259
+ const now = new Date();
260
+ const year = now.getFullYear();
261
+ // December 1st
262
+ const startWinterPeriod = new Date(year, 11, 1); // December == 11
263
+ // March 1st
264
+ const endWinterPeriod = new Date(year + 1, 2, 1); // March == 2
265
+ const isWinterPeriod = (0, moment_1.default)().isBetween((0, moment_1.default)(startWinterPeriod), (0, moment_1.default)(endWinterPeriod), 'day', '[]');
266
+ return isWinterPeriod ? 14 : 7;
267
+ };
268
+ exports.getSamplesMinDateOffset = getSamplesMinDateOffset;
269
+ const getMinDateOffset = (now, cartContainsInstallation, cartContainsVrac, cartData, grassProduct, concreteOrder, isAccessoriesOnly, expeditionMethod, vracType) => {
270
+ const current_hour = now.getHours();
271
+ const current_day = now.getDay();
272
+ let nb_days_offset = 1;
273
+ // Variable to set all grass delays the same as non-speciality grasses (as of now, Kentucky and Prestige).
274
+ // Use this instead of changing all values, in case our clients change their mind later!
275
+ const allGrassDelaysSameAsNonSpecialityGrasses = true;
276
+ // ========================
277
+ // IF INSTALL
278
+ // Install logic adjusted on 01-05-2024 (task #GR7-T429)
279
+ if (!!cartContainsInstallation) {
280
+ // --------------------
281
+ // "Low staff" logic = 96hours delay for first available date
282
+ // switch (current_day) {
283
+ // case 3:
284
+ // nb_days_offset = 5
285
+ // break
286
+ // default:
287
+ // nb_days_offset = 4
288
+ // break
289
+ // }
290
+ // --------------------
291
+ // "Medium staff" logic = 48hours delay for first available date
292
+ switch (current_day) {
293
+ case 5:
294
+ nb_days_offset = 3;
295
+ break;
296
+ default:
297
+ nb_days_offset = 2;
298
+ break;
299
+ }
300
+ // --------------------
301
+ // Regular logic (if fee applies for current year) = 24 hour delay for first available date
302
+ // switch (current_day) {
303
+ // case 5:
304
+ // nb_days_offset = current_hour < 10 ? 1 : 3
305
+ // break
306
+ // case 6:
307
+ // case 0:
308
+ // nb_days_offset = 2
309
+ // break
310
+ // default:
311
+ // nb_days_offset = 1
312
+ // break
313
+ // }
314
+ }
315
+ // ========================
316
+ // IF SAMPLE OR ACCESSORIES ONLY
317
+ else if (cartData.items.find((item) => item.is_sample) || !!isAccessoriesOnly) {
318
+ if (expeditionMethod === 'delivery') {
319
+ nb_days_offset = !!isAccessoriesOnly ? 7 : (0, exports.getSamplesMinDateOffset)();
320
+ }
321
+ else {
322
+ switch (current_day) {
323
+ case 4:
324
+ nb_days_offset = 4;
325
+ break;
326
+ case 5:
327
+ nb_days_offset = current_hour < 10 ? 3 : 4;
328
+ break;
329
+ case 6:
330
+ nb_days_offset = 4;
331
+ break;
332
+ case 0:
333
+ nb_days_offset = 3;
334
+ break;
335
+ default:
336
+ nb_days_offset = 2;
337
+ }
338
+ }
339
+ }
340
+ // ========================
341
+ // IF VRAC PRODUCTS WITH DELIVERY
342
+ else if (expeditionMethod === 'delivery' &&
343
+ !!cartContainsVrac &&
344
+ !!(0, object_1.recursiveCheckObject)(vracType, 'vrac_type') &&
345
+ [products_1.VracTypeEnum.AUTRE_TONNE, products_1.VracTypeEnum.NOBEL_TONNE].includes(vracType.vrac_type)) {
346
+ nb_days_offset = 1;
347
+ }
348
+ // ========================
349
+ // IF BASE GRASS / ALL GRASSES ARE SAME
350
+ else if (!!grassProduct &&
351
+ ((0, products_2.checkIfIsNonSpecialityGrass)(grassProduct.sku, grassProduct.slug) || !!allGrassDelaysSameAsNonSpecialityGrasses)) {
352
+ const amTimeToCheck = !!grassProduct && expeditionMethod == 'pickup' ? 12 : 10;
353
+ // Logic ajusted on 08-05-2025 (task #GR-I377 in Sprint) - If grass & pickup, first check starts at noon. If not, at 10am.
354
+ switch (current_day) {
355
+ case 5:
356
+ nb_days_offset = current_hour < amTimeToCheck ? 1 : current_hour < 16 ? 3 : 3; // earliest is tomorrow if before 10AM, else after tomorrow, not counting the weekend (on fridays)
357
+ // Logic ajusted on 14-02-2025 (task #GR-I151 in Sprint) - New check for between 10h (or 12h if grass&pickup) and 16h
358
+ break;
359
+ case 6:
360
+ nb_days_offset = 3; // earliest is after tomorrow, not counting the weekend (on fridays or saturdays)
361
+ break;
362
+ case 0:
363
+ nb_days_offset = 2; // earliest is after tomorrow, not counting the weekend (on sundays)
364
+ break;
365
+ default:
366
+ nb_days_offset = 1; // earliest is tomorrow
367
+ }
368
+ }
369
+ // ========================
370
+ // IF CONCRETE WITH PICKUP | UNAVAILABLE PRODUCT
371
+ else if (!!concreteOrder &&
372
+ concreteOrder.type === 'green' &&
373
+ !concreteOrder.inStock &&
374
+ expeditionMethod === 'pickup') {
375
+ // 13-08-2025 : Bug GR-I511 - Pickup for concrete not in stock only change the available day
376
+ const amTimeToCheck = 10;
377
+ switch (current_day) {
378
+ case 0:
379
+ nb_days_offset = 2;
380
+ break;
381
+ case 4:
382
+ nb_days_offset = current_hour < amTimeToCheck ? 1 : 4;
383
+ break;
384
+ case 5:
385
+ nb_days_offset = 3;
386
+ break;
387
+ case 6:
388
+ nb_days_offset = current_hour < amTimeToCheck ? 2 : 3;
389
+ break;
390
+ default:
391
+ nb_days_offset = current_hour < amTimeToCheck ? 1 : 2;
392
+ }
393
+ }
394
+ // ========================
395
+ // IF CONCRETE WITH PICKUP | ONLY AVAILABLE PRODUCTS
396
+ else if (!!concreteOrder &&
397
+ concreteOrder.type === 'green' &&
398
+ concreteOrder.inStock &&
399
+ expeditionMethod === 'pickup') {
400
+ nb_days_offset = 0;
401
+ }
402
+ // ========================
403
+ // IF SPECIALITY GRASS
404
+ else if (!!grassProduct && !!!(0, products_2.checkIfIsNonSpecialityGrass)(grassProduct.sku, grassProduct.slug)) {
405
+ switch (current_day) {
406
+ case 5:
407
+ case 6:
408
+ case 0:
409
+ nb_days_offset = 4; // if we are on friday and it's earlier than 10
410
+ break;
411
+ default:
412
+ nb_days_offset = 2; // earliest is after tomorrow
413
+ }
414
+ }
415
+ // ========================
416
+ // IF CONCRETE WITH DELIVERY | ONLY AVAILABLE PRODUCTS
417
+ else if (!!concreteOrder && concreteOrder.type === 'green' && expeditionMethod === 'delivery') {
418
+ switch (current_day) {
419
+ case 0:
420
+ nb_days_offset = 3;
421
+ break;
422
+ case 1:
423
+ case 2:
424
+ case 3:
425
+ nb_days_offset = current_hour < 10 ? 2 : 3;
426
+ break;
427
+ case 4:
428
+ nb_days_offset = current_hour < 10 ? 2 : current_hour < 16 ? 4 : 5;
429
+ // Logic ajusted on 14-02-2025 (task #GR-I151 in Sprint) - New check for between 10h and 16h
430
+ break;
431
+ case 5:
432
+ nb_days_offset = current_hour < 16 ? 4 : 5;
433
+ // Logic ajusted on 14-02-2025 (task #GR-I151 in Sprint) - New check for 16h instead of 10h
434
+ break;
435
+ case 6:
436
+ nb_days_offset = 4;
437
+ break;
438
+ default:
439
+ break;
440
+ }
441
+ }
442
+ // ========================
443
+ // IF ANY PRODUCT WITH DELIVERY THAT DID NOT FIT IN PREVIOUS CATEGORIES
444
+ else if (expeditionMethod === 'delivery') {
445
+ switch (current_day) {
446
+ case 0:
447
+ nb_days_offset = 4;
448
+ break;
449
+ case 1:
450
+ case 2:
451
+ nb_days_offset = current_hour < 10 ? 3 : 4;
452
+ break;
453
+ case 3:
454
+ nb_days_offset = current_hour < 10 ? 3 : 6;
455
+ break;
456
+ case 4:
457
+ case 5:
458
+ nb_days_offset = current_hour < 10 ? 5 : 6;
459
+ break;
460
+ case 6:
461
+ nb_days_offset = 5;
462
+ break;
463
+ default:
464
+ break;
465
+ }
466
+ }
467
+ return nb_days_offset;
468
+ };
469
+ exports.getMinDateOffset = getMinDateOffset;
470
+ /**
471
+ * Function shouldDisableDate
472
+ * @description compares date with blockedDates from DB and blocked days (currently hardcoded in function)
473
+ * @param date - Date to check
474
+ * @param blockedDates - Blocked dates from DB
475
+ * @param expeditionMethod - pickup or shipping
476
+ * @param cartData
477
+ */
478
+ const shouldDisableDate = (date, blockedDates, expeditionMethod, cartData, schedule, selectedStore) => {
479
+ if (!!!cartData)
480
+ return false;
481
+ const typeToCheck = (0, cart_1.getCartType)(cartData);
482
+ // ---------------------------------------------------------------------------------------
483
+ // Blocked days check
484
+ // NEW!!! - For now, blocked days are hardcoded here. Will be moved to space eventually.
485
+ const blockedDays = {
486
+ vrac: [0],
487
+ beton: [0],
488
+ gazon: [0],
489
+ only_accessories: [0],
490
+ sample: [0]
491
+ };
492
+ if (!!!typeToCheck ||
493
+ (!!blockedDays[typeToCheck] && !!blockedDays[typeToCheck].includes(date.getDay()) && expeditionMethod !== 'pickup')) {
494
+ return true;
495
+ }
496
+ // ---------------------------------------------------------------------------------------
497
+ // Blocked dates checks
498
+ if (expeditionMethod !== 'pickup' && !!typeToCheck && !!blockedDates) {
499
+ const sameType = blockedDates.find((blocked) => blocked.cart_type === typeToCheck);
500
+ if (!!sameType && !!sameType.dates) {
501
+ for (let dates of sameType.dates) {
502
+ if (!!dates.start_date &&
503
+ !!dates.end_date &&
504
+ (0, moment_1.default)(date).isBetween((0, moment_1.default)((0, data_3.formatDate)(dates.start_date)), (0, moment_1.default)((0, data_3.formatDate)(dates.end_date)), 'date', '[]'))
505
+ return true;
506
+ }
507
+ }
508
+ }
509
+ const storeId = (0, object_1.recursiveCheckObject)(cartData, 'shipping_payload.pickup_store.id');
510
+ if ((!!storeId || !!selectedStore) && expeditionMethod === 'pickup' && !!schedule) {
511
+ return !!(0, exports.dateIsClosedInSchedule)(!!selectedStore ? selectedStore : storeId, date, schedule);
512
+ }
513
+ return false;
514
+ };
515
+ exports.shouldDisableDate = shouldDisableDate;
516
+ const dateIsClosedInSchedule = (storeId, dateToCheck, spaceSchedule) => {
517
+ var _a;
518
+ const weekdayIndex = dateToCheck.getDay();
519
+ const storeSchedules = spaceSchedule.store_schedules[storeId];
520
+ let isExternal = false;
521
+ // If store schedule exists, check it, if not, set min date to dateToCheck.
522
+ if (!!storeSchedules) {
523
+ let selectedDaySchedule;
524
+ // If periods are activated for the space, check the specific period schedule, if not check the general schedule
525
+ if (!!spaceSchedule.space_periods_active) {
526
+ const year = dateToCheck.getFullYear().toString();
527
+ const periods = (_a = spaceSchedule.year_periods[year]) !== null && _a !== void 0 ? _a : [];
528
+ const matchingPeriod = periods.find((p) => new Date(p.starts_at) <= dateToCheck && dateToCheck <= new Date(p.ends_at));
529
+ if (!!matchingPeriod) {
530
+ const periodSchedule = storeSchedules[matchingPeriod.id];
531
+ if (!!periodSchedule) {
532
+ if (!!periodSchedule.external) {
533
+ isExternal = true;
534
+ }
535
+ const daySchedule = periodSchedule.weekly_schedule[weekdayIndex];
536
+ if (!!daySchedule) {
537
+ selectedDaySchedule = daySchedule;
538
+ }
539
+ }
540
+ }
541
+ }
542
+ // If no schedule found for that day in active period, or periods aren't activated for that space, fall back to general schedule
543
+ // A closed day should NOT enter this if
544
+ // A period with an external schedule should NOT enter this if
545
+ if (!!!isExternal &&
546
+ (!!!selectedDaySchedule ||
547
+ (!!selectedDaySchedule.schedule &&
548
+ !!selectedDaySchedule.open &&
549
+ !!!selectedDaySchedule.schedule.closing_time &&
550
+ !!!selectedDaySchedule.schedule.opening_time))) {
551
+ const generalSchedule = storeSchedules['general'];
552
+ if (!!generalSchedule) {
553
+ if (!!generalSchedule.external) {
554
+ isExternal = true;
555
+ }
556
+ selectedDaySchedule = generalSchedule.weekly_schedule[weekdayIndex];
557
+ }
558
+ }
559
+ // NEW - Returns true here even if isExternal
560
+ if (!!selectedDaySchedule && selectedDaySchedule.open === false) {
561
+ return true;
562
+ }
563
+ }
564
+ let allClosedDays = spaceSchedule.common_closed_days;
565
+ // If schedule for period is external, filter out all common dates since they do not apply
566
+ if (!!isExternal)
567
+ allClosedDays = allClosedDays.filter((d) => d.type != 'common');
568
+ const isClosed = allClosedDays.some((c) => {
569
+ const start = new Date(c.start_date);
570
+ const end = c.end_date ? new Date(c.end_date) : start;
571
+ start.setFullYear(dateToCheck.getFullYear());
572
+ start.setHours(0, 0, 0, 0);
573
+ end.setFullYear(dateToCheck.getFullYear());
574
+ end.setHours(0, 0, 0, 0);
575
+ dateToCheck.setHours(0, 0, 0, 0);
576
+ return c.open === false && dateToCheck >= start && dateToCheck <= end && !!c.associated_stores.includes(storeId);
577
+ });
578
+ return isClosed;
579
+ };
580
+ exports.dateIsClosedInSchedule = dateIsClosedInSchedule;
581
+ /**
582
+ * Function checkIfCartTypeHasBlockedDates
583
+ * @description checks if type of cart corresponds to a blockedDates array and if array has dates defined
584
+ * @param cartData
585
+ * @param blockedDates
586
+ */
587
+ const checkIfCartTypeHasBlockedDates = (cartData, blockedDates) => {
588
+ if (!!!cartData || !!!blockedDates || !!!blockedDates.length)
589
+ return false;
590
+ const cartType = (0, cart_1.getCartType)(cartData);
591
+ const sameType = blockedDates.find((blocked) => blocked.cart_type === cartType);
592
+ if (!!!sameType)
593
+ return false;
594
+ return !!sameType.dates && !!sameType.dates.length;
595
+ };
596
+ exports.checkIfCartTypeHasBlockedDates = checkIfCartTypeHasBlockedDates;
597
+ // #endregion
598
+ // ------------------------------------------------------------------------------------------
599
+ // ------------------------------------------------------------------------------------------
600
+ // #region FEES
601
+ exports.slugsToCheckFromExpeditionFees = {
602
+ pickup: ['frais-preparation-general-beton', 'frais-palette', 'minimum-facturable-commande'],
603
+ shipping: [
604
+ 'livraison-echantillons',
605
+ 'livraison-accessoires',
606
+ 'livraison-beton-accessoires',
607
+ 'livraison-gazon',
608
+ 'frais-de-livraison-vrac',
609
+ 'minimum-facturable-commande'
610
+ ]
611
+ };
612
+ const getPalletQty = (items, orderType, minQteGrassOrder = 0) => {
613
+ const total = (0, sumBy_1.default)(items.map((item) => {
614
+ if (!!!item.other_units ||
615
+ !!item.is_service ||
616
+ !!item.is_sample ||
617
+ (!!orderType &&
618
+ !!['grass'].includes(orderType) &&
619
+ (0, products_2.checkIfIsNonSpecialityGrass)(item.sku, item.parent_slug || '', true) &&
620
+ !!item.is_upsell_of_sku)) {
621
+ return 0;
622
+ }
623
+ const paletteUnit = item.other_units.find((u) => u.unit_slug === 'pal');
624
+ const sellUnitCheck = item.other_units.find((u) => !!u.is_sale_unit);
625
+ let sellUnit = 1;
626
+ if (!!sellUnitCheck) {
627
+ sellUnit = !!sellUnitCheck.fitting_unit ? sellUnitCheck.fitting_unit : 1;
628
+ }
629
+ if (!!!paletteUnit || !!!paletteUnit.fitting_unit) {
630
+ return 0;
631
+ }
632
+ const typeAttr = item.attributes[data_4.AttributesIdEnumGR.TYPE];
633
+ if (!!!typeAttr || !!!typeAttr.length) {
634
+ return 0;
635
+ }
636
+ // If item is an accessory
637
+ if (!!typeAttr && !typeAttr.includes('gazon') && !typeAttr.includes('beton')) {
638
+ return (0, floor_1.default)((item.qte * sellUnit) / paletteUnit.fitting_unit);
639
+ }
640
+ // If is grass and minQteGrassOrder is defined
641
+ if (!!typeAttr.includes('gazon') && !!minQteGrassOrder && item.qte < minQteGrassOrder) {
642
+ return minQteGrassOrder / paletteUnit.fitting_unit;
643
+ }
644
+ return (item.qte * sellUnit) / paletteUnit.fitting_unit;
645
+ }));
646
+ if (orderType === 'concrete') {
647
+ return (0, ceil_1.default)(total);
648
+ }
649
+ return total;
650
+ };
651
+ exports.getPalletQty = getPalletQty;
652
+ // Retourne un nombre de frais de palettes à ajouter au panier selon la vraie quantité de palettes calculées pour les produits de gazon
653
+ const getGrassRoundedPickupPalletFees = (realPalletNumber) => {
654
+ // More than 400 square feet of grass needs another pallet
655
+ const ratio = (0, round_1.default)(400 / 740, 3);
656
+ // Get only the decimals from the real calculated pallet number, if the decimal is bigger than 400 / 740, round up
657
+ const fraction = (0, round_1.default)(realPalletNumber % 1, 3);
658
+ if (fraction >= ratio)
659
+ return (0, ceil_1.default)(realPalletNumber);
660
+ return (0, floor_1.default)(realPalletNumber);
661
+ };
662
+ exports.getGrassRoundedPickupPalletFees = getGrassRoundedPickupPalletFees;
663
+ const getPalletQtyPalletFee = (items, expeditionMethod, isGrass, isMixed) => {
664
+ let totalPalletGrass = 0;
665
+ let totalPalletOther = 0;
666
+ // For this fee specifically, remove all accessories before calculating palQty
667
+ items = items.filter((i) => !(0, products_2.checkIfProductIsOfType)(i, 'accessoire'));
668
+ if (!!isGrass) {
669
+ const grassItemsToCheck = !!isMixed ? items.filter((i) => !!(0, products_2.checkIfProductIsOfType)(i, 'gazon', true)) : items;
670
+ const calculatedPalletsGrass = (0, exports.getPalletQty)(grassItemsToCheck, 'grass');
671
+ totalPalletGrass =
672
+ expeditionMethod === 'pickup'
673
+ ? (0, exports.getGrassRoundedPickupPalletFees)(calculatedPalletsGrass)
674
+ : (0, ceil_1.default)(calculatedPalletsGrass);
675
+ }
676
+ if (!!!isGrass || !!isMixed) {
677
+ const otherItemsToCheck = !!isMixed ? items.filter((i) => !!!(0, products_2.checkIfProductIsOfType)(i, 'gazon', true)) : items;
678
+ totalPalletOther = (0, exports.calculatePalFeeForOtherThanGrass)(otherItemsToCheck);
679
+ }
680
+ const totalPallet = totalPalletGrass + totalPalletOther;
681
+ return totalPallet;
682
+ };
683
+ exports.getPalletQtyPalletFee = getPalletQtyPalletFee;
684
+ const calculatePalFeeForOtherThanGrass = (items) => {
685
+ const total = (0, sumBy_1.default)(items.map((item) => {
686
+ if (!!!item.other_units || !!item.is_service || !!item.is_sample) {
687
+ return 0;
688
+ }
689
+ const exceptions = [
690
+ 'muret-supra-citadin-180',
691
+ 'muret-m-100-serie-moderne-double-face',
692
+ 'muret-ora-double-face',
693
+ 'pas-japonais-grand',
694
+ 'marche-nueva',
695
+ 'marche-aria',
696
+ 'marche-t-200',
697
+ 'marche-solino',
698
+ 'marche-caralina',
699
+ 'marche-rio-15',
700
+ 'marche-appalaches',
701
+ 'marche-citadin',
702
+ 'marche-laurentien',
703
+ 'marche-m-100-serie-moderne',
704
+ 'marche-citadin-180',
705
+ 'marche-ora',
706
+ 'marche-t-100-serie-traditionnelle',
707
+ 'marche-prestige-180'
708
+ ];
709
+ const itemIsException = item.parent_slug && exceptions.includes(item.parent_slug);
710
+ const palUnit = item.other_units.find((u) => u.unit_slug === 'pal');
711
+ const rgUnit = item.other_units.find((u) => u.unit_slug === 'rg');
712
+ const unitUnit = item.other_units.find((u) => !!u.fitting_unit && u.fitting_unit === 1);
713
+ const sellUnitCheck = item.other_units.find((u) => !!u.is_sale_unit);
714
+ let sellUnit = 1;
715
+ if (!!sellUnitCheck) {
716
+ sellUnit = !!sellUnitCheck.fitting_unit ? sellUnitCheck.fitting_unit : 1;
717
+ }
718
+ const typeAttr = item.attributes[data_4.AttributesIdEnumGR.TYPE];
719
+ // --------------------------------------------------
720
+ // 1. If not all units are defined
721
+ // if no palUnit or no typeAttr
722
+ if (!!!palUnit || !!!palUnit.fitting_unit || !!!typeAttr || !!!typeAttr.length) {
723
+ if (!!itemIsException)
724
+ return 1;
725
+ // if no rgUnit, can't calculate pallet amount
726
+ if (!!!rgUnit || !!!rgUnit.fitting_unit) {
727
+ return 0;
728
+ }
729
+ else {
730
+ const nbRang = (item.qte * sellUnit) / rgUnit.fitting_unit;
731
+ // if has quantities but rang amount is lower than 1, return 0
732
+ if (nbRang > 0 && nbRang <= 1) {
733
+ return 0;
734
+ }
735
+ else {
736
+ return 1;
737
+ }
738
+ }
739
+ }
740
+ // --------------------------------------------------
741
+ // 2. If is accessory
742
+ if (!!typeAttr && !typeAttr.includes('gazon') && !typeAttr.includes('beton')) {
743
+ return (0, floor_1.default)((item.qte * sellUnit) / palUnit.fitting_unit);
744
+ }
745
+ const palQty = (item.qte * sellUnit) / (palUnit.fitting_unit || 1);
746
+ const rgQty = !!rgUnit ? (item.qte * sellUnit) / (rgUnit.fitting_unit || 1) : 0;
747
+ const unitQty = !!unitUnit ? (item.qte * sellUnit) / (unitUnit.fitting_unit || 1) : !!sellUnit ? item.qte : 0;
748
+ // --------------------------------------------------
749
+ // 3. Calculate pal quantities
750
+ // RULES:
751
+ // - 1 pal = 1 pal
752
+ // - 1 pal + 1 rang = 1 pal
753
+ // - 1 pal + 2 rang = 2 pal
754
+ // - 1 pal + 1 rang + 1 unité = 2 pals
755
+ // - 1 pal + 1 unité = 1 pal
756
+ // - 0 pal :
757
+ // - If less than or equals 1 rang (or equivalent in units) = 0 pal (excluding exceptions)
758
+ // - More thant 1 rang (or equivalent in units) = 1 pal
759
+ let totalPal = (0, floor_1.default)(palQty);
760
+ const unitsInRg = !!rgUnit ? rgUnit.fitting_unit || 0 : 0;
761
+ const unitsInPal = palUnit.fitting_unit || 0;
762
+ // if qte gives round number of pallets, return totalPal
763
+ if (item.qte / unitsInPal === totalPal)
764
+ return totalPal;
765
+ // if rgQty and rgUnit are defined
766
+ if (!!rgQty && !!rgUnit) {
767
+ const rgInPal = (palUnit.fitting_unit || 1) / (rgUnit.fitting_unit || 1);
768
+ // if palQty is higher than 1 and at least 2 rang extra
769
+ if (palQty >= 1 && (0, ceil_1.default)(rgQty % rgInPal) >= 2) {
770
+ totalPal += 1;
771
+ }
772
+ else {
773
+ if (palQty < 1) {
774
+ if (!!unitQty) {
775
+ // if item is in exception list and at least 1 unit extra
776
+ if (!!itemIsException && unitQty % unitsInPal !== 0) {
777
+ totalPal += 1;
778
+ }
779
+ else if (!!unitsInRg && unitQty > unitsInRg && unitQty / unitsInRg > 1) {
780
+ // if unit count does not equal rang count and total unit count is higher than rang count
781
+ totalPal += 1;
782
+ }
783
+ }
784
+ }
785
+ }
786
+ }
787
+ else {
788
+ if (!!unitQty && !!itemIsException) {
789
+ if (unitQty % unitsInPal !== 0) {
790
+ totalPal += 1;
791
+ }
792
+ }
793
+ }
794
+ return totalPal;
795
+ }));
796
+ return total;
797
+ };
798
+ exports.calculatePalFeeForOtherThanGrass = calculatePalFeeForOtherThanGrass;
799
+ const getMinGrassQte = (_grassProduct, expeditionMethod, _isPro) => {
800
+ let minQteGrassOrder = 0;
801
+ // if (!![kentucky, prestige].includes(grassProduct.sku)) {
802
+ // if (expeditionMethod !== 'pickup') {
803
+ // minQteGrassOrder = !!isPro ? 1480 : 740
804
+ // }
805
+ // } else {
806
+ // // Grass product is Speciality Grass
807
+ // if (expeditionMethod === 'pickup') {
808
+ // minQteGrassOrder = 740
809
+ // } else {
810
+ // minQteGrassOrder = !!isPro ? 1480 : 740
811
+ // }
812
+ // }
813
+ // MODIF AVEC FRAIS 2024 - Même minimum facturable pour tous les gazons, et tous les clients
814
+ // Toujours 0 pour la cueillette (pas de minimum), et 740 en livraison
815
+ if (expeditionMethod != 'pickup') {
816
+ minQteGrassOrder = 740; // 1 pallet
817
+ }
818
+ return minQteGrassOrder;
819
+ };
820
+ exports.getMinGrassQte = getMinGrassQte;
821
+ const getMinQteInstall = (_isPro) => {
822
+ // return !!isPro ? 2220 : 740
823
+ // MODIF AVEC FRAIS 2024 - Même minimum facturable pour tous les clients pour l'installation
824
+ return 740;
825
+ };
826
+ exports.getMinQteInstall = getMinQteInstall;
827
+ const resetAllFeesIfAccessoriesOnly = (currentItems) => {
828
+ const slugsToDelete = [
829
+ 'livraison-gazon',
830
+ 'minimum-facturable-commande',
831
+ 'surcharge-jour-meme-gazon',
832
+ 'livraison-beton-accessoires',
833
+ 'frais-preparation-general-beton',
834
+ 'frais-commande-beton-pas-en-ligne',
835
+ 'frais-preparation',
836
+ 'surcharges-installation-gazon',
837
+ 'surcharges-commandes-gazon',
838
+ 'surcharges-commandes-gazon-debut-fin-saison',
839
+ 'surcharge-gazon-ramassage-hors-ferme',
840
+ 'frais-commande-gazon-pas-en-ligne',
841
+ ...products_3.fuelSurchargeSlugs
842
+ ];
843
+ let itemsToDelete = [];
844
+ for (let i of currentItems) {
845
+ if (!!i.parent_slug && !!slugsToDelete.includes(i.parent_slug))
846
+ itemsToDelete.push(i.sku);
847
+ }
848
+ return itemsToDelete;
849
+ };
850
+ const checkIfShouldApplySameDayGrassFee = (firstDayForExpedition, expeditionMethod, selectedExpeditionDate, testDate // for unit test. To test holiday + hour after 4PM
851
+ ) => {
852
+ // a. Check min date for expedition type (for POS carts)
853
+ const dateToCheck = expeditionMethod === 'pickup' ? firstDayForExpedition.min_pickup : firstDayForExpedition.min_delivery;
854
+ const dateSelectedIsBeforeFirstCalculatedDay = !!dateToCheck && (0, moment_1.default)((0, data_3.formatDate)(selectedExpeditionDate)).isBefore((0, moment_1.default)(dateToCheck), 'date');
855
+ // b. Check if current day is a holiday
856
+ const isHoliday = (0, data_1.getHolidays)().some((h) => (0, moment_1.default)(h).isSame(testDate ? (0, moment_1.default)(testDate) : (0, moment_1.default)(), 'date'));
857
+ // c. Check if current time is after 4PM
858
+ const isAfter4PM = (!!testDate ? (0, moment_1.default)(testDate) : (0, moment_1.default)()).hour() >= 16;
859
+ // d. Check if date selected is tomorrow
860
+ const dateSelectedForExpeditionIsTomorrowOrToday = (0, moment_1.default)(selectedExpeditionDate).isSameOrBefore((0, moment_1.default)().add(1, 'day'), 'date');
861
+ // If date selected is before first calculated date for expedition,
862
+ // or order was created after 4PM/on a holiday and selected date for expedition is the next day,
863
+ // apply fees
864
+ return (!!dateSelectedIsBeforeFirstCalculatedDay ||
865
+ ((!!isHoliday || !!isAfter4PM) && !!dateSelectedForExpeditionIsTomorrowOrToday));
866
+ };
867
+ exports.checkIfShouldApplySameDayGrassFee = checkIfShouldApplySameDayGrassFee;
868
+ const checkForSameGrassDayFee = (isPOS, isPro, totalPallet, grassProduct, selectedExepeditionDate, isReserved) => {
869
+ if (!!isReserved)
870
+ return false;
871
+ return !!selectedExepeditionDate && !!grassProduct && totalPallet >= 4 && (!!isPOS || !!isPro);
872
+ };
873
+ exports.checkForSameGrassDayFee = checkForSameGrassDayFee;
874
+ // Correspond to the qte after which the expedition or installation fee should be reapplied
875
+ // Eg. For each group of 24 pallets of a product, an expedition fee is added to the cart
876
+ exports.expeditionFeePalletTier = 24;
877
+ exports.installationFeePalletTier = 48;
878
+ /**
879
+ * Calculates fees that should be applied to provided cart, and fetches them from database or fee array if provided.
880
+ * Returns the items to add, update and delete, as well as other cart info to set after fees.
881
+ * ** Optimized version possible, where address zones and distance are calculated before and properties are sent directly to function
882
+ * ** Optimized version reverted, logic found in commit here : [#2087b32]{@link https://github.com/ciaoqc/gng-tb-admin-sdk/commit/2087b3207df9e5916a979b8bb255abc2a4c1dac6}
883
+ * @async
884
+ * @param fetchProduct
885
+ * @param getIfAddressIsInsideZones
886
+ * @param getDistanceFromAddress
887
+ * @param cart
888
+ * @param expeditionMethod
889
+ * @param grassProduct
890
+ * @param concreteOrder
891
+ * @param cartContainsInstallation
892
+ * @param cartContainsVrac
893
+ * @param availableVracStoreIDs
894
+ * @param isPro
895
+ * @param addOnePalletToPickup
896
+ * @param cartContainsSample
897
+ * @param saveToShippingPayload
898
+ * @param deliveryAddress
899
+ * @param locale
900
+ * @param expeditionDate
901
+ * @param equipmentPickupOnSite
902
+ * @param cartContainsOnlyAccessories
903
+ * @param pickupStore
904
+ * @param allStores
905
+ * @param customPriceList
906
+ * @param useFeeArray
907
+ */
908
+ const applyFeesToCart = async (fetchProduct, getIfAddressIsInsideZones, getDistanceFromAddress, cart, expeditionMethod, grassProduct, concreteOrder, cartContainsInstallation, cartContainsVrac, availableVracStoreIDs, isPro, addOnePalletToPickup, cartContainsSample, saveToShippingPayload, deliveryAddress, locale, expeditionDate, equipmentPickupOnSite, cartContainsOnlyAccessories, pickupStore, allStores, customPriceList, useFeeArray) => {
909
+ let itemsToAdd = [];
910
+ let itemsToDelete = [];
911
+ let itemsToUpdate = [];
912
+ let newShippingPayload = cart.shipping_payload || {};
913
+ // Pour le minimum facturable de la livraison
914
+ let minQteGrassOrder = 0;
915
+ if (!!grassProduct) {
916
+ minQteGrassOrder = (0, exports.getMinGrassQte)(grassProduct, expeditionMethod, isPro);
917
+ }
918
+ // Vérification du type du cart
919
+ const isPOS = [Cart_1.CartTypeEnum.POS, Cart_1.CartTypeEnum.POS_TRANSACTIONNAL].includes(cart.cart_type);
920
+ const isMixed = cart.cart_content_type === Cart_1.CartContentTypeEnum.MIXED;
921
+ let totalPalletOther = 0;
922
+ let totalPalletGrass = 0;
923
+ if (!!concreteOrder) {
924
+ const concreteItemsToCheck = !!isMixed
925
+ ? cart.items.filter((i) => !!!(0, products_2.checkIfProductIsOfType)(i, 'gazon', true))
926
+ : cart.items;
927
+ totalPalletOther = (0, exports.getPalletQty)(concreteItemsToCheck, 'concrete');
928
+ }
929
+ if (!!grassProduct) {
930
+ const grassItemsToCheck = !!isMixed && !!concreteOrder ? cart.items.filter((i) => !!(0, products_2.checkIfProductIsOfType)(i, 'gazon', true)) : cart.items;
931
+ totalPalletGrass = (0, exports.getPalletQty)(grassItemsToCheck, 'grass');
932
+ }
933
+ const totalPallet = totalPalletGrass + totalPalletOther;
934
+ const totalPalletMinQte = (0, exports.getPalletQty)(cart.items, !!concreteOrder ? 'concrete' : !!grassProduct ? 'grass' : undefined, minQteGrassOrder);
935
+ // Pour le minimum facturable de l'installation
936
+ const minQteInstall = (0, exports.getMinQteInstall)(!!isPro);
937
+ // Type de cart (en ligne, en magasin, avec un commis, etc...)
938
+ const cartType = !!isPOS ? 'in_store' : !!cart.clerk_id ? 'with_clerk' : 'online';
939
+ const installAllInclusiveActive = (0, products_2.isInstallAllInclusiveActive)(cartContainsInstallation, isPro, customPriceList);
940
+ // --------------------------------------------------------------------------------------------------
941
+ // #region FRAIS PALETTE
942
+ // --------------------------------------------------------------------------------------------------
943
+ const shouldAddPaletFees = !!!cartContainsInstallation && !!!cartContainsSample && !!!cartContainsVrac;
944
+ if ((!!isMixed || !!shouldAddPaletFees) && (!!isPro || !!!grassProduct) && !!!cartContainsOnlyAccessories) {
945
+ let qtyOfSkuNeeded = (0, exports.getPalletQtyPalletFee)(cart.items, expeditionMethod, !!(0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.GRASS, cart), isMixed);
946
+ if (!!addOnePalletToPickup && expeditionMethod === 'pickup') {
947
+ qtyOfSkuNeeded += 1;
948
+ }
949
+ if (!!addOnePalletToPickup && !!!useFeeArray && !!saveToShippingPayload) {
950
+ newShippingPayload = Object.assign(Object.assign({}, newShippingPayload), { addOnePalletToPickup: true });
951
+ }
952
+ const productToAdd = await fetchProduct('frais-palette', locale, !!useFeeArray, true);
953
+ if (!!productToAdd && !!productToAdd.declinations) {
954
+ const palletFeeDecli = productToAdd.declinations[0];
955
+ if (!!qtyOfSkuNeeded) {
956
+ itemsToAdd.push(Object.assign(Object.assign({}, productToAdd.declinations[0]), { qte: qtyOfSkuNeeded, parent_slug: productToAdd.slug, is_upsell_of_sku: 'summary', categories: productToAdd.categories }));
957
+ }
958
+ else if (cart.items.some((i) => i.sku === palletFeeDecli.sku)) {
959
+ itemsToDelete.push(palletFeeDecli.sku);
960
+ }
961
+ }
962
+ }
963
+ // #endregion FRAIS PALETTE
964
+ // --------------------------------------------------------------------------------------------------
965
+ // #region COMMANDE GAZON - FRAIS DE LIVRAISON
966
+ // --------------------------------------------------------------------------------------------------
967
+ if (!!grassProduct) {
968
+ if (expeditionMethod === 'delivery') {
969
+ const parentProduct = await fetchProduct('livraison-gazon', locale, !!useFeeArray, true);
970
+ const product3 = parentProduct
971
+ ? parentProduct.declinations.find((decli) => ['17000000T'].includes(decli.sku))
972
+ : undefined;
973
+ const product4_15 = parentProduct
974
+ ? parentProduct.declinations.find((decli) => decli.sku === '170000000')
975
+ : undefined;
976
+ const product16 = parentProduct
977
+ ? parentProduct.declinations.find((decli) => decli.sku === '170000160')
978
+ : undefined;
979
+ const add = (product, qty) => {
980
+ if (!!product) {
981
+ const alreadyToAdd = (0, findIndex_1.default)(itemsToAdd, (i) => i.sku === product.sku);
982
+ if (alreadyToAdd === -1) {
983
+ itemsToAdd.push(Object.assign(Object.assign({}, product), { is_upsell_of_sku: 'summary', qte: qty, parent_slug: 'livraison-gazon' }));
984
+ }
985
+ else {
986
+ itemsToAdd[alreadyToAdd] = Object.assign(Object.assign(Object.assign({}, itemsToAdd[alreadyToAdd]), { is_upsell_of_sku: 'summary', qte: itemsToAdd[alreadyToAdd].qte + qty, parent_slug: 'livraison-gazon' }), (!!parentProduct ? { categories: parentProduct.categories } : {}));
987
+ }
988
+ }
989
+ };
990
+ const addRestQty = (pallets) => {
991
+ if (pallets > 0 && pallets < 4) {
992
+ add(product3, 1);
993
+ }
994
+ if (pallets >= 4 && pallets < 16) {
995
+ add(product4_15, 1);
996
+ }
997
+ if (pallets >= 16) {
998
+ add(product16, 1);
999
+ }
1000
+ };
1001
+ if (totalPalletMinQte <= exports.expeditionFeePalletTier) {
1002
+ addRestQty(totalPalletMinQte);
1003
+ }
1004
+ else {
1005
+ const qty4AndMore = (0, floor_1.default)(totalPalletMinQte / exports.expeditionFeePalletTier);
1006
+ const rest = (0, ceil_1.default)(totalPalletMinQte % exports.expeditionFeePalletTier);
1007
+ add(product16, qty4AndMore);
1008
+ addRestQty(rest);
1009
+ }
1010
+ }
1011
+ cart.items
1012
+ .filter((i) => i.parent_slug === 'livraison-gazon')
1013
+ .map((item) => {
1014
+ if (!itemsToAdd.map((i) => i.sku).includes(item.sku) || expeditionMethod === 'pickup') {
1015
+ itemsToDelete.push(item.sku);
1016
+ }
1017
+ return;
1018
+ });
1019
+ }
1020
+ // #endregion COMMANDE GAZON - FRAIS DE LIVRAISON
1021
+ // --------------------------------------------------------------------------------------------------
1022
+ // #region COMMANDE BETON - FRAIS DE LIVRAISON
1023
+ // --------------------------------------------------------------------------------------------------
1024
+ if (!!!cartContainsVrac && !!!cartContainsSample && !!!grassProduct && !!!cartContainsOnlyAccessories) {
1025
+ if (expeditionMethod === 'delivery') {
1026
+ const parentProduct = await fetchProduct('livraison-beton-accessoires', locale, !!useFeeArray, true);
1027
+ const product1To5 = parentProduct
1028
+ ? parentProduct.declinations.find((decli) => decli.sku === '170060450')
1029
+ : undefined;
1030
+ const product6To11 = parentProduct
1031
+ ? parentProduct.declinations.find((decli) => decli.sku === '170060650')
1032
+ : undefined;
1033
+ const product12AndMore = parentProduct
1034
+ ? parentProduct.declinations.find((decli) => decli.sku === '170060000')
1035
+ : undefined;
1036
+ const add = (product, qty) => {
1037
+ if (!!product) {
1038
+ const alreadyToAdd = (0, findIndex_1.default)(itemsToAdd, (i) => i.sku === product.sku);
1039
+ if (alreadyToAdd === -1) {
1040
+ itemsToAdd.push(Object.assign(Object.assign({}, product), { is_upsell_of_sku: 'summary', parent_slug: 'livraison-beton-accessoires', qte: qty }));
1041
+ }
1042
+ else {
1043
+ itemsToAdd[alreadyToAdd] = Object.assign(Object.assign(Object.assign({}, itemsToAdd[alreadyToAdd]), { is_upsell_of_sku: 'summary', qte: itemsToAdd[alreadyToAdd].qte + qty, parent_slug: 'livraison-beton-accessoires' }), (!!parentProduct ? { categories: parentProduct.categories } : {}));
1044
+ }
1045
+ }
1046
+ };
1047
+ const addRestQty = (pallets) => {
1048
+ switch (true) {
1049
+ case pallets > 0 && pallets <= 5:
1050
+ add(product1To5, 1);
1051
+ return;
1052
+ case pallets > 5 && pallets < 12:
1053
+ add(product6To11, 1);
1054
+ return;
1055
+ case pallets >= 12:
1056
+ add(product12AndMore, 1);
1057
+ return;
1058
+ }
1059
+ };
1060
+ if (totalPalletOther <= exports.expeditionFeePalletTier) {
1061
+ addRestQty(totalPalletOther);
1062
+ }
1063
+ else {
1064
+ const qty4AndMore = (0, floor_1.default)(totalPalletMinQte / exports.expeditionFeePalletTier);
1065
+ const rest = (0, ceil_1.default)(totalPalletOther) % exports.expeditionFeePalletTier;
1066
+ add(product12AndMore, qty4AndMore);
1067
+ addRestQty(rest);
1068
+ }
1069
+ }
1070
+ cart.items
1071
+ .filter((i) => i.parent_slug === 'livraison-beton-accessoires')
1072
+ .map((item) => {
1073
+ if (!itemsToAdd.map((i) => i.sku).includes(item.sku) || expeditionMethod === 'pickup') {
1074
+ itemsToDelete.push(item.sku);
1075
+ }
1076
+ return;
1077
+ });
1078
+ }
1079
+ // #endregion COMMANDE BETON - FRAIS DE LIVRAISON
1080
+ // --------------------------------------------------------------------------------------------------
1081
+ // #region COMMANDE GAZON - MINIMUM FACTURABLE
1082
+ // --------------------------------------------------------------------------------------------------
1083
+ if (!!grassProduct) {
1084
+ // In this case, prestige is included in speciality grasses, since the fee must include kentucky price too
1085
+ const isSpecialityGrass = !!grassProduct && !!!(0, products_2.checkIfIsNonSpecialityGrass)(grassProduct.sku, grassProduct.slug, true);
1086
+ const qtyToAdd = minQteGrassOrder - grassProduct.qte;
1087
+ if (qtyToAdd > 0) {
1088
+ const product = await fetchProduct('minimum-facturable-commande', locale, !!useFeeArray, true);
1089
+ if (!!product) {
1090
+ const decli = product.declinations.find((d) => d.sku === '010010000-M');
1091
+ if (!!decli) {
1092
+ let price = grassProduct.price;
1093
+ if (!!isSpecialityGrass) {
1094
+ const isKentucky = cart.items.find((i) => (0, products_2.checkIfIsNonSpecialityGrass)(i.sku, i.parent_slug || '', true));
1095
+ price = isKentucky ? price + (0, products_4.getLowestPrice)(isKentucky).price.amount : price;
1096
+ }
1097
+ let minGrassQteItem = Object.assign(Object.assign({}, decli), { regular_price: Object.assign(Object.assign({}, decli.regular_price), { amount: price }) });
1098
+ if (!!isPro && !!customPriceList) {
1099
+ minGrassQteItem = (0, g2_1.checkForCustomPriceEquivalent)(Object.assign(Object.assign({}, minGrassQteItem), { price_override: true }), customPriceList);
1100
+ }
1101
+ itemsToAdd.push(Object.assign(Object.assign({}, minGrassQteItem), { is_upsell_of_sku: 'summary', parent_slug: product.slug, price_override: true, qte: qtyToAdd, categories: product.categories }));
1102
+ }
1103
+ }
1104
+ }
1105
+ const minimumBillable = cart.items.find((i) => i.parent_slug === 'minimum-facturable-commande');
1106
+ if (qtyToAdd <= 0 && !!minimumBillable) {
1107
+ itemsToDelete.push(minimumBillable.sku);
1108
+ }
1109
+ }
1110
+ // #endregion COMMANDE GAZON - MINIMUM FACTURABLE
1111
+ // --------------------------------------------------------------------------------------------------
1112
+ // #region COMMANDE GAZON - SURCHARGE JOUR MÊME
1113
+ // --------------------------------------------------------------------------------------------------
1114
+ const sameDayGrassFee = await fetchProduct('surcharge-jour-meme-gazon', locale, !!useFeeArray, true);
1115
+ let decli;
1116
+ if (!!sameDayGrassFee) {
1117
+ decli = sameDayGrassFee.declinations.find((d) => d.sku === '000010990');
1118
+ }
1119
+ if (!!(0, exports.checkForSameGrassDayFee)(isPOS, isPro, totalPalletGrass, grassProduct, expeditionDate, (0, object_1.recursiveCheckObject)(cart.shipping_payload, 'is_reserved'))) {
1120
+ // a. Fetch min date for expedition type (for POS carts)
1121
+ const firstDayForExpedition = (0, exports.getMinDatePicker)(cart, grassProduct, undefined, expeditionMethod || 'delivery', !!isPro, !!cart.created_by ? (0, data_3.formatDate)(cart.created_by.date) : undefined, undefined, undefined, isPOS);
1122
+ // b. Call function to get if fee should be applied
1123
+ const shouldApplySameDayFee = (0, exports.checkIfShouldApplySameDayGrassFee)(firstDayForExpedition, expeditionMethod, expeditionDate);
1124
+ if (!!sameDayGrassFee && !!decli) {
1125
+ if (!!shouldApplySameDayFee) {
1126
+ itemsToAdd.push(Object.assign(Object.assign({}, decli), { is_upsell_of_sku: 'summary', parent_slug: sameDayGrassFee.slug, price_override: true, qte: !!grassProduct ? grassProduct.qte : 1, categories: sameDayGrassFee.categories }));
1127
+ }
1128
+ }
1129
+ }
1130
+ if (!!sameDayGrassFee && !!decli) {
1131
+ if (!!cart.items.some((i) => i.sku === decli.sku)) {
1132
+ itemsToDelete.push(decli.sku);
1133
+ }
1134
+ }
1135
+ // #endregion COMMANDE GAZON - SURCHARGE JOUR MÊME
1136
+ // --------------------------------------------------------------------------------------------------
1137
+ // #region LIVRAISON ÉCHANTILLONS
1138
+ // --------------------------------------------------------------------------------------------------
1139
+ if (!!cartContainsSample) {
1140
+ let removeShippingFee = false;
1141
+ if (expeditionMethod === 'delivery') {
1142
+ let productToAdd = await fetchProduct('livraison-echantillons', locale, !!useFeeArray, true);
1143
+ try {
1144
+ removeShippingFee = await (0, exports.checkIfShouldRemoveSampleShippingFee)(fetchProduct, cart, locale, !!useFeeArray);
1145
+ }
1146
+ catch (e) {
1147
+ console.log('error on checking if should remove sample shipping fee: ', e.toString());
1148
+ }
1149
+ if (!!removeShippingFee) {
1150
+ productToAdd = undefined;
1151
+ }
1152
+ if (!!productToAdd && !!productToAdd.declinations) {
1153
+ itemsToAdd.push(Object.assign(Object.assign({}, productToAdd.declinations[0]), { qte: 1, is_upsell_of_sku: 'summary', parent_slug: productToAdd.slug, categories: productToAdd.categories }));
1154
+ }
1155
+ }
1156
+ const sampleDeliveryFee = cart.items.find((i) => i.parent_slug === 'livraison-echantillons');
1157
+ if ((expeditionMethod === 'pickup' || !!removeShippingFee) && !!sampleDeliveryFee) {
1158
+ itemsToDelete.push(sampleDeliveryFee.sku);
1159
+ }
1160
+ }
1161
+ // #endregion LIVRAISON ÉCHANTILLONS
1162
+ // --------------------------------------------------------------------------------------------------
1163
+ // #region LIVRAISON ACCESSOIRES
1164
+ // --------------------------------------------------------------------------------------------------
1165
+ const cartAccessoriesDeliveryFee = cart.items.find((i) => i.parent_slug === 'livraison-accessoires');
1166
+ if (!!cartContainsOnlyAccessories) {
1167
+ // reset all service fees associated to grass or beton carts, if found
1168
+ itemsToDelete = resetAllFeesIfAccessoriesOnly(cart.items);
1169
+ // check to add delivery fee
1170
+ if (expeditionMethod === 'delivery') {
1171
+ const productToAdd = await fetchProduct('livraison-accessoires', locale, !!useFeeArray, true);
1172
+ if (!!productToAdd && !!productToAdd.declinations) {
1173
+ itemsToAdd.push(Object.assign(Object.assign({}, productToAdd.declinations[0]), { qte: 1, is_upsell_of_sku: 'summary', parent_slug: productToAdd.slug, categories: productToAdd.categories }));
1174
+ }
1175
+ }
1176
+ if (expeditionMethod === 'pickup' && !!cartAccessoriesDeliveryFee) {
1177
+ itemsToDelete.push(cartAccessoriesDeliveryFee.sku);
1178
+ }
1179
+ }
1180
+ else {
1181
+ if (!!cartAccessoriesDeliveryFee) {
1182
+ itemsToDelete.push(cartAccessoriesDeliveryFee.sku);
1183
+ }
1184
+ }
1185
+ // #endregion LIVRAISON ACCESSOIRES
1186
+ // --------------------------------------------------------------------------------------------------
1187
+ // #region COMMANDE GAZON - SURCHARGE DE PRIX DE GAZON
1188
+ // --------------------------------------------------------------------------------------------------
1189
+ // Les surcharges sur le gazon s'appliquent toujours pour les pros, ou juste dans le cas de commandes d'une palette ou plus pour les clients au détail
1190
+ const shouldApplyFees = !!isPro || totalPalletGrass >= 1;
1191
+ if (!!grassProduct) {
1192
+ const feesToAdd = [];
1193
+ let orderDate = expeditionDate;
1194
+ let pickupStoreId = '';
1195
+ if (!!pickupStore && !!pickupStore.id) {
1196
+ pickupStoreId = pickupStore.id;
1197
+ }
1198
+ else {
1199
+ const shipping_address = cart.shipping_address;
1200
+ if (!!shipping_address) {
1201
+ const pickupStore = allStores.find((store) => store.address.postal_code === shipping_address.address.postal_code);
1202
+ if (!!pickupStore && !!pickupStore.id) {
1203
+ pickupStoreId = pickupStore.id;
1204
+ }
1205
+ }
1206
+ }
1207
+ let surchargesCommandesGazon = undefined;
1208
+ let surchargesCommandesGazonDebutFinSaison = undefined;
1209
+ let surchargesInstallationGazon = undefined;
1210
+ let surchargesInstallationGazonDebutFinSaison = undefined;
1211
+ let surchargesGazonPickupHorsFerme = undefined;
1212
+ let fraisSiCommandePasEnLigne = undefined;
1213
+ try {
1214
+ surchargesCommandesGazon = await fetchProduct('surcharges-commandes-gazon', locale, !!useFeeArray, true);
1215
+ }
1216
+ catch (e) {
1217
+ console.log('error on fetching product: ', e.toString());
1218
+ }
1219
+ try {
1220
+ surchargesCommandesGazonDebutFinSaison = await fetchProduct('surcharges-commandes-gazon-debut-fin-saison', locale, !!useFeeArray, true);
1221
+ }
1222
+ catch (e) {
1223
+ console.log('error on fetching product: ', e.toString());
1224
+ }
1225
+ try {
1226
+ surchargesInstallationGazon = await fetchProduct('surcharges-installation-gazon', locale, !!useFeeArray, true);
1227
+ }
1228
+ catch (e) {
1229
+ console.log('error on fetching product: ', e.toString());
1230
+ }
1231
+ try {
1232
+ surchargesInstallationGazonDebutFinSaison = await fetchProduct('surcharges-installation-gazon-debut-fin-saison', locale, useFeeArray, true);
1233
+ }
1234
+ catch (e) {
1235
+ console.log('error on fetching product: ', e.toString());
1236
+ }
1237
+ try {
1238
+ surchargesGazonPickupHorsFerme = await fetchProduct('surcharge-gazon-ramassage-hors-ferme', locale, !!useFeeArray, true);
1239
+ }
1240
+ catch (e) {
1241
+ console.log('error on fetching product: ', e.toString());
1242
+ }
1243
+ try {
1244
+ fraisSiCommandePasEnLigne =
1245
+ cartType === 'online' || expeditionMethod === 'pickup'
1246
+ ? undefined
1247
+ : await fetchProduct('frais-commande-gazon-pas-en-ligne', locale, !!useFeeArray, true);
1248
+ }
1249
+ catch (e) {
1250
+ console.log('error on fetching product: ', e.toString());
1251
+ }
1252
+ if (!!orderDate) {
1253
+ const addSku = (sku, product) => {
1254
+ const decli = product.declinations.find((i) => i.sku === sku);
1255
+ if (!!decli) {
1256
+ feesToAdd.push(Object.assign(Object.assign({}, decli), { qte: !!product.slug.includes('installation') && grassProduct.qte < minQteInstall
1257
+ ? minQteInstall
1258
+ : (!!product.slug.includes('commandes-gazon') ||
1259
+ ['frais-commande-gazon-pas-en-ligne', 'surcharge-gazon-ramassage-hors-ferme'].includes(product.slug)) &&
1260
+ grassProduct.qte < minQteGrassOrder
1261
+ ? minQteGrassOrder
1262
+ : grassProduct.qte, is_upsell_of_sku: 'summary', parent_slug: product.slug, other_units: decli.other_units }));
1263
+ }
1264
+ };
1265
+ let allOrderFees = [];
1266
+ let allInstallationFees = [];
1267
+ if (!!shouldApplyFees) {
1268
+ // ---------------------------------------------------
1269
+ // #region Si la date de la commande est ...
1270
+ if (!!surchargesCommandesGazon) {
1271
+ // ... un samedi et que la commande est en livraison OU en pickup dans un magasin qui n'est pas rattaché à uen gazonnière
1272
+ if (orderDate.getDay() === 6) {
1273
+ if (expeditionMethod === 'delivery') {
1274
+ allOrderFees.push(['000010400', surchargesCommandesGazon]);
1275
+ }
1276
+ else {
1277
+ if (!!!data_2.grassFarmStores.includes(pickupStoreId)) {
1278
+ allOrderFees.push(['000010400', surchargesCommandesGazon]);
1279
+ }
1280
+ }
1281
+ }
1282
+ // ... un dimanche ou jours fériés officiels
1283
+ // NOTE: seulement pour le frais gazon, celui d'installation s'applique indépendemment plus bas dans la logique
1284
+ if ((0, moment_1.default)(orderDate).day() === 0 ||
1285
+ (0, data_1.getHolidays)().some((date) => (0, moment_1.default)(date).isSame((0, moment_1.default)(orderDate), 'day'))) {
1286
+ allOrderFees = [...allOrderFees, ['000010850', surchargesCommandesGazon]];
1287
+ }
1288
+ // ... dans les vacances de construction
1289
+ const cd = (0, data_1.getContructionHolidays)();
1290
+ if ((0, moment_1.default)(orderDate).isBetween((0, moment_1.default)(cd[0]), (0, moment_1.default)(cd[1]), 'day', '[]')) {
1291
+ allOrderFees = [...allOrderFees, ['000010860', surchargesCommandesGazon]];
1292
+ }
1293
+ // ... en été
1294
+ const summer = (0, data_1.getSummerDate)();
1295
+ if ((0, moment_1.default)(orderDate).isBetween((0, moment_1.default)(summer[0]), (0, moment_1.default)(summer[1]), 'day', '[]')) {
1296
+ allOrderFees = [...allOrderFees, ['000010300', surchargesCommandesGazon]];
1297
+ }
1298
+ }
1299
+ // #endregion
1300
+ // ---------------------------------------------------
1301
+ // ---------------------------------------------------
1302
+ // #region Si la date de commande se trouve entre (inclusif)...
1303
+ // NOTE : les frais d'installation ne doivent seulement s'appliquer pour les clients pros (POS et WEB)
1304
+ const shouldAddGrassSeasonFee = !!surchargesCommandesGazonDebutFinSaison;
1305
+ const shouldAddInstallSeasonFee = !!cartContainsInstallation && !!isPro && !!surchargesInstallationGazonDebutFinSaison;
1306
+ // ...début de la saison au 30 avril
1307
+ if ((0, moment_1.default)(orderDate).isBetween(`${(0, moment_1.default)().format('YYYY')}-03-01`, `${(0, moment_1.default)().format('YYYY')}-04-30`, 'day', '[]')) {
1308
+ if (shouldAddGrassSeasonFee)
1309
+ allOrderFees = [...allOrderFees, ['000010100', surchargesCommandesGazonDebutFinSaison]];
1310
+ if (shouldAddInstallSeasonFee)
1311
+ allInstallationFees.push(['000010600', surchargesInstallationGazonDebutFinSaison]);
1312
+ }
1313
+ // ...15 oct. au 31 oct.
1314
+ if ((0, moment_1.default)(orderDate).isBetween(`${(0, moment_1.default)().format('YYYY')}-10-15`, `${(0, moment_1.default)().format('YYYY')}-10-31`, 'day', '[]')) {
1315
+ if (shouldAddGrassSeasonFee)
1316
+ allOrderFees = [...allOrderFees, ['000010840', surchargesCommandesGazonDebutFinSaison]];
1317
+ if (shouldAddInstallSeasonFee)
1318
+ allInstallationFees.push(['000010940', surchargesInstallationGazonDebutFinSaison]);
1319
+ }
1320
+ //...1er nov. au 14 nov.
1321
+ if ((0, moment_1.default)(orderDate).isBetween(`${(0, moment_1.default)().format('YYYY')}-11-01`, `${(0, moment_1.default)().format('YYYY')}-11-14`, 'day', '[]')) {
1322
+ if (shouldAddGrassSeasonFee)
1323
+ allOrderFees = [...allOrderFees, ['000010700', surchargesCommandesGazonDebutFinSaison]];
1324
+ if (shouldAddInstallSeasonFee)
1325
+ allInstallationFees.push(['000010800', surchargesInstallationGazonDebutFinSaison]);
1326
+ }
1327
+ // ...15 nov. à la fin de la saison
1328
+ if ((0, moment_1.default)(orderDate).isBetween(`${(0, moment_1.default)().format('YYYY')}-11-15`, `${(0, moment_1.default)().format('YYYY')}-12-31`, 'day', '[]')) {
1329
+ if (shouldAddGrassSeasonFee)
1330
+ allOrderFees = [...allOrderFees, ['000010900', surchargesCommandesGazonDebutFinSaison]];
1331
+ if (shouldAddInstallSeasonFee)
1332
+ allInstallationFees.push(['000010950', surchargesInstallationGazonDebutFinSaison]);
1333
+ }
1334
+ // #endregion
1335
+ // ---------------------------------------------------
1336
+ // Si la commande est en pick-up et le magazin n'est pas une gazonnière
1337
+ if (expeditionMethod === 'pickup' && !!surchargesGazonPickupHorsFerme) {
1338
+ if (!!!data_2.grassFarmStores.includes(pickupStoreId)) {
1339
+ allOrderFees = [...allOrderFees, ['000012500', surchargesGazonPickupHorsFerme]];
1340
+ }
1341
+ }
1342
+ }
1343
+ // Si la commande a de l'installation et la date de la commande est un dimanche ou un jour férié
1344
+ if (!!surchargesInstallationGazon &&
1345
+ !!cartContainsInstallation &&
1346
+ ((0, moment_1.default)(orderDate).day() === 0 ||
1347
+ (0, data_1.getHolidays)().some((date) => (0, moment_1.default)(date).isSame((0, moment_1.default)(orderDate), 'day')))) {
1348
+ allInstallationFees.push(['000010750', surchargesInstallationGazon]);
1349
+ }
1350
+ // Si la commande a été faite autrement qu'en ligne ET ne contient pas d'installation (PROS ONLY)
1351
+ if (!!fraisSiCommandePasEnLigne && !!!cartContainsInstallation && !!isPro) {
1352
+ allOrderFees = [...allOrderFees, ['FRSGAZON', fraisSiCommandePasEnLigne]];
1353
+ }
1354
+ allOrderFees.map((fee) => {
1355
+ addSku(fee[0], fee[1]);
1356
+ });
1357
+ allInstallationFees.map((fee) => {
1358
+ addSku(fee[0], fee[1]);
1359
+ });
1360
+ }
1361
+ itemsToAdd = [...itemsToAdd, ...feesToAdd];
1362
+ }
1363
+ if (!!grassProduct || !!isMixed) {
1364
+ cart.items.forEach((i) => {
1365
+ if (!!i.parent_slug &&
1366
+ [
1367
+ 'surcharges-commandes-gazon',
1368
+ 'surcharges-commandes-gazon-debut-fin-saison',
1369
+ 'surcharges-installation-gazon',
1370
+ 'surcharges-installation-gazon-debut-fin-saison',
1371
+ 'surcharge-gazon-ramassage-hors-ferme',
1372
+ 'frais-commande-gazon-pas-en-ligne'
1373
+ ].includes(i.parent_slug)) {
1374
+ itemsToDelete.push(i.sku);
1375
+ }
1376
+ });
1377
+ }
1378
+ // #endregion SURCHARGE DE PRIX DE GAZON
1379
+ // --------------------------------------------------------------------------------------------------
1380
+ // #region SURCHARGE CARBURANT TEMPORAIRE - COÛTS DE PRODUCTION GAZON
1381
+ // 1¢/pi² sur gazon Kentucky, livraison ET cueillette, pro seulement
1382
+ // La surcharge s'applique dès que du Kentucky est présent (directement ou comme gazon base)
1383
+ const isGrassEligibleForFuelSurcharge = cart.items.some((i) => (0, products_2.checkIfIsNonSpecialityGrass)(i.sku, i.parent_slug || '', true));
1384
+ // L'activation/désactivation est contrôlée par l'état draft du produit
1385
+ const fuelGazonProd = !!grassProduct && isGrassEligibleForFuelSurcharge && isPro && !!!cart.is_booking
1386
+ ? await fetchProduct(products_3.fuelSurchargeGazonSlug, locale, !!useFeeArray, true)
1387
+ : undefined;
1388
+ if (!!fuelGazonProd && !!grassProduct) {
1389
+ let fuelGazonDecli = fuelGazonProd.declinations.find((d) => d.sku === products_3.fuelSurchargeGazonSku);
1390
+ if (!!fuelGazonDecli) {
1391
+ if (!!customPriceList) {
1392
+ fuelGazonDecli = (0, g2_1.checkForCustomPriceEquivalent)(fuelGazonDecli, customPriceList);
1393
+ }
1394
+ if (!(0, products_2.shouldHideItemIfRegPriceIs0)(fuelGazonDecli, fuelGazonProd.slug, false)) {
1395
+ itemsToAdd.push(Object.assign(Object.assign({}, fuelGazonDecli), { qte: grassProduct.qte < minQteGrassOrder ? minQteGrassOrder : grassProduct.qte, is_upsell_of_sku: 'summary', parent_slug: fuelGazonProd.slug, categories: fuelGazonProd.categories }));
1396
+ }
1397
+ }
1398
+ }
1399
+ else {
1400
+ cart.items
1401
+ .filter((i) => i.sku === products_3.fuelSurchargeGazonSku)
1402
+ .forEach((i) => itemsToDelete.push(i.sku));
1403
+ }
1404
+ // #endregion SURCHARGE CARBURANT TEMPORAIRE - COÛTS DE PRODUCTION GAZON
1405
+ // --------------------------------------------------------------------------------------------------
1406
+ // #region COMMANDE BÉTON - FRAIS DE PRÉPARATION
1407
+ // --------------------------------------------------------------------------------------------------
1408
+ if (!!concreteOrder && !!!cartContainsSample && !!!cartContainsOnlyAccessories) {
1409
+ // ----------------------------------------------------------------------------------------------
1410
+ // Frais de préparation général
1411
+ // MODIF FRAIS 2024 - Ajout du frais FP-1 seulement si le panier contient un minimum de 1 palette de produits de béton
1412
+ // Vérifie vraiment que les produits de béton pour la quantité
1413
+ const fraisPreparationGeneralBeton = await fetchProduct('frais-preparation-general-beton', locale, !!useFeeArray, true);
1414
+ const onlyConcretePalQty = (0, exports.getPalletQty)(cart.items.filter((i) => (0, products_2.checkIfProductIsOfType)(i, 'beton', true)));
1415
+ if (!!fraisPreparationGeneralBeton && onlyConcretePalQty >= 1) {
1416
+ const decli = fraisPreparationGeneralBeton.declinations.find((i) => i.sku === 'FP-1');
1417
+ if (!!decli) {
1418
+ itemsToAdd.push(Object.assign(Object.assign({}, decli), { qte: 1, is_upsell_of_sku: 'summary', parent_slug: fraisPreparationGeneralBeton.slug, categories: fraisPreparationGeneralBeton.categories }));
1419
+ }
1420
+ }
1421
+ // ----------------------------------------------------------------------------------------------
1422
+ // Frais si commande pas en ligne/par un commis
1423
+ if (expeditionMethod !== 'pickup' && cartType !== 'online' && !!isPro) {
1424
+ const getFeeAmount = (decli) => {
1425
+ // fee is a percentage of price for each item that isn't a service or fee
1426
+ // percentage is determined by FRSBETON regular_price.value
1427
+ const percent = (0, toNumber_1.default)(decli.regular_price.amount);
1428
+ let amount = 0;
1429
+ for (let item of cart.items) {
1430
+ if (!!item.is_service)
1431
+ continue;
1432
+ if (!!customPriceList) {
1433
+ item = (0, g2_1.checkForCustomPriceEquivalent)(item, customPriceList);
1434
+ }
1435
+ const itemPrice = (0, products_4.getLowestPrice)(item).price.amount;
1436
+ amount += itemPrice * item.qte * percent;
1437
+ }
1438
+ return (0, round_1.default)(amount, 3);
1439
+ };
1440
+ const feeProd = await fetchProduct('frais-commande-beton-pas-en-ligne', locale, !!useFeeArray, true);
1441
+ if (!!feeProd) {
1442
+ const skuToAdd = (feeProd.declinations || []).find((d) => d.sku === 'FRSBETON');
1443
+ if (!!skuToAdd) {
1444
+ itemsToAdd.push(Object.assign(Object.assign({}, skuToAdd), { qte: 1, parent_slug: feeProd.slug, is_upsell_of_sku: 'summary', regular_price: Object.assign(Object.assign({}, skuToAdd.regular_price), { amount: getFeeAmount(skuToAdd), price_type: (0, round_1.default)((0, toNumber_1.default)(skuToAdd.regular_price.amount) * 100, 2).toString() }), price_override: true, categories: feeProd.categories }));
1445
+ }
1446
+ }
1447
+ }
1448
+ else {
1449
+ if (cart.items.some((item) => item.sku === 'FRSBETON')) {
1450
+ itemsToDelete.push('FRSBETON');
1451
+ }
1452
+ }
1453
+ // ----------------------------------------------------------------------------------------------
1454
+ // Frais de préparation si commande contient 4 palettes incomplètes
1455
+ const concreteItems = cart.items.filter((i) => i.attributes[data_4.AttributesIdEnumGR.TYPE] && i.attributes[data_4.AttributesIdEnumGR.TYPE].includes('beton'));
1456
+ let numberOfIncompletePallets = 0;
1457
+ for (const item of concreteItems) {
1458
+ if (!!!item.other_units)
1459
+ continue;
1460
+ const saleUnit = item.other_units.find((unit) => unit.is_sale_unit);
1461
+ const palUnit = item.other_units.find((unit) => unit.unit_slug === 'pal');
1462
+ if (!!!saleUnit || !!!saleUnit.fitting_unit || !!!palUnit || !!!palUnit.fitting_unit)
1463
+ continue;
1464
+ const calculatedPal = saleUnit.fitting_unit * item.qte;
1465
+ const rest = (0, round_1.default)(calculatedPal, 3) % (0, round_1.default)(palUnit.fitting_unit, 3);
1466
+ if (!!rest) {
1467
+ numberOfIncompletePallets++;
1468
+ }
1469
+ }
1470
+ if (numberOfIncompletePallets >= 4) {
1471
+ const surchargesCommandesBeton = await fetchProduct('frais-preparation', locale, !!useFeeArray, true);
1472
+ if (!!surchargesCommandesBeton) {
1473
+ const decli = surchargesCommandesBeton.declinations.find((i) => i.sku === 'FP4');
1474
+ if (!!decli) {
1475
+ itemsToAdd.push(Object.assign(Object.assign({}, decli), { qte: 1, is_upsell_of_sku: 'summary', parent_slug: surchargesCommandesBeton.slug, categories: surchargesCommandesBeton.categories }));
1476
+ }
1477
+ }
1478
+ }
1479
+ else {
1480
+ const prepItem = cart.items.find((item) => item.parent_slug === 'frais-preparation');
1481
+ if (!!prepItem) {
1482
+ itemsToDelete.push(prepItem.sku);
1483
+ }
1484
+ }
1485
+ }
1486
+ else {
1487
+ if (cart.items.some((item) => item.sku === 'FP-1')) {
1488
+ itemsToDelete.push('FP-1');
1489
+ }
1490
+ if (cart.items.some((item) => item.sku === 'FRSBETON')) {
1491
+ itemsToDelete.push('FRSBETON');
1492
+ }
1493
+ }
1494
+ // #endregion COMMANDE BÉTON - FRAIS DE PRÉPARATION
1495
+ // --------------------------------------------------------------------------------------------------
1496
+ // #region FRAIS LIVRAISON SELON L'EMPLACEMENT
1497
+ // --------------------------------------------------------------------------------------------------
1498
+ let isOutOfArea = false;
1499
+ if (expeditionMethod === 'delivery' && !!deliveryAddress) {
1500
+ let insideZones = undefined;
1501
+ try {
1502
+ insideZones = await getIfAddressIsInsideZones(deliveryAddress);
1503
+ }
1504
+ catch (e) {
1505
+ console.log('error on fetching zones for address: ', e.toString());
1506
+ }
1507
+ if (!!insideZones && !!Array.isArray(insideZones)) {
1508
+ if (!!insideZones.length && insideZones.includes('zone-gr')) {
1509
+ // =============================================================================================
1510
+ // TOUS TYPES DE COMMANDE
1511
+ // Si une ou plusieurs zones correspondent
1512
+ let productInstallToAdd;
1513
+ if (!!grassProduct) {
1514
+ productInstallToAdd = !!cartContainsInstallation
1515
+ ? await fetchProduct('surcharges-installation-gazon', locale, !!useFeeArray, true)
1516
+ : undefined;
1517
+ }
1518
+ const productToAdd = await fetchProduct('surcharges-commandes-gazon', locale, !!useFeeArray, true);
1519
+ if (insideZones.includes('zone-mtl')) {
1520
+ if (!!productToAdd) {
1521
+ const mtl = productToAdd.declinations.find((i) => i.sku === '170050000');
1522
+ if (!!mtl) {
1523
+ itemsToAdd.push(Object.assign(Object.assign({}, mtl), { qte: (0, ceil_1.default)((0, ceil_1.default)(totalPallet) / exports.expeditionFeePalletTier), is_upsell_of_sku: 'summary', parent_slug: 'surcharges-commandes-gazon', categories: productToAdd.categories }));
1524
+ }
1525
+ }
1526
+ // If Installation ...
1527
+ if (!!grassProduct && !!productInstallToAdd) {
1528
+ const mtlInstall = productInstallToAdd.declinations.find((i) => i.sku === '170055500');
1529
+ if (!!mtlInstall) {
1530
+ itemsToAdd.push(Object.assign(Object.assign({}, mtlInstall), { qte: (0, ceil_1.default)(totalPalletGrass / exports.installationFeePalletTier), is_upsell_of_sku: 'summary', parent_slug: 'surcharges-installation-gazon', categories: productInstallToAdd.categories }));
1531
+ }
1532
+ }
1533
+ }
1534
+ if (insideZones.includes('zone-ontario')) {
1535
+ if (!!productToAdd) {
1536
+ const ontario = productToAdd.declinations.find((i) => i.sku === '170000ONT');
1537
+ if (!!ontario) {
1538
+ itemsToAdd.push(Object.assign(Object.assign({}, ontario), { qte: (0, ceil_1.default)((0, ceil_1.default)(totalPallet) / exports.expeditionFeePalletTier), is_upsell_of_sku: 'summary', parent_slug: 'surcharges-commandes-gazon', categories: productToAdd.categories }));
1539
+ }
1540
+ }
1541
+ // If Installation ...
1542
+ if (!!grassProduct && !!productInstallToAdd) {
1543
+ const ontarioInstall = productInstallToAdd.declinations.find((i) => i.sku === '170033ONT');
1544
+ if (!!ontarioInstall) {
1545
+ itemsToAdd.push(Object.assign(Object.assign({}, ontarioInstall), { qte: (0, ceil_1.default)(totalPalletGrass / exports.installationFeePalletTier), is_upsell_of_sku: 'summary', parent_slug: 'surcharges-installation-gazon', categories: productInstallToAdd.categories }));
1546
+ }
1547
+ }
1548
+ }
1549
+ if (insideZones.includes('zone-ile-orleans')) {
1550
+ if (!!productToAdd) {
1551
+ const ileOrleans = productToAdd.declinations.find((i) => i.sku === '170000418');
1552
+ if (!!ileOrleans) {
1553
+ itemsToAdd.push(Object.assign(Object.assign({}, ileOrleans), { qte: (0, ceil_1.default)((0, ceil_1.default)(totalPallet) / exports.expeditionFeePalletTier), is_upsell_of_sku: 'summary', parent_slug: 'surcharges-commandes-gazon', categories: productToAdd.categories }));
1554
+ }
1555
+ }
1556
+ }
1557
+ // }
1558
+ // =============================================================================================
1559
+ // COMMANDES VRAC
1560
+ // Infos pour la livraison du vrac, vérification faite maintenant dans deux zones
1561
+ if (!!cartContainsVrac) {
1562
+ if (insideZones.includes('zone-vrac') || insideZones.includes('zone-vrac-les-coteaux')) {
1563
+ const deliveryTruckProduct = await fetchProduct('frais-de-livraison-vrac', locale, !!useFeeArray, true);
1564
+ // Fetch de l'adresse du magasin de la zone concernée, pour calculer le prix du frais de livraison
1565
+ const storeIDToCheck = insideZones.includes('zone-vrac') ? 'sainte-julie-nobel' : 'default';
1566
+ const storeAddress = getStoreAddressByID(allStores, storeIDToCheck);
1567
+ // Si le magasin de la zone ne se trouve pas dans le array de magasins disponibles pour les produits de vrac de la commande,
1568
+ // mettre la commande comme hors-zone automatiquement
1569
+ if (!!availableVracStoreIDs && !availableVracStoreIDs.includes(storeIDToCheck)) {
1570
+ isOutOfArea = true;
1571
+ }
1572
+ else if (!!deliveryTruckProduct && !!storeAddress) {
1573
+ let distance = null;
1574
+ try {
1575
+ distance = await getDistanceFromAddress(storeAddress, deliveryAddress);
1576
+ }
1577
+ catch (_) {
1578
+ console.log(_);
1579
+ }
1580
+ if (distance === null) {
1581
+ isOutOfArea = true;
1582
+ }
1583
+ else {
1584
+ itemsToAdd = [
1585
+ ...itemsToAdd,
1586
+ ...(0, exports.calculateShippingForVrac)(distance, cart.items, deliveryTruckProduct, itemsToAdd, expeditionDate)
1587
+ ];
1588
+ }
1589
+ }
1590
+ }
1591
+ else {
1592
+ isOutOfArea = true;
1593
+ }
1594
+ }
1595
+ }
1596
+ else {
1597
+ isOutOfArea = true;
1598
+ }
1599
+ }
1600
+ }
1601
+ cart.items.forEach((i) => {
1602
+ if (!!i.parent_slug && ['frais-de-livraison-vrac', 'surcharges-commandes-gazon'].includes(i.parent_slug)) {
1603
+ itemsToDelete.push(i.sku);
1604
+ }
1605
+ });
1606
+ // #endregion FRAIS LIVRAISON SELON L'EMPLACEMENT
1607
+ // --------------------------------------------------------------------------------------------------
1608
+ // #region RAMASSAGE D'ÉQUIPEMENT SUR LE CHANTIER
1609
+ // --------------------------------------------------------------------------------------------------
1610
+ if (!!equipmentPickupOnSite) {
1611
+ // consoleLog({ equipmentPickupOnSite: 'true' })
1612
+ }
1613
+ // #endregion RAMASSAGE D'ÉQUIPEMENT SUR LE CHANTIER
1614
+ // --------------------------------------------------------------------------------------------------
1615
+ // #region FRAIS EXTRA LIVRAISON EN PÉRIODE DE DÉGEL
1616
+ const degelFeeSku = '170000018';
1617
+ if (!!isPro &&
1618
+ expeditionMethod === 'delivery' &&
1619
+ !!!cartContainsSample &&
1620
+ !!!cartContainsVrac &&
1621
+ !!expeditionDate &&
1622
+ !!isDegel(expeditionDate)) {
1623
+ const degelFeeProd = await fetchProduct('frais-livraison-periode-degel', locale, !!useFeeArray, true);
1624
+ if (!!degelFeeProd) {
1625
+ const degelFeeDecli = degelFeeProd.declinations.find((d) => d.sku === degelFeeSku);
1626
+ if (!!degelFeeDecli) {
1627
+ itemsToAdd.push(Object.assign(Object.assign({}, degelFeeDecli), { qte: 1, is_upsell_of_sku: 'summary', parent_slug: degelFeeProd.slug, categories: degelFeeProd.categories }));
1628
+ }
1629
+ }
1630
+ }
1631
+ else {
1632
+ if (!!cart.items.some((i) => i.sku === degelFeeSku)) {
1633
+ itemsToDelete.push(degelFeeSku);
1634
+ }
1635
+ }
1636
+ // #endregion
1637
+ // --------------------------------------------------------------------------------------------------
1638
+ // #region SURCHARGE CARBURANT TEMPORAIRE - LIVRAISON
1639
+ // 95$ par tranche de 24 palettes, pro seulement, pas de booking
1640
+ const fuelLivraisonProd = isPro &&
1641
+ !!!cart.is_booking &&
1642
+ itemsToAdd.some((i) => !!i.parent_slug &&
1643
+ ['livraison-gazon', 'livraison-beton-accessoires'].includes(i.parent_slug))
1644
+ ? await fetchProduct(products_3.fuelSurchargeLivraisonSlug, locale, !!useFeeArray, true)
1645
+ : undefined;
1646
+ if (!!fuelLivraisonProd) {
1647
+ let fuelLivraisonDecli = fuelLivraisonProd.declinations.find((d) => d.sku === products_3.fuelSurchargeLivraisonSku);
1648
+ if (!!fuelLivraisonDecli) {
1649
+ if (!!customPriceList) {
1650
+ fuelLivraisonDecli = (0, g2_1.checkForCustomPriceEquivalent)(fuelLivraisonDecli, customPriceList);
1651
+ }
1652
+ if (!(0, products_2.shouldHideItemIfRegPriceIs0)(fuelLivraisonDecli, fuelLivraisonProd.slug, false)) {
1653
+ itemsToAdd.push(Object.assign(Object.assign({}, fuelLivraisonDecli), { qte: (0, ceil_1.default)(totalPallet / exports.expeditionFeePalletTier) || 1, is_upsell_of_sku: 'summary', parent_slug: fuelLivraisonProd.slug, categories: fuelLivraisonProd.categories }));
1654
+ }
1655
+ }
1656
+ }
1657
+ else {
1658
+ cart.items
1659
+ .filter((i) => i.sku === products_3.fuelSurchargeLivraisonSku)
1660
+ .forEach((i) => itemsToDelete.push(i.sku));
1661
+ }
1662
+ // #endregion SURCHARGE CARBURANT TEMPORAIRE - LIVRAISON
1663
+ // --------------------------------------------------------------------------------------------------
1664
+ // #region SURCHARGE CARBURANT TEMPORAIRE - MOBILISATION
1665
+ // 95$ par tranche de 48 palettes, pro seulement
1666
+ const fuelMobilisationProd = isPro &&
1667
+ cartContainsInstallation &&
1668
+ !!!cart.is_booking &&
1669
+ cart.items.some((i) => i.parent_slug === 'frais-de-mobilisation')
1670
+ ? await fetchProduct(products_3.fuelSurchargeMobilisationSlug, locale, !!useFeeArray, true)
1671
+ : undefined;
1672
+ if (!!fuelMobilisationProd) {
1673
+ let fuelMobilisationDecli = fuelMobilisationProd.declinations.find((d) => d.sku === products_3.fuelSurchargeMobilisationSku);
1674
+ if (!!fuelMobilisationDecli) {
1675
+ if (!!customPriceList) {
1676
+ fuelMobilisationDecli = (0, g2_1.checkForCustomPriceEquivalent)(fuelMobilisationDecli, customPriceList);
1677
+ }
1678
+ if (!(0, products_2.shouldHideItemIfRegPriceIs0)(fuelMobilisationDecli, fuelMobilisationProd.slug, false)) {
1679
+ // Utiliser getPalletQtyPalletFee pour aligner sur le même calcul que les autres frais
1680
+ // (gère l'arrondi spécifique livraison vs cueillette de gazon)
1681
+ const palletQtyForFee = (0, exports.getPalletQtyPalletFee)(cart.items, expeditionMethod, true, isMixed);
1682
+ itemsToAdd.push(Object.assign(Object.assign({}, fuelMobilisationDecli), { qte: (0, ceil_1.default)(Math.max(palletQtyForFee, 1) / exports.installationFeePalletTier) || 1, is_upsell_of_sku: 'summary', parent_slug: fuelMobilisationProd.slug, categories: fuelMobilisationProd.categories }));
1683
+ }
1684
+ }
1685
+ }
1686
+ else {
1687
+ cart.items
1688
+ .filter((i) => i.sku === products_3.fuelSurchargeMobilisationSku)
1689
+ .forEach((i) => itemsToDelete.push(i.sku));
1690
+ }
1691
+ // #endregion SURCHARGE CARBURANT TEMPORAIRE - MOBILISATION
1692
+ // --------------------------------------------------------------------------------------------------
1693
+ // #region Gestion d'ajout / delete des frais
1694
+ itemsToDelete = itemsToDelete.filter((i) => !itemsToAdd.map((add) => add.sku).includes(i));
1695
+ itemsToAdd = itemsToAdd
1696
+ .map((item) => {
1697
+ const cartItem = cart.items.find((i) => i.sku === item.sku);
1698
+ if (!!cartItem) {
1699
+ if (cartItem.qte !== item.qte) {
1700
+ itemsToUpdate.push({ sku: item.sku, qte: item.qte });
1701
+ return;
1702
+ }
1703
+ else {
1704
+ return;
1705
+ }
1706
+ }
1707
+ else {
1708
+ // If fee regular price is 0.00$ and item fits criteria, do not add to cart
1709
+ if (!!item.parent_slug &&
1710
+ (0, products_2.shouldHideItemIfRegPriceIs0)(item, item.parent_slug, !!item.is_upsell_of_sku && item.parent_slug.includes('installation'))) {
1711
+ return;
1712
+ }
1713
+ }
1714
+ // When installation all-inclusive, force frais de livraison to 0$
1715
+ return installAllInclusiveActive ? (0, products_2.applyAllInclusiveOverrides)(item) : item;
1716
+ })
1717
+ .filter((i) => !!i);
1718
+ // #endregion Gestion d'ajout / delete des frais
1719
+ return {
1720
+ newCart: Object.assign(Object.assign({}, cart), { shipping_payload: newShippingPayload }),
1721
+ itemsToDelete,
1722
+ itemsToUpdate,
1723
+ itemsToAdd,
1724
+ totalPallet,
1725
+ isOutOfArea
1726
+ };
1727
+ };
1728
+ exports.applyFeesToCart = applyFeesToCart;
1729
+ // #endregion
1730
+ // ------------------------------------------------------------------------------------------
1731
+ // ------------------------------------------------------------------------------------------
1732
+ // #region SHIPPING
1733
+ /**
1734
+ * Checks if sample shipping fee should be removed from cart depending on cart items found in cart.
1735
+ * ** Optimized version possible using brand name instead of brand id, removing async check.
1736
+ * ** Optimized version reverted, logic found in commit here : [#2087b32]{@link https://github.com/ciaoqc/gng-tb-admin-sdk/commit/2087b3207df9e5916a979b8bb255abc2a4c1dac6}
1737
+ * @param fetchProduct
1738
+ * @param cart
1739
+ * @param locale
1740
+ * @param useFeeArray
1741
+ */
1742
+ const checkIfShouldRemoveSampleShippingFee = async (fetchProduct, cart, locale, useFeeArray) => {
1743
+ if (!!!cart.items)
1744
+ return false;
1745
+ const currentItems = cart.items.filter((i) => i.is_sample);
1746
+ let currentItemsChecked = [];
1747
+ for (let item of currentItems) {
1748
+ if (!!!item.parent_slug)
1749
+ continue;
1750
+ // 1. Get parent product for brand ID
1751
+ const parentProd = await fetchProduct(item.parent_slug, locale, !!useFeeArray, true);
1752
+ if (!!!parentProd)
1753
+ continue;
1754
+ const brand = parentProd.brand;
1755
+ // 2. Check if item.attributes contains FAMILY attribute with value Tena
1756
+ const isTena = !!item.attributes &&
1757
+ !!item.attributes[data_4.AttributesIdEnumGR.FAMILY] &&
1758
+ !!item.attributes[data_4.AttributesIdEnumGR.FAMILY].includes('tena');
1759
+ // 3. Check if item.attributes.TYPE is grass and is not Kentucky or Prestige (both non-speciality grasses)
1760
+ // const excludedGrass = [`kentucky`, `prestige`]
1761
+ const hasGrassType = (0, products_2.checkIfProductIsOfType)(item, 'gazon');
1762
+ const isExcludedGrass = (0, products_2.checkIfIsNonSpecialityGrass)(item.sku, item.parent_slug);
1763
+ const isGrass = !!hasGrassType && !!!isExcludedGrass;
1764
+ const valuesToCheck = {
1765
+ brand: !!brand ? brand : '',
1766
+ isTena: isTena,
1767
+ isGrass: isGrass
1768
+ };
1769
+ currentItemsChecked.push(valuesToCheck);
1770
+ }
1771
+ if (!!currentItemsChecked.length) {
1772
+ const allIncludedBrandsNoTena = currentItemsChecked.filter((item) => !!item.brand && !!data_2.includedFreeShippingBrands.includes(item.brand) && !!!item.isTena);
1773
+ const allGrass = currentItemsChecked.filter((item) => !!item.isGrass);
1774
+ // 3. count all items with included brands and check if length === currentItems.length
1775
+ // if true, remove shipping cost (set productToAdd undefined)
1776
+ if (currentItems.length === allIncludedBrandsNoTena.length || currentItems.length === allGrass.length) {
1777
+ return true;
1778
+ }
1779
+ else {
1780
+ // 4. add IncludedBrandsNoTena + isGrass lengths and check if equals currentItems.length
1781
+ // if true, remove shipping cost (set productToAdd undefined)
1782
+ const added = allIncludedBrandsNoTena.length + allGrass.length;
1783
+ if (added === currentItems.length) {
1784
+ return true;
1785
+ }
1786
+ }
1787
+ }
1788
+ return false;
1789
+ };
1790
+ exports.checkIfShouldRemoveSampleShippingFee = checkIfShouldRemoveSampleShippingFee;
1791
+ const calculateShippingForVrac = (distance = 0, cartItems, deliveryTruckProduct, currentItemsToAdd, deliveryDate) => {
1792
+ let itemsToAdd = [...currentItemsToAdd];
1793
+ const allVracItems = cartItems.filter((i) => (0, products_2.checkIfProductIsOfType)(i, 'vrac'));
1794
+ for (const vracItem of allVracItems) {
1795
+ const totalTons = vracItem.qte;
1796
+ const isInDegelPeriod = !!isDegel(deliveryDate);
1797
+ const volumeTons = [
1798
+ {
1799
+ min: 1,
1800
+ max: 4
1801
+ },
1802
+ {
1803
+ min: 4,
1804
+ max: isInDegelPeriod ? 11 : 15
1805
+ },
1806
+ {
1807
+ min: isInDegelPeriod ? 11 : 15,
1808
+ max: isInDegelPeriod ? 16 : 20
1809
+ },
1810
+ {
1811
+ min: isInDegelPeriod ? 16 : 20,
1812
+ max: isInDegelPeriod ? 19 : 24
1813
+ },
1814
+ {
1815
+ min: isInDegelPeriod ? 19 : 24,
1816
+ max: isInDegelPeriod ? 24 : 30
1817
+ }
1818
+ ];
1819
+ const checkTons = (tons) => {
1820
+ let skuToAdd = '';
1821
+ switch (true) {
1822
+ case tons <= volumeTons[0].max:
1823
+ switch (true) {
1824
+ case distance >= 0 && distance < 15:
1825
+ skuToAdd = '170000615';
1826
+ break;
1827
+ case distance >= 15 && distance < 30:
1828
+ skuToAdd = '170000630';
1829
+ break;
1830
+ case distance >= 30:
1831
+ skuToAdd = '170000660';
1832
+ break;
1833
+ }
1834
+ tons = -1;
1835
+ break;
1836
+ case tons > volumeTons[1].min && tons <= volumeTons[1].max:
1837
+ switch (true) {
1838
+ case distance >= 0 && distance < 15:
1839
+ skuToAdd = '170001015';
1840
+ break;
1841
+ case distance >= 15 && distance < 30:
1842
+ skuToAdd = '170001030';
1843
+ break;
1844
+ case distance >= 30:
1845
+ skuToAdd = '170001060';
1846
+ break;
1847
+ }
1848
+ tons = -1;
1849
+ break;
1850
+ case tons > volumeTons[2].min && tons <= volumeTons[2].max:
1851
+ switch (true) {
1852
+ case distance >= 0 && distance < 15:
1853
+ skuToAdd = '170001215';
1854
+ break;
1855
+ case distance >= 15 && distance < 30:
1856
+ skuToAdd = '170001230';
1857
+ break;
1858
+ case distance >= 30:
1859
+ skuToAdd = '170001260';
1860
+ break;
1861
+ }
1862
+ tons = -1;
1863
+ break;
1864
+ case tons > volumeTons[3].min && tons <= volumeTons[3].max:
1865
+ switch (true) {
1866
+ case distance >= 0 && distance < 15:
1867
+ skuToAdd = '170002015';
1868
+ break;
1869
+ case distance >= 15 && distance < 30:
1870
+ skuToAdd = '170002030';
1871
+ break;
1872
+ case distance >= 30:
1873
+ skuToAdd = '170002060';
1874
+ break;
1875
+ }
1876
+ tons = -1;
1877
+ break;
1878
+ case tons > volumeTons[4].min:
1879
+ switch (true) {
1880
+ case distance >= 0 && distance < 15:
1881
+ skuToAdd = '170003015';
1882
+ break;
1883
+ case distance >= 15 && distance < 30:
1884
+ skuToAdd = '170003030';
1885
+ break;
1886
+ case distance >= 30:
1887
+ skuToAdd = '170003060';
1888
+ break;
1889
+ }
1890
+ tons = tons - volumeTons[4].max;
1891
+ break;
1892
+ default:
1893
+ tons = -1;
1894
+ }
1895
+ const decliToAdd = deliveryTruckProduct.declinations.find((d) => d.sku === skuToAdd);
1896
+ if (!!decliToAdd) {
1897
+ if (!!itemsToAdd.find((item) => item.sku === decliToAdd.sku)) {
1898
+ const index = itemsToAdd.findIndex((item) => item.sku === decliToAdd.sku);
1899
+ itemsToAdd[index] = Object.assign(Object.assign({}, itemsToAdd[index]), { qte: itemsToAdd[index].qte + 1 });
1900
+ }
1901
+ else {
1902
+ itemsToAdd.push(Object.assign(Object.assign({}, decliToAdd), { parent_slug: 'frais-de-livraison-vrac', qte: 1, is_upsell_of_sku: 'summary', categories: deliveryTruckProduct.categories }));
1903
+ }
1904
+ }
1905
+ if (tons > 0) {
1906
+ checkTons(tons);
1907
+ }
1908
+ };
1909
+ checkTons(totalTons);
1910
+ }
1911
+ return itemsToAdd;
1912
+ };
1913
+ exports.calculateShippingForVrac = calculateShippingForVrac;
1914
+ const getStoresForVracProdShipping = (inventoryItem) => {
1915
+ let availability = {};
1916
+ for (let vracStore of data_2.vracShippingStores) {
1917
+ const sameInInventory = inventoryItem.inventories.find((i) => i.store_id == vracStore);
1918
+ availability[vracStore] = !!sameInInventory && !!!sameInInventory.unavailable_in_store;
1919
+ }
1920
+ return availability;
1921
+ };
1922
+ exports.getStoresForVracProdShipping = getStoresForVracProdShipping;
1923
+ const getStoreAddressByID = (allStores, storeID) => {
1924
+ const sameStore = allStores.find((s) => s.id == storeID);
1925
+ return !!sameStore ? sameStore.address : undefined;
1926
+ };
1927
+ // #endregion
1928
+ // ------------------------------------------------------------------------------------------
1929
+ // ------------------------------------------------------------------------------------------
1930
+ // #region VALIDATION
1931
+ /**
1932
+ * Function checkIfCartExpired
1933
+ * @description checks if cart expired using the updated_at date stored in the shipping_payload
1934
+ * @param cartData
1935
+ * @param grassProduct
1936
+ * @param concreteOrder
1937
+ * @param isPro
1938
+ * @param options.blocked_shipping_dates
1939
+ * @param options.vracType
1940
+ * @param options.chosenPaymentType
1941
+ * @param options.forceCheckForCartTypes
1942
+ */
1943
+ const checkIfCartExpired = (cartData, grassProduct, concreteOrder, isPro, options = {}) => {
1944
+ // ######################################################################################
1945
+ // #region TESTS
1946
+ // ----------------------------------------------------------
1947
+ // 1) Is same day after 10
1948
+ // const test1 = {
1949
+ // now: moment().set('hours', 11).toDate(),
1950
+ // updated_last: moment().set('hours', 9).toDate(),
1951
+ // time: 'AM',
1952
+ // selected_date: moment().add(4, 'day').toDate()
1953
+ // }
1954
+ // 2) Is same day after 10 but with AM still possible
1955
+ // const test2 = {
1956
+ // now: moment().set({ day: 6, hours: 11 }).toDate(),
1957
+ // updated_last: moment().set({ day: 6, hours: 9 }).toDate(),
1958
+ // time: 'AM',
1959
+ // selected_date: moment().set('day', 9).toDate()
1960
+ // }
1961
+ // const now = test2.now
1962
+ // const updated_last = test2.updated_last
1963
+ // const time = test2.time
1964
+ // const selected_date = test2.selected_date
1965
+ //
1966
+ // #endregion
1967
+ // ######################################################################################
1968
+ const isPOS = Cart_1.CartTypeEnum.WEB != cartData.cart_type;
1969
+ const isSample = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.SAMPLE, cartData);
1970
+ const isAccessoriesOnly = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.ONLY_ACCESSORIES, cartData);
1971
+ // const cartContainsInstallation = checkIfCartContainsType(CartGeneralTypeEnum.INSTALLATION, cartData)
1972
+ // 1. Check if it is normal for selected date to be undefined / expired
1973
+ const selectedDate = !!cartData.shipping_payload && !!cartData.shipping_payload.delivery_or_pickup_date
1974
+ ? (0, data_3.formatDate)(cartData.shipping_payload.delivery_or_pickup_date)
1975
+ : undefined;
1976
+ const noDeliveryDateIsNormal = (0, exports.checkIfNoDeliveryDateIsNormal)(cartData, concreteOrder) ||
1977
+ (!!options.chosenPaymentType && ['depot'].includes(options.chosenPaymentType));
1978
+ const shouldForceCheck = (options.forceCheckForCartTypes || []).some((t) => (0, cart_1.checkIfCartContainsType)(t, cartData));
1979
+ // If force check property sent, check event if !!noDeliveryDateIsNormal
1980
+ if (!!noDeliveryDateIsNormal && !shouldForceCheck) {
1981
+ return false;
1982
+ }
1983
+ else if (!!!selectedDate) {
1984
+ return true;
1985
+ }
1986
+ // 2. Check date depending on when cart was last updated
1987
+ const now = (0, moment_1.default)().toDate();
1988
+ const updated_last = !!cartData.shipping_payload && !!cartData.shipping_payload.updated_at
1989
+ ? (0, data_3.formatDate)(cartData.shipping_payload.updated_at)
1990
+ : (0, moment_1.default)().toDate();
1991
+ const time = !!cartData.shipping_payload && !!cartData.shipping_payload.delivery_period
1992
+ ? cartData.shipping_payload.delivery_period
1993
+ : 'PM';
1994
+ const minDates = (0, exports.getMinDatePicker)(cartData, grassProduct, concreteOrder, !!cartData.is_pickup ? 'pickup' : 'delivery', !!isPro, updated_last, options.blocked_shipping_dates, options.vracType, isPOS);
1995
+ const currentMinDate = !!cartData.is_pickup ? minDates.min_pickup : minDates.min_delivery;
1996
+ const ok_hours = (0, exports.getAvailableHours)(currentMinDate, selectedDate, grassProduct, concreteOrder, (!!cartData.is_pickup ? 'pickup' : 'delivery'), time, isPro, isSample, isAccessoriesOnly, updated_last);
1997
+ return (!!updated_last &&
1998
+ (((0, moment_1.default)(selectedDate).isSameOrBefore(now, 'day') && !!!(0, moment_1.default)(currentMinDate).isSame(now, 'day')) ||
1999
+ (0, moment_1.default)(now).isAfter(updated_last, 'day') ||
2000
+ (0, moment_1.default)(currentMinDate).isAfter(selectedDate, 'day') ||
2001
+ (updated_last.getHours() < 10 &&
2002
+ now.getHours() >= 10 &&
2003
+ time === 'AM' &&
2004
+ !!ok_hours.deliveryTimes.every((d) => d.value == 'PM'))));
2005
+ };
2006
+ exports.checkIfCartExpired = checkIfCartExpired;
2007
+ const checkIfNoDeliveryDateIsNormal = (cartData, concreteOrder, checkForInputShown) => {
2008
+ const isAccessoriesOnly = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.ONLY_ACCESSORIES, cartData);
2009
+ const isSample = (0, cart_1.checkIfCartContainsType)(cart_2.CartGeneralTypeEnum.SAMPLE, cartData);
2010
+ return ((!!!checkForInputShown && !!cartData.shipping_payload && !!cartData.shipping_payload.isOutOfArea) ||
2011
+ (!!concreteOrder && concreteOrder.type !== 'green') ||
2012
+ ((!!isAccessoriesOnly || !!isSample) && !!!cartData.is_pickup));
2013
+ };
2014
+ exports.checkIfNoDeliveryDateIsNormal = checkIfNoDeliveryDateIsNormal;
2015
+ // #endregion
2016
+ // ------------------------------------------------------------------------------------------
2017
2017
  //# sourceMappingURL=expedition.js.map