@lyxa.ai/marketing 1.0.40 → 1.0.42

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 (246) hide show
  1. package/dist/lib/event/event-initializations.d.ts.map +1 -1
  2. package/dist/lib/event/event-initializations.js +2 -0
  3. package/dist/lib/event/event-initializations.js.map +1 -1
  4. package/dist/lib/event/event-listeners/event-listeners.d.ts.map +1 -1
  5. package/dist/lib/event/event-listeners/event-listeners.js.map +1 -1
  6. package/dist/lib/index.d.ts +652 -0
  7. package/dist/lib/index.d.ts.map +1 -1
  8. package/dist/lib/index.js +6 -6
  9. package/dist/lib/index.js.map +1 -1
  10. package/dist/lib/modules/coupon/routers/coupon.router.d.ts +4 -0
  11. package/dist/lib/modules/coupon/routers/coupon.router.d.ts.map +1 -1
  12. package/dist/lib/modules/coupon/services/coupon.service.d.ts +1 -0
  13. package/dist/lib/modules/coupon/services/coupon.service.d.ts.map +1 -1
  14. package/dist/lib/modules/coupon/services/coupon.service.js +74 -65
  15. package/dist/lib/modules/coupon/services/coupon.service.js.map +1 -1
  16. package/dist/lib/modules/coupon/services/custom-coupon.service.d.ts +28 -2
  17. package/dist/lib/modules/coupon/services/custom-coupon.service.d.ts.map +1 -1
  18. package/dist/lib/modules/coupon/services/custom-coupon.service.js +13 -33
  19. package/dist/lib/modules/coupon/services/custom-coupon.service.js.map +1 -1
  20. package/dist/lib/modules/coupon/services/helper.service.d.ts +30 -2
  21. package/dist/lib/modules/coupon/services/helper.service.d.ts.map +1 -1
  22. package/dist/lib/modules/coupon/services/helper.service.js +121 -8
  23. package/dist/lib/modules/coupon/services/helper.service.js.map +1 -1
  24. package/dist/lib/modules/coupon/services/individual-store-coupon.service.d.ts +29 -3
  25. package/dist/lib/modules/coupon/services/individual-store-coupon.service.d.ts.map +1 -1
  26. package/dist/lib/modules/coupon/services/individual-store-coupon.service.js +10 -62
  27. package/dist/lib/modules/coupon/services/individual-store-coupon.service.js.map +1 -1
  28. package/dist/lib/modules/coupon/services/patterns/repository/CouponRepository.d.ts.map +1 -1
  29. package/dist/lib/modules/coupon/services/patterns/repository/CouponRepository.js +117 -155
  30. package/dist/lib/modules/coupon/services/patterns/repository/CouponRepository.js.map +1 -1
  31. package/dist/lib/modules/coupon/services/referral-code-coupon.service.d.ts +9 -0
  32. package/dist/lib/modules/coupon/services/referral-code-coupon.service.d.ts.map +1 -1
  33. package/dist/lib/modules/coupon/services/referral-code-coupon.service.js +97 -30
  34. package/dist/lib/modules/coupon/services/referral-code-coupon.service.js.map +1 -1
  35. package/dist/lib/modules/coupon/services/referral-reward-coupon.service.d.ts.map +1 -1
  36. package/dist/lib/modules/coupon/services/referral-reward-coupon.service.js +5 -1
  37. package/dist/lib/modules/coupon/services/referral-reward-coupon.service.js.map +1 -1
  38. package/dist/lib/modules/coupon/services/shops-categories-coupon.service.d.ts +29 -3
  39. package/dist/lib/modules/coupon/services/shops-categories-coupon.service.d.ts.map +1 -1
  40. package/dist/lib/modules/coupon/services/shops-categories-coupon.service.js +10 -63
  41. package/dist/lib/modules/coupon/services/shops-categories-coupon.service.js.map +1 -1
  42. package/dist/lib/modules/coupon/validations/coupon.validation.d.ts +13 -0
  43. package/dist/lib/modules/coupon/validations/coupon.validation.d.ts.map +1 -1
  44. package/dist/lib/modules/coupon/validations/coupon.validation.js +3 -2
  45. package/dist/lib/modules/coupon/validations/coupon.validation.js.map +1 -1
  46. package/dist/lib/modules/deal-setting/routers/deal-setting.router.d.ts.map +1 -1
  47. package/dist/lib/modules/deal-setting/services/deal-setting.service.d.ts.map +1 -1
  48. package/dist/lib/modules/deal-setting/services/deal-setting.service.js +4 -4
  49. package/dist/lib/modules/deal-setting/services/deal-setting.service.js.map +1 -1
  50. package/dist/lib/modules/featured-setting/routers/featured-setting.router.d.ts.map +1 -1
  51. package/dist/lib/modules/limited-time-offer/campaign/campaign.router.d.ts +339 -0
  52. package/dist/lib/modules/limited-time-offer/campaign/campaign.router.d.ts.map +1 -0
  53. package/dist/lib/modules/limited-time-offer/campaign/campaign.router.js +77 -0
  54. package/dist/lib/modules/limited-time-offer/campaign/campaign.router.js.map +1 -0
  55. package/dist/lib/modules/limited-time-offer/campaign/jobs/index.d.ts +4 -0
  56. package/dist/lib/modules/limited-time-offer/campaign/jobs/index.d.ts.map +1 -0
  57. package/dist/lib/modules/limited-time-offer/campaign/jobs/index.js +24 -0
  58. package/dist/lib/modules/limited-time-offer/campaign/jobs/index.js.map +1 -0
  59. package/dist/lib/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.producer.d.ts +12 -0
  60. package/dist/lib/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.producer.d.ts.map +1 -0
  61. package/dist/lib/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.producer.js +29 -0
  62. package/dist/lib/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.producer.js.map +1 -0
  63. package/dist/lib/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.worker.d.ts +8 -0
  64. package/dist/lib/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.worker.d.ts.map +1 -0
  65. package/dist/lib/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.worker.js +79 -0
  66. package/dist/lib/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.worker.js.map +1 -0
  67. package/dist/lib/modules/limited-time-offer/campaign/limited-time-offer-campaign.validation.d.ts +851 -0
  68. package/dist/lib/modules/limited-time-offer/campaign/limited-time-offer-campaign.validation.d.ts.map +1 -0
  69. package/dist/lib/modules/limited-time-offer/campaign/limited-time-offer-campaign.validation.js +100 -0
  70. package/dist/lib/modules/limited-time-offer/campaign/limited-time-offer-campaign.validation.js.map +1 -0
  71. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.d.ts +11 -0
  72. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.d.ts.map +1 -0
  73. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.js +75 -0
  74. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.js.map +1 -0
  75. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.d.ts +9 -0
  76. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.d.ts.map +1 -0
  77. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.js +42 -0
  78. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.js.map +1 -0
  79. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.d.ts +78 -0
  80. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.d.ts.map +1 -0
  81. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.js +308 -0
  82. package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.js.map +1 -0
  83. package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.service.d.ts +12 -0
  84. package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.service.d.ts.map +1 -0
  85. package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.service.js +94 -0
  86. package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.service.js.map +1 -0
  87. package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.validation.d.ts +189 -0
  88. package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.validation.d.ts.map +1 -0
  89. package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.validation.js +24 -0
  90. package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.validation.js.map +1 -0
  91. package/dist/lib/modules/limited-time-offer/config/limited-time-offer.router.d.ts +122 -0
  92. package/dist/lib/modules/limited-time-offer/config/limited-time-offer.router.d.ts.map +1 -0
  93. package/dist/lib/modules/limited-time-offer/config/limited-time-offer.router.js +37 -0
  94. package/dist/lib/modules/limited-time-offer/config/limited-time-offer.router.js.map +1 -0
  95. package/dist/lib/modules/limited-time-offer/limited-time-offer.router.d.ts +644 -0
  96. package/dist/lib/modules/limited-time-offer/limited-time-offer.router.d.ts.map +1 -0
  97. package/dist/lib/modules/limited-time-offer/limited-time-offer.router.js +13 -0
  98. package/dist/lib/modules/limited-time-offer/limited-time-offer.router.js.map +1 -0
  99. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.router.d.ts +170 -0
  100. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.router.d.ts.map +1 -0
  101. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.router.js +51 -0
  102. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.router.js.map +1 -0
  103. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.validation.d.ts +603 -0
  104. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.validation.d.ts.map +1 -0
  105. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.validation.js +85 -0
  106. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.validation.js.map +1 -0
  107. package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant-marketing.service.d.ts +12 -0
  108. package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant-marketing.service.d.ts.map +1 -0
  109. package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant-marketing.service.js +98 -0
  110. package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant-marketing.service.js.map +1 -0
  111. package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.d.ts +21 -0
  112. package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.d.ts.map +1 -0
  113. package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.js +133 -0
  114. package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.js.map +1 -0
  115. package/dist/lib/modules/marketing/patterns/repository/MarketingMetricsRepository.d.ts +2 -1
  116. package/dist/lib/modules/marketing/patterns/repository/MarketingMetricsRepository.d.ts.map +1 -1
  117. package/dist/lib/modules/marketing/patterns/repository/MarketingMetricsRepository.js +23 -15
  118. package/dist/lib/modules/marketing/patterns/repository/MarketingMetricsRepository.js.map +1 -1
  119. package/dist/lib/modules/marketing/routers/marketing.router.d.ts +5 -0
  120. package/dist/lib/modules/marketing/routers/marketing.router.d.ts.map +1 -1
  121. package/dist/lib/modules/marketing/routers/marketing.router.js +3 -0
  122. package/dist/lib/modules/marketing/routers/marketing.router.js.map +1 -1
  123. package/dist/lib/modules/marketing/services/buy1-get1-marketing.service.d.ts +0 -2
  124. package/dist/lib/modules/marketing/services/buy1-get1-marketing.service.d.ts.map +1 -1
  125. package/dist/lib/modules/marketing/services/buy1-get1-marketing.service.js +18 -39
  126. package/dist/lib/modules/marketing/services/buy1-get1-marketing.service.js.map +1 -1
  127. package/dist/lib/modules/marketing/services/discount-marketing.service.d.ts +0 -3
  128. package/dist/lib/modules/marketing/services/discount-marketing.service.d.ts.map +1 -1
  129. package/dist/lib/modules/marketing/services/discount-marketing.service.js +26 -52
  130. package/dist/lib/modules/marketing/services/discount-marketing.service.js.map +1 -1
  131. package/dist/lib/modules/marketing/services/marketing.service.d.ts +1 -0
  132. package/dist/lib/modules/marketing/services/marketing.service.d.ts.map +1 -1
  133. package/dist/lib/modules/marketing/services/marketing.service.js +55 -25
  134. package/dist/lib/modules/marketing/services/marketing.service.js.map +1 -1
  135. package/dist/lib/modules/marketing/services/product-marketing.service.d.ts +9 -2
  136. package/dist/lib/modules/marketing/services/product-marketing.service.d.ts.map +1 -1
  137. package/dist/lib/modules/marketing/services/product-marketing.service.js +132 -7
  138. package/dist/lib/modules/marketing/services/product-marketing.service.js.map +1 -1
  139. package/dist/lib/modules/marketing/services/synchronize-product-marketing.service.d.ts.map +1 -1
  140. package/dist/lib/modules/marketing/services/synchronize-product-marketing.service.js +58 -31
  141. package/dist/lib/modules/marketing/services/synchronize-product-marketing.service.js.map +1 -1
  142. package/dist/lib/modules/marketing/transformers/buy1-get1-marketing.transformer.d.ts +3 -0
  143. package/dist/lib/modules/marketing/transformers/buy1-get1-marketing.transformer.d.ts.map +1 -1
  144. package/dist/lib/modules/marketing/transformers/discount-marketing.transformer.d.ts +3 -0
  145. package/dist/lib/modules/marketing/transformers/discount-marketing.transformer.d.ts.map +1 -1
  146. package/dist/lib/modules/marketing/transformers/product-marketing.transformer.d.ts +1 -0
  147. package/dist/lib/modules/marketing/transformers/product-marketing.transformer.d.ts.map +1 -1
  148. package/dist/lib/modules/marketing/validations/buy1-get1-marketing.validation.d.ts +42 -12
  149. package/dist/lib/modules/marketing/validations/buy1-get1-marketing.validation.d.ts.map +1 -1
  150. package/dist/lib/modules/marketing/validations/discount-marketing.validation.d.ts +57 -21
  151. package/dist/lib/modules/marketing/validations/discount-marketing.validation.d.ts.map +1 -1
  152. package/dist/lib/modules/marketing/validations/product-marketing.validation.d.ts +77 -0
  153. package/dist/lib/modules/marketing/validations/product-marketing.validation.d.ts.map +1 -1
  154. package/dist/lib/modules/marketing/validations/product-marketing.validation.js +20 -1
  155. package/dist/lib/modules/marketing/validations/product-marketing.validation.js.map +1 -1
  156. package/dist/lib/modules/punch-marketing-history/routers/punch-marketing-history.router.d.ts.map +1 -1
  157. package/dist/types/event/event-initializations.d.ts.map +1 -1
  158. package/dist/types/event/event-listeners/event-listeners.d.ts.map +1 -1
  159. package/dist/types/index.d.ts +652 -0
  160. package/dist/types/index.d.ts.map +1 -1
  161. package/dist/types/modules/coupon/routers/coupon.router.d.ts +4 -0
  162. package/dist/types/modules/coupon/routers/coupon.router.d.ts.map +1 -1
  163. package/dist/types/modules/coupon/services/coupon.service.d.ts +1 -0
  164. package/dist/types/modules/coupon/services/coupon.service.d.ts.map +1 -1
  165. package/dist/types/modules/coupon/services/custom-coupon.service.d.ts +28 -2
  166. package/dist/types/modules/coupon/services/custom-coupon.service.d.ts.map +1 -1
  167. package/dist/types/modules/coupon/services/helper.service.d.ts +30 -2
  168. package/dist/types/modules/coupon/services/helper.service.d.ts.map +1 -1
  169. package/dist/types/modules/coupon/services/individual-store-coupon.service.d.ts +29 -3
  170. package/dist/types/modules/coupon/services/individual-store-coupon.service.d.ts.map +1 -1
  171. package/dist/types/modules/coupon/services/patterns/repository/CouponRepository.d.ts.map +1 -1
  172. package/dist/types/modules/coupon/services/referral-code-coupon.service.d.ts +57 -0
  173. package/dist/types/modules/coupon/services/referral-code-coupon.service.d.ts.map +1 -1
  174. package/dist/types/modules/coupon/services/referral-reward-coupon.service.d.ts.map +1 -1
  175. package/dist/types/modules/coupon/services/shops-categories-coupon.service.d.ts +29 -3
  176. package/dist/types/modules/coupon/services/shops-categories-coupon.service.d.ts.map +1 -1
  177. package/dist/types/modules/coupon/validations/coupon.validation.d.ts +13 -0
  178. package/dist/types/modules/coupon/validations/coupon.validation.d.ts.map +1 -1
  179. package/dist/types/modules/deal-setting/routers/deal-setting.router.d.ts.map +1 -1
  180. package/dist/types/modules/deal-setting/services/deal-setting.service.d.ts.map +1 -1
  181. package/dist/types/modules/featured-setting/routers/featured-setting.router.d.ts.map +1 -1
  182. package/dist/types/modules/limited-time-offer/campaign/campaign.router.d.ts +339 -0
  183. package/dist/types/modules/limited-time-offer/campaign/campaign.router.d.ts.map +1 -0
  184. package/dist/types/modules/limited-time-offer/campaign/jobs/index.d.ts +4 -0
  185. package/dist/types/modules/limited-time-offer/campaign/jobs/index.d.ts.map +1 -0
  186. package/dist/types/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.producer.d.ts +12 -0
  187. package/dist/types/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.producer.d.ts.map +1 -0
  188. package/dist/types/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.worker.d.ts +8 -0
  189. package/dist/types/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.worker.d.ts.map +1 -0
  190. package/dist/types/modules/limited-time-offer/campaign/limited-time-offer-campaign.validation.d.ts +851 -0
  191. package/dist/types/modules/limited-time-offer/campaign/limited-time-offer-campaign.validation.d.ts.map +1 -0
  192. package/dist/types/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.d.ts +11 -0
  193. package/dist/types/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.d.ts.map +1 -0
  194. package/dist/types/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.d.ts +9 -0
  195. package/dist/types/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.d.ts.map +1 -0
  196. package/dist/types/modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.d.ts +78 -0
  197. package/dist/types/modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.d.ts.map +1 -0
  198. package/dist/types/modules/limited-time-offer/config/limited-time-offer-config.service.d.ts +12 -0
  199. package/dist/types/modules/limited-time-offer/config/limited-time-offer-config.service.d.ts.map +1 -0
  200. package/dist/types/modules/limited-time-offer/config/limited-time-offer-config.validation.d.ts +189 -0
  201. package/dist/types/modules/limited-time-offer/config/limited-time-offer-config.validation.d.ts.map +1 -0
  202. package/dist/types/modules/limited-time-offer/config/limited-time-offer.router.d.ts +122 -0
  203. package/dist/types/modules/limited-time-offer/config/limited-time-offer.router.d.ts.map +1 -0
  204. package/dist/types/modules/limited-time-offer/limited-time-offer.router.d.ts +644 -0
  205. package/dist/types/modules/limited-time-offer/limited-time-offer.router.d.ts.map +1 -0
  206. package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.router.d.ts +170 -0
  207. package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.router.d.ts.map +1 -0
  208. package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.service.d.ts +1 -0
  209. package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.service.d.ts.map +1 -0
  210. package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.validation.d.ts +603 -0
  211. package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.validation.d.ts.map +1 -0
  212. package/dist/types/modules/limited-time-offer/participant/services/limited-time-offer-participant-marketing.service.d.ts +12 -0
  213. package/dist/types/modules/limited-time-offer/participant/services/limited-time-offer-participant-marketing.service.d.ts.map +1 -0
  214. package/dist/types/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.d.ts +21 -0
  215. package/dist/types/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.d.ts.map +1 -0
  216. package/dist/types/modules/marketing/patterns/repository/MarketingMetricsRepository.d.ts +2 -1
  217. package/dist/types/modules/marketing/patterns/repository/MarketingMetricsRepository.d.ts.map +1 -1
  218. package/dist/types/modules/marketing/routers/marketing.router.d.ts +5 -0
  219. package/dist/types/modules/marketing/routers/marketing.router.d.ts.map +1 -1
  220. package/dist/types/modules/marketing/services/buy1-get1-marketing.service.d.ts +0 -2
  221. package/dist/types/modules/marketing/services/buy1-get1-marketing.service.d.ts.map +1 -1
  222. package/dist/types/modules/marketing/services/discount-marketing.service.d.ts +0 -3
  223. package/dist/types/modules/marketing/services/discount-marketing.service.d.ts.map +1 -1
  224. package/dist/types/modules/marketing/services/marketing.service.d.ts +1 -0
  225. package/dist/types/modules/marketing/services/marketing.service.d.ts.map +1 -1
  226. package/dist/types/modules/marketing/services/product-marketing.service.d.ts +13 -2
  227. package/dist/types/modules/marketing/services/product-marketing.service.d.ts.map +1 -1
  228. package/dist/types/modules/marketing/services/synchronize-product-marketing.service.d.ts.map +1 -1
  229. package/dist/types/modules/marketing/transformers/buy1-get1-marketing.transformer.d.ts +3 -0
  230. package/dist/types/modules/marketing/transformers/buy1-get1-marketing.transformer.d.ts.map +1 -1
  231. package/dist/types/modules/marketing/transformers/discount-marketing.transformer.d.ts +3 -0
  232. package/dist/types/modules/marketing/transformers/discount-marketing.transformer.d.ts.map +1 -1
  233. package/dist/types/modules/marketing/transformers/product-marketing.transformer.d.ts +1 -0
  234. package/dist/types/modules/marketing/transformers/product-marketing.transformer.d.ts.map +1 -1
  235. package/dist/types/modules/marketing/validations/buy1-get1-marketing.validation.d.ts +42 -12
  236. package/dist/types/modules/marketing/validations/buy1-get1-marketing.validation.d.ts.map +1 -1
  237. package/dist/types/modules/marketing/validations/discount-marketing.validation.d.ts +57 -21
  238. package/dist/types/modules/marketing/validations/discount-marketing.validation.d.ts.map +1 -1
  239. package/dist/types/modules/marketing/validations/product-marketing.validation.d.ts +77 -0
  240. package/dist/types/modules/marketing/validations/product-marketing.validation.d.ts.map +1 -1
  241. package/dist/types/modules/punch-marketing-history/routers/punch-marketing-history.router.d.ts.map +1 -1
  242. package/package.json +2 -2
  243. package/dist/lib/events/event-initializations.d.ts +0 -2
  244. package/dist/lib/events/event-initializations.d.ts.map +0 -1
  245. package/dist/lib/events/event-initializations.js +0 -5
  246. package/dist/lib/events/event-initializations.js.map +0 -1
@@ -52,15 +52,23 @@ const shared_1 = require("@lyxa.ai/core/dist/utilities/shared");
52
52
  const enum_1 = require("@lyxa.ai/core/dist/utilities/enum");
53
53
  const error_common_1 = require("@lyxa.ai/core/dist/utilities/error-common");
54
54
  const helper_service_1 = require("./helper.service");
55
+ const CouponRepository_1 = require("./patterns/repository/CouponRepository");
55
56
  let ReferralCodeCouponService = class ReferralCodeCouponService {
56
57
  model;
57
58
  settingsModel;
58
59
  userModel;
60
+ _coreUserModel = null;
59
61
  constructor() {
60
62
  this.model = models_1.ReferralCodeCouponModel;
61
63
  this.settingsModel = models_1.ReferralSettingModel;
62
64
  this.userModel = models_1.UserModel;
63
65
  }
66
+ get coreUserModel() {
67
+ if (!this._coreUserModel) {
68
+ this._coreUserModel = (0, models_1.getCoreUserModel)();
69
+ }
70
+ return this._coreUserModel;
71
+ }
64
72
  async create(data) {
65
73
  return await this.model.create(data);
66
74
  }
@@ -80,6 +88,63 @@ let ReferralCodeCouponService = class ReferralCodeCouponService {
80
88
  }
81
89
  return record;
82
90
  }
91
+ normalizeName(value) {
92
+ if (!value)
93
+ return '';
94
+ return value
95
+ .normalize('NFD')
96
+ .replace(/[\u0300-\u036f]/g, '')
97
+ .replace(/[^a-zA-Z]/g, '')
98
+ .toUpperCase();
99
+ }
100
+ padToThree(value) {
101
+ if (!value)
102
+ return 'XXX';
103
+ if (value.length >= 3) {
104
+ return value.slice(0, 3);
105
+ }
106
+ return value.padEnd(3, 'X');
107
+ }
108
+ containsArabic(text) {
109
+ return /[\u0600-\u06FF]/.test(text);
110
+ }
111
+ generateRandomAlphaNumeric(length) {
112
+ const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
113
+ let result = '';
114
+ for (let i = 0; i < length; i++) {
115
+ result += chars.charAt(Math.floor(Math.random() * chars.length));
116
+ }
117
+ return result;
118
+ }
119
+ generateThreeDigits() {
120
+ return Math.floor(Math.random() * 1000)
121
+ .toString()
122
+ .padStart(3, '0');
123
+ }
124
+ generateCouponFromName(firstName, lastName) {
125
+ const fullName = `${firstName} ${lastName ?? ''}`;
126
+ if (this.containsArabic(fullName)) {
127
+ return this.generateRandomAlphaNumeric(6) + this.generateThreeDigits();
128
+ }
129
+ const first = this.normalizeName(firstName);
130
+ const last = this.normalizeName(lastName ?? '');
131
+ const safeFirst = first || 'XXX';
132
+ const safeLast = last || 'XXX';
133
+ const firstPart = this.padToThree(safeFirst);
134
+ const lastPart = this.padToThree(safeLast);
135
+ const digits = this.generateThreeDigits();
136
+ return `${firstPart}${lastPart}${digits}`;
137
+ }
138
+ splitName(fullName) {
139
+ if (!fullName || !fullName.trim()) {
140
+ return { firstName: '', lastName: '' };
141
+ }
142
+ const parts = fullName.trim().split(/\s+/);
143
+ if (parts.length === 1) {
144
+ return { firstName: parts[0], lastName: '' };
145
+ }
146
+ return { firstName: parts[0], lastName: parts[parts.length - 1] };
147
+ }
83
148
  generateCode(length = 6) {
84
149
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
85
150
  let result = '';
@@ -88,41 +153,41 @@ let ReferralCodeCouponService = class ReferralCodeCouponService {
88
153
  }
89
154
  return result;
90
155
  }
91
- async generateCouponCode() {
92
- let code = 'SAMPLE';
156
+ async generateCouponCode(fullName) {
157
+ const { firstName, lastName } = this.splitName(fullName);
158
+ let code = '';
93
159
  let exists = true;
94
160
  while (exists) {
95
- code = this.generateCode();
96
- exists = (await this.model.exists({ code: code })) ? true : false;
161
+ code = this.generateCouponFromName(firstName, lastName);
162
+ const result = await this.model.exists({ code });
163
+ exists = !!result;
97
164
  }
98
165
  return code;
99
166
  }
100
167
  async createReferralCodeForUser(userId) {
101
- if (!userId) {
102
- throw new server_1.TRPCError({
103
- code: 'NOT_FOUND',
104
- message: `User not found`,
105
- });
106
- }
168
+ if (!userId)
169
+ (0, error_common_1.notFoundError)('User not found');
170
+ const user = await this.userModel.findById(userId).select('coreUser');
171
+ if (!user)
172
+ (0, error_common_1.notFoundError)('User not found');
173
+ const coreUser = await this.coreUserModel.findById(user.coreUser).select('name');
174
+ const fullName = coreUser?.name ?? 'Customer';
107
175
  const existingReferralCodeCoupon = await this.model.findOne({
108
176
  referralUser: userId,
109
177
  });
110
178
  if (existingReferralCodeCoupon) {
111
179
  return existingReferralCodeCoupon;
112
180
  }
181
+ const code = await this.generateCouponCode(fullName);
113
182
  const referralCodeCoupon = await this.create({
114
- code: await this.generateCouponCode(),
183
+ code,
115
184
  couponType: enum_1.CouponType.REFERRAL_CODE,
116
185
  referralUser: userId,
117
186
  orderLimitPerUser: 1,
118
187
  isOrderLimitPerUserEnabled: true,
119
188
  });
120
- if (!referralCodeCoupon) {
121
- throw new server_1.TRPCError({
122
- code: 'INTERNAL_SERVER_ERROR',
123
- message: 'Could not create referral code coupon',
124
- });
125
- }
189
+ if (!referralCodeCoupon)
190
+ (0, error_common_1.internalServerError)('Could not create referral code coupon');
126
191
  return referralCodeCoupon;
127
192
  }
128
193
  async validateCoupon(data, coupon) {
@@ -144,7 +209,7 @@ let ReferralCodeCouponService = class ReferralCodeCouponService {
144
209
  if (minimumOrderAmount && minimumOrderAmount >= data.amountBeforeCoupon) {
145
210
  return {
146
211
  isValid: false,
147
- message: 'Minimum order amount not met',
212
+ message: `Minimum order amount ${minimumOrderAmount}$ is not met!`,
148
213
  };
149
214
  }
150
215
  let discountAmount = referralCouponSettings.receiver?.valueType == enum_1.ValueType.FIXED
@@ -159,19 +224,21 @@ let ReferralCodeCouponService = class ReferralCodeCouponService {
159
224
  if (secondaryDiscountAmount > data.secondaryAmountBeforeCoupon) {
160
225
  secondaryDiscountAmount = data.secondaryAmountBeforeCoupon;
161
226
  }
162
- return {
163
- isValid: true,
164
- discountAmount,
165
- secondaryDiscountAmount,
166
- amountAfterCoupon: (0, shared_1.roundBaseCurrency)(data.amountBeforeCoupon - discountAmount),
167
- secondaryAmountAfterCoupon: (0, shared_1.roundSecondaryCurrency)(data.secondaryAmountBeforeCoupon - secondaryDiscountAmount),
168
- discountCut: {
169
- companyCut: discountAmount,
170
- secondaryCompanyCut: secondaryDiscountAmount,
171
- shopCut: 0,
172
- secondaryShopCut: 0,
227
+ const referrerName = await helper_service_1.couponHelperService.fetchUserName(coupon.referralUser._id);
228
+ const couponRepository = new CouponRepository_1.CouponRepository();
229
+ return helper_service_1.couponHelperService.buildCouponResponse(data, discountAmount, secondaryDiscountAmount, false, couponRepository.addLabelsToCoupons([
230
+ {
231
+ ...coupon.toJSON(),
232
+ referringUser: { name: referrerName },
233
+ value: referralCouponSettings.receiver?.value,
234
+ valueType: referralCouponSettings.receiver?.valueType,
235
+ minimumOrderValue: referralCouponSettings.receiver?.minimumOrderValue,
236
+ secondaryCurrencyValue: referralCouponSettings.receiver?.valueType == enum_1.ValueType.FIXED
237
+ ? await (0, currency_1.convertToSecondary)(referralCouponSettings.receiver?.value ?? 0)
238
+ : null,
239
+ secondaryCurrencyMinOrderValue: await (0, currency_1.convertToSecondary)(referralCouponSettings.receiver?.minimumOrderValue ?? 0),
173
240
  },
174
- };
241
+ ])[0]);
175
242
  }
176
243
  async getReferralCodeCoupon(userId) {
177
244
  let coupon = await this.model.findOne({ referralUser: userId });
@@ -1 +1 @@
1
- {"version":3,"file":"referral-code-coupon.service.js","sourceRoot":"/","sources":["modules/coupon/services/referral-code-coupon.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, { Service } from 'typedi';\nimport { TRPCError } from '@trpc/server';\nimport { DocumentType, mongoose } from '@typegoose/typegoose';\nimport {\n\tReferralCodeCouponModel,\n\tReferralCodeCoupon as Model,\n\tReferralSettingModel,\n\tReferralSetting,\n\tUserModel,\n\tUser,\n} from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport {\n\tCouponValidationOutputDTO,\n\tCreateReferralCodeCouponDTO as CreateDTO,\n\tReferralCodeCouponResponseDTO,\n\tUpdateReferralCodeCouponDTO as UpdateDTO,\n\tValidateCouponDTO,\n} from '@modules/coupon/validations';\nimport { SoftDeleteModel } from '@lyxa.ai/core/dist/libraries/mongo/plugins/soft-delete-plugin';\nimport { convertToSecondary } from '@lyxa.ai/core/dist/utilities/currency';\nimport { roundBaseCurrency, roundSecondaryCurrency } from '@lyxa.ai/core/dist/utilities/shared';\nimport { ValueType, CouponType } from '@lyxa.ai/core/dist/utilities/enum';\nimport { notFoundError } from '@lyxa.ai/core/dist/utilities/error-common';\nimport { couponHelperService } from './helper.service';\n\n@Service()\nexport class ReferralCodeCouponService {\n\tprivate model;\n\tprivate settingsModel: typeof ReferralSettingModel & SoftDeleteModel<ReferralSetting>;\n\tprivate userModel: typeof UserModel & SoftDeleteModel<User>;\n\n\tconstructor() {\n\t\tthis.model = ReferralCodeCouponModel;\n\t\tthis.settingsModel = ReferralSettingModel as typeof ReferralSettingModel &\n\t\t\tSoftDeleteModel<ReferralSetting>;\n\t\tthis.userModel = UserModel as typeof UserModel & SoftDeleteModel<User>;\n\t}\n\n\t/**\n\t * Create a new record\n\t * @param data Data for the new record\n\t */\n\tpublic async create(data: CreateDTO): Promise<DocumentType<Model>> {\n\t\treturn await this.model.create(data);\n\t}\n\n\t/**\n\t * Update record\n\t * @param id ID of the record\n\t * @param data Data to update\n\t */\n\tpublic async update(id: string, data: UpdateDTO): Promise<DocumentType<Model>> {\n\t\tconst record = await this.model.findOneAndUpdate(\n\t\t\t{\n\t\t\t\t_id: id,\n\t\t\t\tdeletedAt: null,\n\t\t\t},\n\t\t\tdata,\n\t\t\t{\n\t\t\t\tnew: true,\n\t\t\t\trunValidators: true,\n\t\t\t}\n\t\t);\n\n\t\tif (!record) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'NOT_FOUND',\n\t\t\t\tmessage: `Record not found`,\n\t\t\t});\n\t\t}\n\n\t\treturn record;\n\t}\n\n\tprivate generateCode(length = 6): string {\n\t\tconst chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n\t\tlet result = '';\n\t\tfor (let i = 0; i < length; i++) {\n\t\t\tresult += chars.charAt(Math.floor(Math.random() * chars.length));\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate async generateCouponCode(): Promise<string> {\n\t\tlet code: string = 'SAMPLE';\n\t\tlet exists = true;\n\n\t\twhile (exists) {\n\t\t\tcode = this.generateCode();\n\t\t\texists = (await this.model.exists({ code: code })) ? true : false;\n\t\t}\n\n\t\treturn code;\n\t}\n\n\t// create referral code for user\n\tpublic async createReferralCodeForUser(\n\t\tuserId: mongoose.Types.ObjectId | undefined\n\t): Promise<DocumentType<Model>> {\n\t\tif (!userId) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'NOT_FOUND',\n\t\t\t\tmessage: `User not found`,\n\t\t\t});\n\t\t}\n\n\t\tconst existingReferralCodeCoupon = await this.model.findOne({\n\t\t\treferralUser: userId,\n\t\t});\n\n\t\tif (existingReferralCodeCoupon) {\n\t\t\treturn existingReferralCodeCoupon;\n\t\t}\n\n\t\tconst referralCodeCoupon = await this.create({\n\t\t\tcode: await this.generateCouponCode(),\n\t\t\tcouponType: CouponType.REFERRAL_CODE,\n\t\t\treferralUser: userId,\n\t\t\torderLimitPerUser: 1,\n\t\t\tisOrderLimitPerUserEnabled: true,\n\t\t});\n\n\t\tif (!referralCodeCoupon) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'INTERNAL_SERVER_ERROR',\n\t\t\t\tmessage: 'Could not create referral code coupon',\n\t\t\t});\n\t\t}\n\n\t\treturn referralCodeCoupon;\n\t}\n\n\tpublic async validateCoupon(\n\t\tdata: ValidateCouponDTO,\n\t\tcoupon: DocumentType<Model>\n\t): Promise<CouponValidationOutputDTO> {\n\t\tif (data.user.toString() == coupon.referralUser.toString()) {\n\t\t\treturn {\n\t\t\t\tisValid: false,\n\t\t\t\tmessage: 'You cannot use your own referral code',\n\t\t\t};\n\t\t}\n\n\t\tconst isNewUser = await couponHelperService.isNewUser(new mongoose.Types.ObjectId(data.user));\n\n\t\tif (!isNewUser) {\n\t\t\treturn {\n\t\t\t\tisValid: false,\n\t\t\t\tmessage: 'This coupon is for new user only',\n\t\t\t};\n\t\t}\n\n\t\tconst referralCouponSettings = await this.getReferralSettings();\n\n\t\tconst minimumOrderAmount = referralCouponSettings.receiver?.minimumOrderValue;\n\n\t\tif (minimumOrderAmount && minimumOrderAmount >= data.amountBeforeCoupon) {\n\t\t\treturn {\n\t\t\t\tisValid: false,\n\t\t\t\tmessage: 'Minimum order amount not met',\n\t\t\t};\n\t\t}\n\n\t\tlet discountAmount =\n\t\t\treferralCouponSettings.receiver?.valueType == ValueType.FIXED\n\t\t\t\t? referralCouponSettings.receiver.value\n\t\t\t\t: roundBaseCurrency((data.amountBeforeCoupon * (referralCouponSettings.receiver?.value || 1)) / 100);\n\n\t\tlet secondaryDiscountAmount =\n\t\t\treferralCouponSettings.receiver?.valueType == ValueType.FIXED\n\t\t\t\t? await convertToSecondary(referralCouponSettings.receiver.value)\n\t\t\t\t: roundSecondaryCurrency(\n\t\t\t\t\t\t(data.secondaryAmountBeforeCoupon * (referralCouponSettings.receiver?.value || 1)) / 100\n\t\t\t\t\t);\n\n\t\tif (discountAmount > data.amountBeforeCoupon) {\n\t\t\tdiscountAmount = data.amountBeforeCoupon;\n\t\t}\n\t\tif (secondaryDiscountAmount > data.secondaryAmountBeforeCoupon) {\n\t\t\tsecondaryDiscountAmount = data.secondaryAmountBeforeCoupon;\n\t\t}\n\n\t\treturn {\n\t\t\tisValid: true,\n\t\t\tdiscountAmount,\n\t\t\tsecondaryDiscountAmount,\n\t\t\tamountAfterCoupon: roundBaseCurrency(data.amountBeforeCoupon - discountAmount),\n\t\t\tsecondaryAmountAfterCoupon: roundSecondaryCurrency(\n\t\t\t\tdata.secondaryAmountBeforeCoupon - secondaryDiscountAmount\n\t\t\t),\n\t\t\tdiscountCut: {\n\t\t\t\tcompanyCut: discountAmount,\n\t\t\t\tsecondaryCompanyCut: secondaryDiscountAmount,\n\t\t\t\tshopCut: 0,\n\t\t\t\tsecondaryShopCut: 0,\n\t\t\t},\n\t\t};\n\t}\n\n\tpublic async getReferralCodeCoupon(\n\t\tuserId: mongoose.Types.ObjectId\n\t): Promise<ReferralCodeCouponResponseDTO> {\n\t\tlet coupon = await this.model.findOne({ referralUser: userId });\n\n\t\tif (!coupon) {\n\t\t\tcoupon = await this.createReferralCodeForUser(userId);\n\t\t}\n\t\tconst referral = coupon as unknown as Model;\n\n\t\treturn {\n\t\t\tcode: referral.code,\n\t\t\ttext: `Download Lyxa and explore the wide variety of offerings and benefits!\\nUse my code at checkout to claim a special coupon: ${referral.code}.\\nhttps://request.lyxa.ai/app/user/home/share`,\n\t\t};\n\t}\n\n\tprivate async getReferralSettings(): Promise<DocumentType<ReferralSetting>> {\n\t\tconst referralSetting = await this.settingsModel.findOne({});\n\t\tif (!referralSetting) notFoundError('Referral setting not found');\n\t\treturn referralSetting;\n\t}\n}\n\nexport const referralCodeCouponService = Container.get(ReferralCodeCouponService);\n"]}
1
+ {"version":3,"file":"referral-code-coupon.service.js","sourceRoot":"/","sources":["modules/coupon/services/referral-code-coupon.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, { Service } from 'typedi';\nimport { TRPCError } from '@trpc/server';\nimport { DocumentType, mongoose } from '@typegoose/typegoose';\nimport {\n\tReferralCodeCouponModel,\n\tReferralCodeCoupon as Model,\n\tReferralSettingModel,\n\tReferralSetting,\n\tUserModel,\n\tUser,\n\tgetCoreUserModel,\n} from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport {\n\tCouponValidationOutputDTO,\n\tCreateReferralCodeCouponDTO as CreateDTO,\n\tReferralCodeCouponResponseDTO,\n\tUpdateReferralCodeCouponDTO as UpdateDTO,\n\tValidateCouponDTO,\n} from '@modules/coupon/validations';\nimport { SoftDeleteModel } from '@lyxa.ai/core/dist/libraries/mongo/plugins/soft-delete-plugin';\nimport { convertToSecondary } from '@lyxa.ai/core/dist/utilities/currency';\nimport { roundBaseCurrency, roundSecondaryCurrency } from '@lyxa.ai/core/dist/utilities/shared';\nimport { ValueType, CouponType } from '@lyxa.ai/core/dist/utilities/enum';\nimport { internalServerError, notFoundError } from '@lyxa.ai/core/dist/utilities/error-common';\nimport { couponHelperService } from './helper.service';\nimport { CouponRepository } from './patterns/repository/CouponRepository';\n\n@Service()\nexport class ReferralCodeCouponService {\n\tprivate model;\n\tprivate settingsModel: typeof ReferralSettingModel & SoftDeleteModel<ReferralSetting>;\n\tprivate userModel: typeof UserModel & SoftDeleteModel<User>;\n\tprivate _coreUserModel: ReturnType<typeof getCoreUserModel> | null = null;\n\n\tconstructor() {\n\t\tthis.model = ReferralCodeCouponModel;\n\t\tthis.settingsModel = ReferralSettingModel as typeof ReferralSettingModel &\n\t\t\tSoftDeleteModel<ReferralSetting>;\n\t\tthis.userModel = UserModel as typeof UserModel & SoftDeleteModel<User>;\n\t}\n\n\tprivate get coreUserModel() {\n\t\tif (!this._coreUserModel) {\n\t\t\tthis._coreUserModel = getCoreUserModel();\n\t\t}\n\t\treturn this._coreUserModel;\n\t}\n\n\t/**\n\t * Create a new record\n\t * @param data Data for the new record\n\t */\n\tpublic async create(data: CreateDTO): Promise<DocumentType<Model>> {\n\t\treturn await this.model.create(data);\n\t}\n\n\t/**\n\t * Update record\n\t * @param id ID of the record\n\t * @param data Data to update\n\t */\n\tpublic async update(id: string, data: UpdateDTO): Promise<DocumentType<Model>> {\n\t\tconst record = await this.model.findOneAndUpdate(\n\t\t\t{\n\t\t\t\t_id: id,\n\t\t\t\tdeletedAt: null,\n\t\t\t},\n\t\t\tdata,\n\t\t\t{\n\t\t\t\tnew: true,\n\t\t\t\trunValidators: true,\n\t\t\t}\n\t\t);\n\n\t\tif (!record) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'NOT_FOUND',\n\t\t\t\tmessage: `Record not found`,\n\t\t\t});\n\t\t}\n\n\t\treturn record;\n\t}\n\n\t/**\n\t * Normalize the name by removing accents, special characters,\n\t * and converting to uppercase\n\t *\n\t * @param name\n\t * @returns Normalized name\n\t */\n\tprivate normalizeName(value: string): string {\n\t\tif (!value) return '';\n\n\t\treturn value\n\t\t\t.normalize('NFD') // split accents\n\t\t\t.replace(/[\\u0300-\\u036f]/g, '') // remove accents\n\t\t\t.replace(/[^a-zA-Z]/g, '') // keep letters only\n\t\t\t.toUpperCase();\n\t}\n\n\t/**\n\t * Pad the value to 3 characters, if it's shorter than 3 characters,\n\t * pad with 'X', if it's longer than 3 characters,\n\t * truncate it to 3 characters\n\t *\n\t * @param value\n\t * @returns\n\t */\n\tprivate padToThree(value: string): string {\n\t\tif (!value) return 'XXX';\n\n\t\tif (value.length >= 3) {\n\t\t\treturn value.slice(0, 3);\n\t\t}\n\n\t\treturn value.padEnd(3, 'X');\n\t}\n\n\t/**\n\t * Detect Arabic Characters\n\t *\n\t * @param text\n\t * @returns\n\t */\n\tprivate containsArabic(text: string): boolean {\n\t\treturn /[\\u0600-\\u06FF]/.test(text);\n\t}\n\n\t/**\n\t * Letters + Numbers (for Arabic fallback)\n\t *\n\t * @param length\n\t * @returns\n\t */\n\tprivate generateRandomAlphaNumeric(length: number): string {\n\t\tconst chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n\t\tlet result = '';\n\n\t\tfor (let i = 0; i < length; i++) {\n\t\t\tresult += chars.charAt(Math.floor(Math.random() * chars.length));\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Random Digits (000–999)\n\t *\n\t * @return string\n\t */\n\tprivate generateThreeDigits(): string {\n\t\treturn Math.floor(Math.random() * 1000)\n\t\t\t.toString()\n\t\t\t.padStart(3, '0');\n\t}\n\n\t/**\n\t * Main Generator (Core Logic)\n\t *\n\t * @param firstName\n\t * @param lastName\n\t * @returns\n\t */\n\tprivate generateCouponFromName(firstName: string, lastName?: string): string {\n\t\tconst fullName = `${firstName} ${lastName ?? ''}`;\n\n\t\t// Arabic rule -> random 6 chars + 3 digits\n\t\tif (this.containsArabic(fullName)) {\n\t\t\treturn this.generateRandomAlphaNumeric(6) + this.generateThreeDigits();\n\t\t}\n\n\t\t// Normalize\n\t\tconst first = this.normalizeName(firstName);\n\t\tconst last = this.normalizeName(lastName ?? '');\n\n\t\t// Fallback if unsafe\n\t\tconst safeFirst = first || 'XXX';\n\t\tconst safeLast = last || 'XXX';\n\n\t\t// Pad\n\t\tconst firstPart = this.padToThree(safeFirst);\n\t\tconst lastPart = this.padToThree(safeLast);\n\n\t\t// Digits\n\t\tconst digits = this.generateThreeDigits();\n\n\t\treturn `${firstPart}${lastPart}${digits}`;\n\t}\n\n\t/**\n\t * Split full name into first name and last name.\n\t * If only one word is provided, treat it as first name and leave last name empty.\n\t * If multiple words are provided, treat the first word as first name and\n\t * the last word as last name, ignoring any middle words.\n\t *\n\t * @param fullName string\n\t * @returns object\n\t */\n\tprivate splitName(fullName: string): { firstName: string; lastName: string } {\n\t\tif (!fullName || !fullName.trim()) {\n\t\t\treturn { firstName: '', lastName: '' };\n\t\t}\n\n\t\tconst parts = fullName.trim().split(/\\s+/);\n\n\t\tif (parts.length === 1) {\n\t\t\t// Only one word -> treat as first name, last name empty\n\t\t\treturn { firstName: parts[0], lastName: '' };\n\t\t}\n\n\t\t// More than one word -> first word = first name, last word = last name\n\t\treturn { firstName: parts[0], lastName: parts[parts.length - 1] };\n\t}\n\n\tprivate generateCode(length = 6): string {\n\t\tconst chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n\t\tlet result = '';\n\t\tfor (let i = 0; i < length; i++) {\n\t\t\tresult += chars.charAt(Math.floor(Math.random() * chars.length));\n\t\t}\n\t\treturn result;\n\t}\n\n\t// private async generateCouponCode(): Promise<string> {\n\t// \tlet code: string = 'SAMPLE';\n\t// \tlet exists = true;\n\n\t// \twhile (exists) {\n\t// \t\tcode = this.generateCode();\n\t// \t\texists = (await this.model.exists({ code: code })) ? true : false;\n\t// \t}\n\n\t// \treturn code;\n\t// }\n\n\tprivate async generateCouponCode(fullName: string): Promise<string> {\n\t\tconst { firstName, lastName } = this.splitName(fullName);\n\n\t\tlet code: string = '';\n\t\tlet exists: boolean = true;\n\n\t\twhile (exists) {\n\t\t\tcode = this.generateCouponFromName(firstName, lastName);\n\t\t\tconst result = await this.model.exists({ code });\n\n\t\t\texists = !!result;\n\t\t}\n\n\t\treturn code;\n\t}\n\n\t// create referral code for user\n\tpublic async createReferralCodeForUser(\n\t\tuserId: mongoose.Types.ObjectId | undefined\n\t): Promise<DocumentType<Model>> {\n\t\tif (!userId) notFoundError('User not found');\n\n\t\t// Get user details to generate code based on name\n\t\tconst user = await this.userModel.findById(userId).select('coreUser');\n\t\tif (!user) notFoundError('User not found');\n\n\t\tconst coreUser = await this.coreUserModel.findById(user.coreUser).select('name');\n\t\tconst fullName = coreUser?.name ?? 'Customer';\n\n\t\tconst existingReferralCodeCoupon = await this.model.findOne({\n\t\t\treferralUser: userId,\n\t\t});\n\n\t\tif (existingReferralCodeCoupon) {\n\t\t\treturn existingReferralCodeCoupon;\n\t\t}\n\n\t\t// const code = await this.generateCouponCode();\n\t\tconst code = await this.generateCouponCode(fullName);\n\n\t\tconst referralCodeCoupon = await this.create({\n\t\t\tcode,\n\t\t\tcouponType: CouponType.REFERRAL_CODE,\n\t\t\treferralUser: userId,\n\t\t\torderLimitPerUser: 1,\n\t\t\tisOrderLimitPerUserEnabled: true,\n\t\t});\n\n\t\tif (!referralCodeCoupon) internalServerError('Could not create referral code coupon');\n\n\t\treturn referralCodeCoupon;\n\t}\n\n\tpublic async validateCoupon(\n\t\tdata: ValidateCouponDTO,\n\t\tcoupon: DocumentType<Model>\n\t): Promise<CouponValidationOutputDTO> {\n\t\tif (data.user.toString() == coupon.referralUser.toString()) {\n\t\t\treturn {\n\t\t\t\tisValid: false,\n\t\t\t\tmessage: 'You cannot use your own referral code',\n\t\t\t};\n\t\t}\n\n\t\tconst isNewUser = await couponHelperService.isNewUser(new mongoose.Types.ObjectId(data.user));\n\n\t\tif (!isNewUser) {\n\t\t\treturn {\n\t\t\t\tisValid: false,\n\t\t\t\tmessage: 'This coupon is for new user only',\n\t\t\t};\n\t\t}\n\n\t\tconst referralCouponSettings = await this.getReferralSettings();\n\n\t\tconst minimumOrderAmount = referralCouponSettings.receiver?.minimumOrderValue;\n\t\tif (minimumOrderAmount && minimumOrderAmount >= data.amountBeforeCoupon) {\n\t\t\treturn {\n\t\t\t\tisValid: false,\n\t\t\t\tmessage: `Minimum order amount ${minimumOrderAmount}$ is not met!`,\n\t\t\t};\n\t\t}\n\n\t\tlet discountAmount =\n\t\t\treferralCouponSettings.receiver?.valueType == ValueType.FIXED\n\t\t\t\t? referralCouponSettings.receiver.value\n\t\t\t\t: roundBaseCurrency((data.amountBeforeCoupon * (referralCouponSettings.receiver?.value || 1)) / 100);\n\n\t\tlet secondaryDiscountAmount =\n\t\t\treferralCouponSettings.receiver?.valueType == ValueType.FIXED\n\t\t\t\t? await convertToSecondary(referralCouponSettings.receiver.value)\n\t\t\t\t: roundSecondaryCurrency(\n\t\t\t\t\t\t(data.secondaryAmountBeforeCoupon * (referralCouponSettings.receiver?.value || 1)) / 100\n\t\t\t\t\t);\n\n\t\tif (discountAmount > data.amountBeforeCoupon) {\n\t\t\tdiscountAmount = data.amountBeforeCoupon;\n\t\t}\n\t\tif (secondaryDiscountAmount > data.secondaryAmountBeforeCoupon) {\n\t\t\tsecondaryDiscountAmount = data.secondaryAmountBeforeCoupon;\n\t\t}\n\n\t\tconst referrerName = await couponHelperService.fetchUserName(coupon.referralUser._id);\n\n\t\tconst couponRepository = new CouponRepository();\n\n\t\treturn couponHelperService.buildCouponResponse(\n\t\t\tdata,\n\t\t\tdiscountAmount,\n\t\t\tsecondaryDiscountAmount,\n\t\t\tfalse, // company pays\n\t\t\tcouponRepository.addLabelsToCoupons([\n\t\t\t\t{\n\t\t\t\t\t...coupon.toJSON(),\n\t\t\t\t\treferringUser: { name: referrerName },\n\t\t\t\t\tvalue: referralCouponSettings.receiver?.value,\n\t\t\t\t\tvalueType: referralCouponSettings.receiver?.valueType,\n\t\t\t\t\tminimumOrderValue: referralCouponSettings.receiver?.minimumOrderValue,\n\t\t\t\t\tsecondaryCurrencyValue:\n\t\t\t\t\t\treferralCouponSettings.receiver?.valueType == ValueType.FIXED\n\t\t\t\t\t\t\t? await convertToSecondary(referralCouponSettings.receiver?.value ?? 0)\n\t\t\t\t\t\t\t: null,\n\t\t\t\t\tsecondaryCurrencyMinOrderValue: await convertToSecondary(\n\t\t\t\t\t\treferralCouponSettings.receiver?.minimumOrderValue ?? 0\n\t\t\t\t\t),\n\t\t\t\t},\n\t\t\t])[0]\n\t\t);\n\t}\n\n\tpublic async getReferralCodeCoupon(\n\t\tuserId: mongoose.Types.ObjectId\n\t): Promise<ReferralCodeCouponResponseDTO> {\n\t\tlet coupon = await this.model.findOne({ referralUser: userId });\n\n\t\tif (!coupon) {\n\t\t\tcoupon = await this.createReferralCodeForUser(userId);\n\t\t}\n\t\tconst referral = coupon as unknown as Model;\n\n\t\treturn {\n\t\t\tcode: referral.code,\n\t\t\ttext: `Download Lyxa and explore the wide variety of offerings and benefits!\\nUse my code at checkout to claim a special coupon: ${referral.code}.\\nhttps://request.lyxa.ai/app/user/home/share`,\n\t\t};\n\t}\n\n\tprivate async getReferralSettings(): Promise<DocumentType<ReferralSetting>> {\n\t\tconst referralSetting = await this.settingsModel.findOne({});\n\t\tif (!referralSetting) notFoundError('Referral setting not found');\n\t\treturn referralSetting;\n\t}\n}\n\nexport const referralCodeCouponService = Container.get(ReferralCodeCouponService);\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"referral-reward-coupon.service.d.ts","sourceRoot":"/","sources":["modules/coupon/services/referral-reward-coupon.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAEN,oBAAoB,IAAI,KAAK,EAU7B,MAAM,4CAA4C,CAAC;AACpD,OAAO,EACN,yBAAyB,EACzB,6BAA6B,IAAI,SAAS,EAC1C,6BAA6B,IAAI,SAAS,EAC1C,iBAAiB,EACjB,MAAM,6BAA6B,CAAC;AAMrC,qBACa,2BAA2B;IACvC,OAAO,CAAC,KAAK,CAA4D;IACzE,OAAO,CAAC,WAAW,CAA+C;IAClE,OAAO,CAAC,aAAa,CAAiE;IACtF,OAAO,CAAC,SAAS,CAA2C;IAC5D,OAAO,CAAC,UAAU,CAA2D;;IAehE,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IASrD,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAuB9E,OAAO,CAAC,YAAY;YASN,kBAAkB;IAanB,4BAA4B,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ;IA0D7D,cAAc,CAC1B,IAAI,EAAE,iBAAiB,EACvB,cAAc,EAAE,YAAY,CAAC,KAAK,CAAC,GACjC,OAAO,CAAC,yBAAyB,CAAC;YAiEvB,mBAAmB;CAUjC;AAED,eAAO,MAAM,2BAA2B,6BAA6C,CAAC"}
1
+ {"version":3,"file":"referral-reward-coupon.service.d.ts","sourceRoot":"/","sources":["modules/coupon/services/referral-reward-coupon.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAEN,oBAAoB,IAAI,KAAK,EAU7B,MAAM,4CAA4C,CAAC;AACpD,OAAO,EACN,yBAAyB,EACzB,6BAA6B,IAAI,SAAS,EAC1C,6BAA6B,IAAI,SAAS,EAC1C,iBAAiB,EACjB,MAAM,6BAA6B,CAAC;AAQrC,qBACa,2BAA2B;IACvC,OAAO,CAAC,KAAK,CAA4D;IACzE,OAAO,CAAC,WAAW,CAA+C;IAClE,OAAO,CAAC,aAAa,CAAiE;IACtF,OAAO,CAAC,SAAS,CAA2C;IAC5D,OAAO,CAAC,UAAU,CAA2D;;IAehE,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IASrD,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAuB9E,OAAO,CAAC,YAAY;YASN,kBAAkB;IAanB,4BAA4B,CAAC,OAAO,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ;IAmE7D,cAAc,CAC1B,IAAI,EAAE,iBAAiB,EACvB,cAAc,EAAE,YAAY,CAAC,KAAK,CAAC,GACjC,OAAO,CAAC,yBAAyB,CAAC;YAiEvB,mBAAmB;CAUjC;AAED,eAAO,MAAM,2BAA2B,6BAA6C,CAAC"}
@@ -49,6 +49,7 @@ const models_1 = require("@lyxa.ai/core/dist/libraries/mongo/models/");
49
49
  const enum_1 = require("@lyxa.ai/core/dist/utilities/enum");
50
50
  const currency_1 = require("@lyxa.ai/core/dist/utilities/currency");
51
51
  const shared_1 = require("@lyxa.ai/core/dist/utilities/shared");
52
+ const core_1 = require("@lyxa.ai/core");
52
53
  let ReferralRewardCouponService = class ReferralRewardCouponService {
53
54
  model;
54
55
  couponModel;
@@ -141,6 +142,9 @@ let ReferralRewardCouponService = class ReferralRewardCouponService {
141
142
  isTotalOrderLimitEnabled: true,
142
143
  });
143
144
  await this.userModel.findByIdAndUpdate(user, { $push: { coupons: referralRewardCoupon._id } }, { new: true, runValidators: true });
145
+ const dispatcher = (0, core_1.getLibraries)().getMicroServiceDispatcher();
146
+ const notificationRouter = await dispatcher.getMicroService('notification');
147
+ await notificationRouter.notificationRouter.sendPushNotificationForCoupon.mutate(referralRewardCoupon._id);
144
148
  }
145
149
  async validateCoupon(data, couponDocument) {
146
150
  if (couponDocument.isMinOrderValueEnabled &&
@@ -148,7 +152,7 @@ let ReferralRewardCouponService = class ReferralRewardCouponService {
148
152
  couponDocument.minOrderValue > data.amountBeforeCoupon) {
149
153
  return {
150
154
  isValid: false,
151
- message: 'Minimum order amount not met',
155
+ message: `Minimum order amount ${couponDocument.minOrderValue}$ is not met!`,
152
156
  };
153
157
  }
154
158
  if (couponDocument.user._id.toString() != data.user?.toString()) {
@@ -1 +1 @@
1
- {"version":3,"file":"referral-reward-coupon.service.js","sourceRoot":"/","sources":["modules/coupon/services/referral-reward-coupon.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, { Service } from 'typedi';\nimport { TRPCError } from '@trpc/server';\nimport { DocumentType, mongoose } from '@typegoose/typegoose';\nimport {\n\tReferralRewardCouponModel,\n\tReferralRewardCoupon as Model,\n\tReferralSetting,\n\tReferralSettingModel,\n\tRegularOrder,\n\tUser,\n\tUserModel,\n\tRegularOrderModel,\n\tCouponModel,\n\tCoupon,\n\tReferralCodeCoupon,\n} from '@lyxa.ai/core/dist/libraries/mongo/models/';\nimport {\n\tCouponValidationOutputDTO,\n\tCreateReferralRewardCouponDTO as CreateDTO,\n\tUpdateReferralRewardCouponDTO as UpdateDTO,\n\tValidateCouponDTO,\n} from '@modules/coupon/validations';\nimport { SoftDeleteModel } from '@lyxa.ai/core/dist/libraries/mongo/plugins/soft-delete-plugin';\nimport { CouponType, Status, ValueType } from '@lyxa.ai/core/dist/utilities/enum';\nimport { convertToSecondary } from '@lyxa.ai/core/dist/utilities/currency';\nimport { roundBaseCurrency, roundSecondaryCurrency } from '@lyxa.ai/core/dist/utilities/shared';\n\n@Service()\nexport class ReferralRewardCouponService {\n\tprivate model: typeof ReferralRewardCouponModel & SoftDeleteModel<Model>;\n\tprivate couponModel: typeof CouponModel & SoftDeleteModel<Coupon>;\n\tprivate settingsModel: typeof ReferralSettingModel & SoftDeleteModel<ReferralSetting>;\n\tprivate userModel: typeof UserModel & SoftDeleteModel<User>;\n\tprivate orderModel: typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\n\tconstructor() {\n\t\tthis.model = ReferralRewardCouponModel as typeof ReferralRewardCouponModel & SoftDeleteModel<Model>;\n\t\tthis.couponModel = CouponModel as typeof CouponModel & SoftDeleteModel<Coupon>;\n\t\tthis.settingsModel = ReferralSettingModel as typeof ReferralSettingModel &\n\t\t\tSoftDeleteModel<ReferralSetting>;\n\t\tthis.userModel = UserModel as typeof UserModel & SoftDeleteModel<User>;\n\t\tthis.orderModel = RegularOrderModel as typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\t}\n\n\t/**\n\t * Create a new record\n\t * @param data Data for the new record\n\t */\n\tpublic async create(data: CreateDTO): Promise<DocumentType<Model>> {\n\t\treturn await this.model.create(data);\n\t}\n\n\t/**\n\t * Update record\n\t * @param id ID of the record\n\t * @param data Data to update\n\t */\n\tpublic async update(id: string, data: UpdateDTO): Promise<DocumentType<Model>> {\n\t\tconst record = await this.model.findOneAndUpdate(\n\t\t\t{\n\t\t\t\t_id: id,\n\t\t\t\tdeletedAt: null,\n\t\t\t},\n\t\t\tdata,\n\t\t\t{\n\t\t\t\tnew: true,\n\t\t\t\trunValidators: true,\n\t\t\t}\n\t\t);\n\n\t\tif (!record) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'NOT_FOUND',\n\t\t\t\tmessage: `Record not found`,\n\t\t\t});\n\t\t}\n\n\t\treturn record;\n\t}\n\n\tprivate generateCode(length = 6): string {\n\t\tconst chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n\t\tlet result = '';\n\t\tfor (let i = 0; i < length; i++) {\n\t\t\tresult += chars.charAt(Math.floor(Math.random() * chars.length));\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate async generateCouponCode(): Promise<string> {\n\t\tlet code: string = 'SAMPLE';\n\t\tlet exists = true;\n\n\t\twhile (exists) {\n\t\t\tcode = this.generateCode();\n\t\t\texists = (await this.model.exists({ code: code })) ? true : false;\n\t\t}\n\n\t\treturn code;\n\t}\n\n\t// give referral reward to user\n\tpublic async giveReferralRewardToReferrer(orderId: mongoose.Types.ObjectId) {\n\t\tconst order = (await this.orderModel.findById(orderId)) as DocumentType<RegularOrder>;\n\n\t\tif (!order) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!order.adjustedFinance?.coupon?.coupon?._id) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst orderCoupon = await this.couponModel.findById(order.adjustedFinance?.coupon?.coupon?._id);\n\n\t\tif (!orderCoupon || orderCoupon.couponType !== CouponType.REFERRAL_CODE) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst user = (orderCoupon as DocumentType<ReferralCodeCoupon>).referralUser;\n\n\t\tconst referralCouponSettings = await this.getReferralSettings();\n\n\t\tif (!referralCouponSettings.sender) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst referralRewardCoupon = await this.create({\n\t\t\tcode: await this.generateCouponCode(),\n\t\t\tstatus: Status.ACTIVE,\n\t\t\tcouponType: CouponType.REFERRAL_REWARD,\n\t\t\tduration: {\n\t\t\t\tstart: new Date(),\n\t\t\t},\n\t\t\tforNewUserOnly: false,\n\t\t\tuser: user._id,\n\t\t\tminOrderValue: referralCouponSettings.sender?.minimumOrderValue ?? null,\n\t\t\tvalue: referralCouponSettings.sender?.value,\n\t\t\tvalueType: referralCouponSettings.sender?.valueType,\n\t\t\treferralCodeUsedBy: order.user as mongoose.Types.ObjectId,\n\t\t\treferralCodeUsedOnOrder: order._id,\n\t\t\texpirationReason: null,\n\t\t\tmaxDiscountLimit: null,\n\t\t\torderLimitPerUser: 1,\n\t\t\tspendLimit: null,\n\t\t\ttotalOrderLimit: 1,\n\t\t\tisMinOrderValueEnabled: !!referralCouponSettings.sender?.minimumOrderValue,\n\t\t\tisMaxDiscountLimitEnabled: false,\n\t\t\tisOrderLimitPerUserEnabled: true,\n\t\t\tisSpendLimitEnabled: false,\n\t\t\tisTotalOrderLimitEnabled: true,\n\t\t});\n\n\t\tawait this.userModel.findByIdAndUpdate(\n\t\t\tuser,\n\t\t\t{ $push: { coupons: referralRewardCoupon._id } },\n\t\t\t{ new: true, runValidators: true }\n\t\t);\n\t}\n\n\tpublic async validateCoupon(\n\t\tdata: ValidateCouponDTO,\n\t\tcouponDocument: DocumentType<Model>\n\t): Promise<CouponValidationOutputDTO> {\n\t\tif (\n\t\t\tcouponDocument.isMinOrderValueEnabled &&\n\t\t\tcouponDocument.minOrderValue &&\n\t\t\tcouponDocument.minOrderValue > data.amountBeforeCoupon\n\t\t) {\n\t\t\t// throw new TRPCError({\n\t\t\t// \tcode: 'BAD_REQUEST',\n\t\t\t// \tmessage: 'Amount is lower than the minimum order amount',\n\t\t\t// });\n\t\t\treturn {\n\t\t\t\tisValid: false,\n\t\t\t\tmessage: 'Minimum order amount not met',\n\t\t\t};\n\t\t}\n\n\t\tif (couponDocument.user._id.toString() != data.user?.toString()) {\n\t\t\treturn {\n\t\t\t\tisValid: false,\n\t\t\t\tmessage: 'This reward is not for you',\n\t\t\t};\n\t\t}\n\n\t\tlet discountAmount =\n\t\t\tcouponDocument.valueType == ValueType.FIXED\n\t\t\t\t? couponDocument.value\n\t\t\t\t: roundBaseCurrency((data.amountBeforeCoupon * couponDocument.value) / 100);\n\n\t\tlet secondaryDiscountAmount =\n\t\t\tcouponDocument.valueType == ValueType.FIXED\n\t\t\t\t? await convertToSecondary(couponDocument.value)\n\t\t\t\t: roundSecondaryCurrency((data.secondaryAmountBeforeCoupon * couponDocument.value) / 100);\n\n\t\tif (couponDocument.isMaxDiscountLimitEnabled && couponDocument.maxDiscountLimit) {\n\t\t\tdiscountAmount = Math.min(discountAmount, couponDocument.maxDiscountLimit);\n\t\t\tsecondaryDiscountAmount = Math.min(\n\t\t\t\tsecondaryDiscountAmount,\n\t\t\t\tawait convertToSecondary(couponDocument.maxDiscountLimit)\n\t\t\t);\n\t\t}\n\n\t\tif (discountAmount > data.amountBeforeCoupon) {\n\t\t\tdiscountAmount = data.amountBeforeCoupon;\n\t\t}\n\t\tif (secondaryDiscountAmount > data.secondaryAmountBeforeCoupon) {\n\t\t\tsecondaryDiscountAmount = data.secondaryAmountBeforeCoupon;\n\t\t}\n\n\t\treturn {\n\t\t\tisValid: true,\n\t\t\tdiscountAmount,\n\t\t\tsecondaryDiscountAmount,\n\t\t\tamountAfterCoupon: roundBaseCurrency(data.amountBeforeCoupon - discountAmount),\n\t\t\tsecondaryAmountAfterCoupon: roundSecondaryCurrency(\n\t\t\t\tdata.secondaryAmountBeforeCoupon - secondaryDiscountAmount\n\t\t\t),\n\t\t\tdiscountCut: {\n\t\t\t\tcompanyCut: discountAmount,\n\t\t\t\tsecondaryCompanyCut: secondaryDiscountAmount,\n\t\t\t\tshopCut: 0,\n\t\t\t\tsecondaryShopCut: 0,\n\t\t\t},\n\t\t};\n\t}\n\n\tprivate async getReferralSettings(): Promise<DocumentType<ReferralSetting>> {\n\t\tconst referralSetting = await this.settingsModel.findOne({});\n\t\tif (!referralSetting) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'NOT_FOUND',\n\t\t\t\tmessage: 'Referral setting not found',\n\t\t\t});\n\t\t}\n\t\treturn referralSetting;\n\t}\n}\n\nexport const referralRewardCouponService = Container.get(ReferralRewardCouponService);\n"]}
1
+ {"version":3,"file":"referral-reward-coupon.service.js","sourceRoot":"/","sources":["modules/coupon/services/referral-reward-coupon.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, { Service } from 'typedi';\nimport { TRPCError } from '@trpc/server';\nimport { DocumentType, mongoose } from '@typegoose/typegoose';\nimport {\n\tReferralRewardCouponModel,\n\tReferralRewardCoupon as Model,\n\tReferralSetting,\n\tReferralSettingModel,\n\tRegularOrder,\n\tUser,\n\tUserModel,\n\tRegularOrderModel,\n\tCouponModel,\n\tCoupon,\n\tReferralCodeCoupon,\n} from '@lyxa.ai/core/dist/libraries/mongo/models/';\nimport {\n\tCouponValidationOutputDTO,\n\tCreateReferralRewardCouponDTO as CreateDTO,\n\tUpdateReferralRewardCouponDTO as UpdateDTO,\n\tValidateCouponDTO,\n} from '@modules/coupon/validations';\nimport { SoftDeleteModel } from '@lyxa.ai/core/dist/libraries/mongo/plugins/soft-delete-plugin';\nimport { CouponType, Status, ValueType } from '@lyxa.ai/core/dist/utilities/enum';\nimport { convertToSecondary } from '@lyxa.ai/core/dist/utilities/currency';\nimport { roundBaseCurrency, roundSecondaryCurrency } from '@lyxa.ai/core/dist/utilities/shared';\nimport { getLibraries } from '@lyxa.ai/core';\nimport { NotificationMicroserviceRouter } from '@lyxa.ai/notification';\n\n@Service()\nexport class ReferralRewardCouponService {\n\tprivate model: typeof ReferralRewardCouponModel & SoftDeleteModel<Model>;\n\tprivate couponModel: typeof CouponModel & SoftDeleteModel<Coupon>;\n\tprivate settingsModel: typeof ReferralSettingModel & SoftDeleteModel<ReferralSetting>;\n\tprivate userModel: typeof UserModel & SoftDeleteModel<User>;\n\tprivate orderModel: typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\n\tconstructor() {\n\t\tthis.model = ReferralRewardCouponModel as typeof ReferralRewardCouponModel & SoftDeleteModel<Model>;\n\t\tthis.couponModel = CouponModel as typeof CouponModel & SoftDeleteModel<Coupon>;\n\t\tthis.settingsModel = ReferralSettingModel as typeof ReferralSettingModel &\n\t\t\tSoftDeleteModel<ReferralSetting>;\n\t\tthis.userModel = UserModel as typeof UserModel & SoftDeleteModel<User>;\n\t\tthis.orderModel = RegularOrderModel as typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\t}\n\n\t/**\n\t * Create a new record\n\t * @param data Data for the new record\n\t */\n\tpublic async create(data: CreateDTO): Promise<DocumentType<Model>> {\n\t\treturn await this.model.create(data);\n\t}\n\n\t/**\n\t * Update record\n\t * @param id ID of the record\n\t * @param data Data to update\n\t */\n\tpublic async update(id: string, data: UpdateDTO): Promise<DocumentType<Model>> {\n\t\tconst record = await this.model.findOneAndUpdate(\n\t\t\t{\n\t\t\t\t_id: id,\n\t\t\t\tdeletedAt: null,\n\t\t\t},\n\t\t\tdata,\n\t\t\t{\n\t\t\t\tnew: true,\n\t\t\t\trunValidators: true,\n\t\t\t}\n\t\t);\n\n\t\tif (!record) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'NOT_FOUND',\n\t\t\t\tmessage: `Record not found`,\n\t\t\t});\n\t\t}\n\n\t\treturn record;\n\t}\n\n\tprivate generateCode(length = 6): string {\n\t\tconst chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';\n\t\tlet result = '';\n\t\tfor (let i = 0; i < length; i++) {\n\t\t\tresult += chars.charAt(Math.floor(Math.random() * chars.length));\n\t\t}\n\t\treturn result;\n\t}\n\n\tprivate async generateCouponCode(): Promise<string> {\n\t\tlet code: string = 'SAMPLE';\n\t\tlet exists = true;\n\n\t\twhile (exists) {\n\t\t\tcode = this.generateCode();\n\t\t\texists = (await this.model.exists({ code: code })) ? true : false;\n\t\t}\n\n\t\treturn code;\n\t}\n\n\t// give referral reward to user\n\tpublic async giveReferralRewardToReferrer(orderId: mongoose.Types.ObjectId) {\n\t\tconst order = (await this.orderModel.findById(orderId)) as DocumentType<RegularOrder>;\n\n\t\tif (!order) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (!order.adjustedFinance?.coupon?.coupon?._id) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst orderCoupon = await this.couponModel.findById(order.adjustedFinance?.coupon?.coupon?._id);\n\n\t\tif (!orderCoupon || orderCoupon.couponType !== CouponType.REFERRAL_CODE) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst user = (orderCoupon as DocumentType<ReferralCodeCoupon>).referralUser;\n\n\t\tconst referralCouponSettings = await this.getReferralSettings();\n\n\t\tif (!referralCouponSettings.sender) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst referralRewardCoupon = await this.create({\n\t\t\tcode: await this.generateCouponCode(),\n\t\t\tstatus: Status.ACTIVE,\n\t\t\tcouponType: CouponType.REFERRAL_REWARD,\n\t\t\tduration: {\n\t\t\t\tstart: new Date(),\n\t\t\t},\n\t\t\tforNewUserOnly: false,\n\t\t\tuser: user._id,\n\t\t\tminOrderValue: referralCouponSettings.sender?.minimumOrderValue ?? null,\n\t\t\tvalue: referralCouponSettings.sender?.value,\n\t\t\tvalueType: referralCouponSettings.sender?.valueType,\n\t\t\treferralCodeUsedBy: order.user as mongoose.Types.ObjectId,\n\t\t\treferralCodeUsedOnOrder: order._id,\n\t\t\texpirationReason: null,\n\t\t\tmaxDiscountLimit: null,\n\t\t\torderLimitPerUser: 1,\n\t\t\tspendLimit: null,\n\t\t\ttotalOrderLimit: 1,\n\t\t\tisMinOrderValueEnabled: !!referralCouponSettings.sender?.minimumOrderValue,\n\t\t\tisMaxDiscountLimitEnabled: false,\n\t\t\tisOrderLimitPerUserEnabled: true,\n\t\t\tisSpendLimitEnabled: false,\n\t\t\tisTotalOrderLimitEnabled: true,\n\t\t});\n\n\t\tawait this.userModel.findByIdAndUpdate(\n\t\t\tuser,\n\t\t\t{ $push: { coupons: referralRewardCoupon._id } },\n\t\t\t{ new: true, runValidators: true }\n\t\t);\n\n\t\t// Send Notification\n\t\tconst dispatcher = getLibraries().getMicroServiceDispatcher();\n\t\tconst notificationRouter =\n\t\t\tawait dispatcher.getMicroService<NotificationMicroserviceRouter>('notification');\n\n\t\tawait notificationRouter.notificationRouter.sendPushNotificationForCoupon.mutate(\n\t\t\treferralRewardCoupon._id\n\t\t);\n\t}\n\n\tpublic async validateCoupon(\n\t\tdata: ValidateCouponDTO,\n\t\tcouponDocument: DocumentType<Model>\n\t): Promise<CouponValidationOutputDTO> {\n\t\tif (\n\t\t\tcouponDocument.isMinOrderValueEnabled &&\n\t\t\tcouponDocument.minOrderValue &&\n\t\t\tcouponDocument.minOrderValue > data.amountBeforeCoupon\n\t\t) {\n\t\t\t// throw new TRPCError({\n\t\t\t// \tcode: 'BAD_REQUEST',\n\t\t\t// \tmessage: 'Amount is lower than the minimum order amount',\n\t\t\t// });\n\t\t\treturn {\n\t\t\t\tisValid: false,\n\t\t\t\tmessage: `Minimum order amount ${couponDocument.minOrderValue}$ is not met!`,\n\t\t\t};\n\t\t}\n\n\t\tif (couponDocument.user._id.toString() != data.user?.toString()) {\n\t\t\treturn {\n\t\t\t\tisValid: false,\n\t\t\t\tmessage: 'This reward is not for you',\n\t\t\t};\n\t\t}\n\n\t\tlet discountAmount =\n\t\t\tcouponDocument.valueType == ValueType.FIXED\n\t\t\t\t? couponDocument.value\n\t\t\t\t: roundBaseCurrency((data.amountBeforeCoupon * couponDocument.value) / 100);\n\n\t\tlet secondaryDiscountAmount =\n\t\t\tcouponDocument.valueType == ValueType.FIXED\n\t\t\t\t? await convertToSecondary(couponDocument.value)\n\t\t\t\t: roundSecondaryCurrency((data.secondaryAmountBeforeCoupon * couponDocument.value) / 100);\n\n\t\tif (couponDocument.isMaxDiscountLimitEnabled && couponDocument.maxDiscountLimit) {\n\t\t\tdiscountAmount = Math.min(discountAmount, couponDocument.maxDiscountLimit);\n\t\t\tsecondaryDiscountAmount = Math.min(\n\t\t\t\tsecondaryDiscountAmount,\n\t\t\t\tawait convertToSecondary(couponDocument.maxDiscountLimit)\n\t\t\t);\n\t\t}\n\n\t\tif (discountAmount > data.amountBeforeCoupon) {\n\t\t\tdiscountAmount = data.amountBeforeCoupon;\n\t\t}\n\t\tif (secondaryDiscountAmount > data.secondaryAmountBeforeCoupon) {\n\t\t\tsecondaryDiscountAmount = data.secondaryAmountBeforeCoupon;\n\t\t}\n\n\t\treturn {\n\t\t\tisValid: true,\n\t\t\tdiscountAmount,\n\t\t\tsecondaryDiscountAmount,\n\t\t\tamountAfterCoupon: roundBaseCurrency(data.amountBeforeCoupon - discountAmount),\n\t\t\tsecondaryAmountAfterCoupon: roundSecondaryCurrency(\n\t\t\t\tdata.secondaryAmountBeforeCoupon - secondaryDiscountAmount\n\t\t\t),\n\t\t\tdiscountCut: {\n\t\t\t\tcompanyCut: discountAmount,\n\t\t\t\tsecondaryCompanyCut: secondaryDiscountAmount,\n\t\t\t\tshopCut: 0,\n\t\t\t\tsecondaryShopCut: 0,\n\t\t\t},\n\t\t};\n\t}\n\n\tprivate async getReferralSettings(): Promise<DocumentType<ReferralSetting>> {\n\t\tconst referralSetting = await this.settingsModel.findOne({});\n\t\tif (!referralSetting) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'NOT_FOUND',\n\t\t\t\tmessage: 'Referral setting not found',\n\t\t\t});\n\t\t}\n\t\treturn referralSetting;\n\t}\n}\n\nexport const referralRewardCouponService = Container.get(ReferralRewardCouponService);\n"]}
@@ -1,6 +1,6 @@
1
- import { DocumentType } from '@typegoose/typegoose';
1
+ import { DocumentType, mongoose } from '@typegoose/typegoose';
2
2
  import { ShopsCategoriesCoupon as Model } from '@lyxa.ai/core/dist/libraries/mongo/models/';
3
- import { CouponValidationOutputDTO, CreateShopsCategoriesCouponDTO as CreateDTO, UpdateShopsCategoriesCouponDTO as UpdateDTO, ValidateCouponDTO } from '../../coupon/validations';
3
+ import { CreateShopsCategoriesCouponDTO as CreateDTO, UpdateShopsCategoriesCouponDTO as UpdateDTO, ValidateCouponDTO } from '../../coupon/validations';
4
4
  export declare class ShopsCategoriesCouponService {
5
5
  private model;
6
6
  private readonly shopModelForCoupon;
@@ -8,7 +8,33 @@ export declare class ShopsCategoriesCouponService {
8
8
  constructor();
9
9
  create(data: CreateDTO): Promise<DocumentType<Model>>;
10
10
  update(id: string, data: UpdateDTO): Promise<DocumentType<Model>>;
11
- validateCoupon(data: ValidateCouponDTO, couponDocument: DocumentType<Model>): Promise<CouponValidationOutputDTO>;
11
+ validateCoupon(data: ValidateCouponDTO, coupon: DocumentType<Model>): Promise<{
12
+ isValid: boolean;
13
+ message?: string | undefined;
14
+ amountAfterCoupon?: number | undefined;
15
+ secondaryAmountAfterCoupon?: number | undefined;
16
+ discountAmount?: number | undefined;
17
+ secondaryDiscountAmount?: number | undefined;
18
+ discountCut?: {
19
+ companyCut?: number | undefined;
20
+ secondaryCompanyCut?: number | undefined;
21
+ shopCut?: number | undefined;
22
+ secondaryShopCut?: number | undefined;
23
+ } | undefined;
24
+ couponDetails?: Record<string, unknown> | undefined;
25
+ } | {
26
+ isValid: boolean;
27
+ message: string;
28
+ shop?: undefined;
29
+ } | {
30
+ isValid: boolean;
31
+ shop: mongoose.Document<unknown, import("@typegoose/typegoose/lib/types").BeAnObject, import("@lyxa.ai/core/dist/libraries/mongo/models/shop.model").Shop, import("@typegoose/typegoose/lib/types").BeAnyObject, {}> & Omit<import("@lyxa.ai/core/dist/libraries/mongo/models/shop.model").Shop & {
32
+ _id: mongoose.Types.ObjectId;
33
+ } & {
34
+ __v: number;
35
+ }, "typegooseName"> & import("@typegoose/typegoose/lib/types").IObjectWithTypegooseFunction;
36
+ message?: undefined;
37
+ }>;
12
38
  }
13
39
  export declare const shopsCategoriesCouponService: ShopsCategoriesCouponService;
14
40
  //# sourceMappingURL=shops-categories-coupon.service.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"shops-categories-coupon.service.d.ts","sourceRoot":"/","sources":["modules/coupon/services/shops-categories-coupon.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAY,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAEN,qBAAqB,IAAI,KAAK,EAI9B,MAAM,4CAA4C,CAAC;AACpD,OAAO,EACN,yBAAyB,EACzB,8BAA8B,IAAI,SAAS,EAC3C,8BAA8B,IAAI,SAAS,EAC3C,iBAAiB,EACjB,MAAM,6BAA6B,CAAC;AAMrC,qBACa,4BAA4B;IACxC,OAAO,CAAC,KAAK,CAAC;IACd,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAmB;IACtD,OAAO,CAAC,UAAU,CAA2D;;IAYhE,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAWrD,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAuBjE,cAAc,CAC1B,IAAI,EAAE,iBAAiB,EACvB,cAAc,EAAE,YAAY,CAAC,KAAK,CAAC,GACjC,OAAO,CAAC,yBAAyB,CAAC;CAiFrC;AAED,eAAO,MAAM,4BAA4B,8BAA8C,CAAC"}
1
+ {"version":3,"file":"shops-categories-coupon.service.d.ts","sourceRoot":"/","sources":["modules/coupon/services/shops-categories-coupon.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAEN,qBAAqB,IAAI,KAAK,EAI9B,MAAM,4CAA4C,CAAC;AACpD,OAAO,EACN,8BAA8B,IAAI,SAAS,EAC3C,8BAA8B,IAAI,SAAS,EAC3C,iBAAiB,EACjB,MAAM,6BAA6B,CAAC;AAIrC,qBACa,4BAA4B;IACxC,OAAO,CAAC,KAAK,CAAC;IACd,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAAmB;IACtD,OAAO,CAAC,UAAU,CAA2D;;IAYhE,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAWrD,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAuBjE,cAAc,CAAC,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,YAAY,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;CAoBhF;AAED,eAAO,MAAM,4BAA4B,8BAA8C,CAAC"}
@@ -45,11 +45,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
45
45
  exports.shopsCategoriesCouponService = exports.ShopsCategoriesCouponService = void 0;
46
46
  const typedi_1 = __importStar(require("typedi"));
47
47
  const server_1 = require("@trpc/server");
48
- const typegoose_1 = require("@typegoose/typegoose");
49
48
  const models_1 = require("@lyxa.ai/core/dist/libraries/mongo/models/");
50
- const currency_1 = require("@lyxa.ai/core/dist/utilities/currency");
51
- const shared_1 = require("@lyxa.ai/core/dist/utilities/shared");
52
- const enum_1 = require("@lyxa.ai/core/dist/utilities/enum");
49
+ const helper_service_1 = require("./helper.service");
53
50
  let ShopsCategoriesCouponService = class ShopsCategoriesCouponService {
54
51
  model;
55
52
  shopModelForCoupon;
@@ -79,65 +76,15 @@ let ShopsCategoriesCouponService = class ShopsCategoriesCouponService {
79
76
  }
80
77
  return record;
81
78
  }
82
- async validateCoupon(data, couponDocument) {
83
- const shopId = new typegoose_1.mongoose.Types.ObjectId(data.shop);
84
- const shop = await this.shopModelForCoupon.findOne({ _id: shopId, deletedAt: null });
85
- if (!shop) {
86
- return {
87
- isValid: false,
88
- message: 'Shop not found',
89
- };
90
- }
91
- if (!couponDocument.shops?.some(s => s.toString() == shopId.toString()) &&
92
- !couponDocument.itemTypes?.includes(shop.itemType)) {
93
- return {
94
- isValid: false,
95
- message: 'Coupon is not valid for this shop',
96
- };
97
- }
98
- if (couponDocument.firstOrderOnly) {
99
- const order = await this.orderModel.findOne({
100
- user: new typegoose_1.mongoose.Types.ObjectId(data.user),
101
- shop: new typegoose_1.mongoose.Types.ObjectId(data.shop),
102
- status: { $ne: enum_1.RegularOrderStatus.CANCELLED },
103
- });
104
- if (order) {
105
- return {
106
- isValid: false,
107
- message: 'This coupon is only valid for the first order in the shop',
108
- };
109
- }
110
- }
111
- let discountAmount = couponDocument.valueType == enum_1.ValueType.FIXED
112
- ? couponDocument.value
113
- : (0, shared_1.roundBaseCurrency)((data.amountBeforeCoupon * couponDocument.value) / 100);
114
- let secondaryDiscountAmount = couponDocument.valueType == enum_1.ValueType.FIXED
115
- ? await (0, currency_1.convertToSecondary)(couponDocument.value)
116
- : (0, shared_1.roundSecondaryCurrency)((data.secondaryAmountBeforeCoupon * couponDocument.value) / 100);
117
- if (couponDocument.isMaxDiscountLimitEnabled && couponDocument.maxDiscountLimit) {
118
- discountAmount = Math.min(discountAmount, couponDocument.maxDiscountLimit);
119
- secondaryDiscountAmount = Math.min(secondaryDiscountAmount, await (0, currency_1.convertToSecondary)(couponDocument.maxDiscountLimit));
120
- }
121
- if (discountAmount > data.amountBeforeCoupon) {
122
- discountAmount = data.amountBeforeCoupon;
123
- }
124
- if (secondaryDiscountAmount > data.secondaryAmountBeforeCoupon) {
125
- secondaryDiscountAmount = data.secondaryAmountBeforeCoupon;
126
- }
127
- const isShopCoverExpenses = couponDocument.isShopCoverExpenses;
128
- return {
129
- isValid: true,
130
- discountAmount,
131
- secondaryDiscountAmount,
132
- amountAfterCoupon: (0, shared_1.roundBaseCurrency)(data.amountBeforeCoupon - discountAmount),
133
- secondaryAmountAfterCoupon: (0, shared_1.roundSecondaryCurrency)(data.secondaryAmountBeforeCoupon - secondaryDiscountAmount),
134
- discountCut: {
135
- companyCut: isShopCoverExpenses ? 0 : discountAmount,
136
- secondaryCompanyCut: isShopCoverExpenses ? 0 : secondaryDiscountAmount,
137
- shopCut: isShopCoverExpenses ? discountAmount : 0,
138
- secondaryShopCut: isShopCoverExpenses ? secondaryDiscountAmount : 0,
139
- },
140
- };
79
+ async validateCoupon(data, coupon) {
80
+ const validation = await helper_service_1.couponHelperService.validateShopEligibility({
81
+ data,
82
+ coupon
83
+ });
84
+ if (!validation.isValid)
85
+ return validation;
86
+ const { discountAmount, secondaryDiscountAmount } = await helper_service_1.couponHelperService.calculateCouponDiscount(data, coupon);
87
+ return helper_service_1.couponHelperService.buildCouponResponse(data, discountAmount, secondaryDiscountAmount, coupon.isShopCoverExpenses ?? false);
141
88
  }
142
89
  };
143
90
  exports.ShopsCategoriesCouponService = ShopsCategoriesCouponService;
@@ -1 +1 @@
1
- {"version":3,"file":"shops-categories-coupon.service.js","sourceRoot":"/","sources":["modules/coupon/services/shops-categories-coupon.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, { Service } from 'typedi';\nimport { TRPCError } from '@trpc/server';\nimport { DocumentType, mongoose } from '@typegoose/typegoose';\nimport {\n\tShopsCategoriesCouponModel,\n\tShopsCategoriesCoupon as Model,\n\tRegularOrder,\n\tRegularOrderModel,\n\tShopModel,\n} from '@lyxa.ai/core/dist/libraries/mongo/models/';\nimport {\n\tCouponValidationOutputDTO,\n\tCreateShopsCategoriesCouponDTO as CreateDTO,\n\tUpdateShopsCategoriesCouponDTO as UpdateDTO,\n\tValidateCouponDTO,\n} from '@modules/coupon/validations';\nimport { convertToSecondary } from '@lyxa.ai/core/dist/utilities/currency';\nimport { roundBaseCurrency, roundSecondaryCurrency } from '@lyxa.ai/core/dist/utilities/shared';\nimport { RegularOrderStatus, ValueType } from '@lyxa.ai/core/dist/utilities/enum';\nimport { SoftDeleteModel } from '@lyxa.ai/core/dist/libraries/mongo/plugins/soft-delete-plugin';\n\n@Service()\nexport class ShopsCategoriesCouponService {\n\tprivate model;\n\tprivate readonly shopModelForCoupon: typeof ShopModel;\n\tprivate orderModel: typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\n\tconstructor() {\n\t\tthis.model = ShopsCategoriesCouponModel;\n\t\tthis.shopModelForCoupon = ShopModel as typeof ShopModel;\n\t\tthis.orderModel = RegularOrderModel as typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\t}\n\n\t/**\n\t * Create a new record\n\t * @param data Data for the new record\n\t */\n\tpublic async create(data: CreateDTO): Promise<DocumentType<Model>> {\n\t\tconst coupon = this.model.create(data);\n\n\t\treturn coupon;\n\t}\n\n\t/**\n\t * Update record\n\t * @param id ID of the record\n\t * @param data Data to update\n\t */\n\tpublic async update(id: string, data: UpdateDTO): Promise<DocumentType<Model>> {\n\t\tconst record = await this.model.findOneAndUpdate(\n\t\t\t{\n\t\t\t\t_id: id,\n\t\t\t\tdeletedAt: null,\n\t\t\t},\n\t\t\tdata,\n\t\t\t{\n\t\t\t\tnew: true,\n\t\t\t\trunValidators: true,\n\t\t\t}\n\t\t);\n\n\t\tif (!record) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'NOT_FOUND',\n\t\t\t\tmessage: `Record not found`,\n\t\t\t});\n\t\t}\n\n\t\treturn record;\n\t}\n\n\tpublic async validateCoupon(\n\t\tdata: ValidateCouponDTO,\n\t\tcouponDocument: DocumentType<Model>\n\t): Promise<CouponValidationOutputDTO> {\n\t\tconst shopId = new mongoose.Types.ObjectId(data.shop);\n\t\tconst shop = await this.shopModelForCoupon.findOne({ _id: shopId, deletedAt: null });\n\t\tif (!shop) {\n\t\t\treturn {\n\t\t\t\tisValid: false,\n\t\t\t\tmessage: 'Shop not found',\n\t\t\t};\n\t\t}\n\n\t\t// Check if the coupon is applicable to the shop and item-type\n\t\tif (\n\t\t\t!couponDocument.shops?.some(s => s.toString() == shopId.toString()) &&\n\t\t\t!couponDocument.itemTypes?.includes(shop.itemType)\n\t\t) {\n\t\t\treturn {\n\t\t\t\tisValid: false,\n\t\t\t\tmessage: 'Coupon is not valid for this shop',\n\t\t\t};\n\t\t}\n\n\t\t// Add condition to check first order only\n\n\t\tif (couponDocument.firstOrderOnly) {\n\t\t\tconst order = await this.orderModel.findOne({\n\t\t\t\tuser: new mongoose.Types.ObjectId(data.user),\n\t\t\t\tshop: new mongoose.Types.ObjectId(data.shop),\n\t\t\t\tstatus: { $ne: RegularOrderStatus.CANCELLED },\n\t\t\t});\n\n\t\t\tif (order) {\n\t\t\t\treturn {\n\t\t\t\t\tisValid: false,\n\t\t\t\t\tmessage: 'This coupon is only valid for the first order in the shop',\n\t\t\t\t};\n\t\t\t}\n\t\t}\n\n\t\tlet discountAmount =\n\t\t\tcouponDocument.valueType == ValueType.FIXED\n\t\t\t\t? couponDocument.value\n\t\t\t\t: roundBaseCurrency((data.amountBeforeCoupon * couponDocument.value) / 100);\n\n\t\tlet secondaryDiscountAmount =\n\t\t\tcouponDocument.valueType == ValueType.FIXED\n\t\t\t\t? await convertToSecondary(couponDocument.value)\n\t\t\t\t: roundSecondaryCurrency((data.secondaryAmountBeforeCoupon * couponDocument.value) / 100);\n\n\t\tif (couponDocument.isMaxDiscountLimitEnabled && couponDocument.maxDiscountLimit) {\n\t\t\tdiscountAmount = Math.min(discountAmount, couponDocument.maxDiscountLimit);\n\t\t\tsecondaryDiscountAmount = Math.min(\n\t\t\t\tsecondaryDiscountAmount,\n\t\t\t\tawait convertToSecondary(couponDocument.maxDiscountLimit)\n\t\t\t);\n\t\t}\n\n\t\tif (discountAmount > data.amountBeforeCoupon) {\n\t\t\tdiscountAmount = data.amountBeforeCoupon;\n\t\t}\n\t\tif (secondaryDiscountAmount > data.secondaryAmountBeforeCoupon) {\n\t\t\tsecondaryDiscountAmount = data.secondaryAmountBeforeCoupon;\n\t\t}\n\n\t\tconst isShopCoverExpenses = couponDocument.isShopCoverExpenses;\n\n\t\treturn {\n\t\t\tisValid: true,\n\t\t\tdiscountAmount,\n\t\t\tsecondaryDiscountAmount,\n\t\t\tamountAfterCoupon: roundBaseCurrency(data.amountBeforeCoupon - discountAmount),\n\t\t\tsecondaryAmountAfterCoupon: roundSecondaryCurrency(\n\t\t\t\tdata.secondaryAmountBeforeCoupon - secondaryDiscountAmount\n\t\t\t),\n\t\t\tdiscountCut: {\n\t\t\t\tcompanyCut: isShopCoverExpenses ? 0 : discountAmount,\n\t\t\t\tsecondaryCompanyCut: isShopCoverExpenses ? 0 : secondaryDiscountAmount,\n\t\t\t\tshopCut: isShopCoverExpenses ? discountAmount : 0,\n\t\t\t\tsecondaryShopCut: isShopCoverExpenses ? secondaryDiscountAmount : 0,\n\t\t\t},\n\t\t};\n\t}\n}\n\nexport const shopsCategoriesCouponService = Container.get(ShopsCategoriesCouponService);\n"]}
1
+ {"version":3,"file":"shops-categories-coupon.service.js","sourceRoot":"/","sources":["modules/coupon/services/shops-categories-coupon.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iDAA4C;AAC5C,yCAAyC;AAEzC,uEAMoD;AAOpD,qDAAuD;AAGhD,IAAM,4BAA4B,GAAlC,MAAM,4BAA4B;IAChC,KAAK,CAAC;IACG,kBAAkB,CAAmB;IAC9C,UAAU,CAA2D;IAE7E;QACC,IAAI,CAAC,KAAK,GAAG,mCAA0B,CAAC;QACxC,IAAI,CAAC,kBAAkB,GAAG,kBAA6B,CAAC;QACxD,IAAI,CAAC,UAAU,GAAG,0BAA6E,CAAC;IACjG,CAAC;IAMM,KAAK,CAAC,MAAM,CAAC,IAAe;QAClC,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;QAEvC,OAAO,MAAM,CAAC;IACf,CAAC;IAOM,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,IAAe;QAC9C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,gBAAgB,CAC/C;YACC,GAAG,EAAE,EAAE;YACP,SAAS,EAAE,IAAI;SACf,EACD,IAAI,EACJ;YACC,GAAG,EAAE,IAAI;YACT,aAAa,EAAE,IAAI;SACnB,CACD,CAAC;QAEF,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,MAAM,IAAI,kBAAS,CAAC;gBACnB,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,kBAAkB;aAC3B,CAAC,CAAC;QACJ,CAAC;QAED,OAAO,MAAM,CAAC;IACf,CAAC;IAEM,KAAK,CAAC,cAAc,CAAC,IAAuB,EAAE,MAA2B;QAC/E,MAAM,UAAU,GAAG,MAAM,oCAAmB,CAAC,uBAAuB,CAAC;YACpE,IAAI;YACJ,MAAM;SACN,CAAC,CAAC;QAEH,IAAI,CAAC,UAAU,CAAC,OAAO;YAAE,OAAO,UAAU,CAAC;QAE3C,MAAM,EAAE,cAAc,EAAE,uBAAuB,EAAE,GAAG,MAAM,oCAAmB,CAAC,uBAAuB,CACpG,IAAI,EACJ,MAAM,CACN,CAAC;QAEF,OAAO,oCAAmB,CAAC,mBAAmB,CAC7C,IAAI,EACJ,cAAc,EACd,uBAAuB,EACvB,MAAM,CAAC,mBAAmB,IAAI,KAAK,CACnC,CAAC;IACH,CAAC;CACD,CAAA;AArEY,oEAA4B;uCAA5B,4BAA4B;IADxC,IAAA,gBAAO,GAAE;;GACG,4BAA4B,CAqExC;AAEY,QAAA,4BAA4B,GAAG,gBAAS,CAAC,GAAG,CAAC,4BAA4B,CAAC,CAAC","sourcesContent":["import Container, { Service } from 'typedi';\nimport { TRPCError } from '@trpc/server';\nimport { DocumentType, mongoose } from '@typegoose/typegoose';\nimport {\n\tShopsCategoriesCouponModel,\n\tShopsCategoriesCoupon as Model,\n\tRegularOrder,\n\tRegularOrderModel,\n\tShopModel,\n} from '@lyxa.ai/core/dist/libraries/mongo/models/';\nimport {\n\tCreateShopsCategoriesCouponDTO as CreateDTO,\n\tUpdateShopsCategoriesCouponDTO as UpdateDTO,\n\tValidateCouponDTO,\n} from '@modules/coupon/validations';\nimport { SoftDeleteModel } from '@lyxa.ai/core/dist/libraries/mongo/plugins/soft-delete-plugin';\nimport { couponHelperService } from './helper.service';\n\n@Service()\nexport class ShopsCategoriesCouponService {\n\tprivate model;\n\tprivate readonly shopModelForCoupon: typeof ShopModel;\n\tprivate orderModel: typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\n\tconstructor() {\n\t\tthis.model = ShopsCategoriesCouponModel;\n\t\tthis.shopModelForCoupon = ShopModel as typeof ShopModel;\n\t\tthis.orderModel = RegularOrderModel as typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\t}\n\n\t/**\n\t * Create a new record\n\t * @param data Data for the new record\n\t */\n\tpublic async create(data: CreateDTO): Promise<DocumentType<Model>> {\n\t\tconst coupon = this.model.create(data);\n\n\t\treturn coupon;\n\t}\n\n\t/**\n\t * Update record\n\t * @param id ID of the record\n\t * @param data Data to update\n\t */\n\tpublic async update(id: string, data: UpdateDTO): Promise<DocumentType<Model>> {\n\t\tconst record = await this.model.findOneAndUpdate(\n\t\t\t{\n\t\t\t\t_id: id,\n\t\t\t\tdeletedAt: null,\n\t\t\t},\n\t\t\tdata,\n\t\t\t{\n\t\t\t\tnew: true,\n\t\t\t\trunValidators: true,\n\t\t\t}\n\t\t);\n\n\t\tif (!record) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'NOT_FOUND',\n\t\t\t\tmessage: `Record not found`,\n\t\t\t});\n\t\t}\n\n\t\treturn record;\n\t}\n\n\tpublic async validateCoupon(data: ValidateCouponDTO, coupon: DocumentType<Model>) {\n\t\tconst validation = await couponHelperService.validateShopEligibility({\n\t\t\tdata,\n\t\t\tcoupon\n\t\t});\n\n\t\tif (!validation.isValid) return validation;\n\n\t\tconst { discountAmount, secondaryDiscountAmount } = await couponHelperService.calculateCouponDiscount(\n\t\t\tdata,\n\t\t\tcoupon\n\t\t);\n\n\t\treturn couponHelperService.buildCouponResponse(\n\t\t\tdata,\n\t\t\tdiscountAmount,\n\t\t\tsecondaryDiscountAmount,\n\t\t\tcoupon.isShopCoverExpenses ?? false\n\t\t);\n\t}\n}\n\nexport const shopsCategoriesCouponService = Container.get(ShopsCategoriesCouponService);\n"]}