@lyxa.ai/marketing 1.0.41 → 1.0.43
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/lib/event/event-initializations.d.ts.map +1 -1
- package/dist/lib/event/event-initializations.js +3 -0
- package/dist/lib/event/event-initializations.js.map +1 -1
- package/dist/lib/event/event-listeners/event-listeners.d.ts +1 -0
- package/dist/lib/event/event-listeners/event-listeners.d.ts.map +1 -1
- package/dist/lib/event/event-listeners/event-listeners.js +52 -0
- package/dist/lib/event/event-listeners/event-listeners.js.map +1 -1
- package/dist/lib/event/events/marketing-product-seed.event.d.ts +17 -0
- package/dist/lib/event/events/marketing-product-seed.event.d.ts.map +1 -0
- package/dist/lib/event/events/marketing-product-seed.event.js +12 -0
- package/dist/lib/event/events/marketing-product-seed.event.js.map +1 -0
- package/dist/lib/index.d.ts +730 -5
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js +6 -6
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/modules/coupon/routers/coupon.router.d.ts +116 -0
- package/dist/lib/modules/coupon/routers/coupon.router.d.ts.map +1 -1
- package/dist/lib/modules/coupon/routers/coupon.router.js +33 -1
- package/dist/lib/modules/coupon/routers/coupon.router.js.map +1 -1
- package/dist/lib/modules/coupon/services/coupon.service.d.ts +1 -0
- package/dist/lib/modules/coupon/services/coupon.service.d.ts.map +1 -1
- package/dist/lib/modules/coupon/services/coupon.service.js +61 -40
- package/dist/lib/modules/coupon/services/coupon.service.js.map +1 -1
- package/dist/lib/modules/coupon/services/helper.service.d.ts.map +1 -1
- package/dist/lib/modules/coupon/services/helper.service.js +11 -6
- package/dist/lib/modules/coupon/services/helper.service.js.map +1 -1
- package/dist/lib/modules/coupon/services/patterns/repository/CouponMetricsRepository.d.ts +32 -0
- package/dist/lib/modules/coupon/services/patterns/repository/CouponMetricsRepository.d.ts.map +1 -0
- package/dist/lib/modules/coupon/services/patterns/repository/CouponMetricsRepository.js +503 -0
- package/dist/lib/modules/coupon/services/patterns/repository/CouponMetricsRepository.js.map +1 -0
- package/dist/lib/modules/coupon/services/patterns/repository/CouponRepository.d.ts.map +1 -1
- package/dist/lib/modules/coupon/services/patterns/repository/CouponRepository.js +108 -149
- package/dist/lib/modules/coupon/services/patterns/repository/CouponRepository.js.map +1 -1
- package/dist/lib/modules/coupon/services/referral-code-coupon.service.d.ts.map +1 -1
- package/dist/lib/modules/coupon/services/referral-code-coupon.service.js +1 -1
- package/dist/lib/modules/coupon/services/referral-code-coupon.service.js.map +1 -1
- package/dist/lib/modules/coupon/services/referral-reward-coupon.service.d.ts.map +1 -1
- package/dist/lib/modules/coupon/services/referral-reward-coupon.service.js +5 -1
- package/dist/lib/modules/coupon/services/referral-reward-coupon.service.js.map +1 -1
- package/dist/lib/modules/coupon/validations/coupon.validation.d.ts +407 -1
- package/dist/lib/modules/coupon/validations/coupon.validation.d.ts.map +1 -1
- package/dist/lib/modules/coupon/validations/coupon.validation.js +39 -1
- package/dist/lib/modules/coupon/validations/coupon.validation.js.map +1 -1
- package/dist/lib/modules/coupon/validations/create-coupon.validation.d.ts +1118 -0
- package/dist/lib/modules/coupon/validations/create-coupon.validation.d.ts.map +1 -0
- package/dist/lib/modules/coupon/validations/create-coupon.validation.js +13 -0
- package/dist/lib/modules/coupon/validations/create-coupon.validation.js.map +1 -0
- package/dist/lib/modules/coupon/validations/index.d.ts +1 -0
- package/dist/lib/modules/coupon/validations/index.d.ts.map +1 -1
- package/dist/lib/modules/coupon/validations/index.js +1 -0
- package/dist/lib/modules/coupon/validations/index.js.map +1 -1
- package/dist/lib/modules/deal-setting/routers/deal-setting.router.d.ts.map +1 -1
- package/dist/lib/modules/featured-setting/routers/featured-setting.router.d.ts.map +1 -1
- package/dist/lib/modules/limited-time-offer/campaign/campaign.router.d.ts +296 -0
- package/dist/lib/modules/limited-time-offer/campaign/campaign.router.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/campaign/campaign.router.js +64 -0
- package/dist/lib/modules/limited-time-offer/campaign/campaign.router.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/campaign/jobs/index.d.ts +4 -0
- package/dist/lib/modules/limited-time-offer/campaign/jobs/index.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/campaign/jobs/index.js +24 -0
- package/dist/lib/modules/limited-time-offer/campaign/jobs/index.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.producer.d.ts +12 -0
- package/dist/lib/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.producer.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.producer.js +29 -0
- package/dist/lib/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.producer.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.worker.d.ts +8 -0
- package/dist/lib/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.worker.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.worker.js +79 -0
- package/dist/lib/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.worker.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/campaign/limited-time-offer-campaign.builder.d.ts +36 -0
- package/dist/lib/modules/limited-time-offer/campaign/limited-time-offer-campaign.builder.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/campaign/limited-time-offer-campaign.builder.js +48 -0
- package/dist/lib/modules/limited-time-offer/campaign/limited-time-offer-campaign.builder.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/campaign/limited-time-offer-campaign.repository.d.ts +22 -0
- package/dist/lib/modules/limited-time-offer/campaign/limited-time-offer-campaign.repository.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/campaign/limited-time-offer-campaign.repository.js +131 -0
- package/dist/lib/modules/limited-time-offer/campaign/limited-time-offer-campaign.repository.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/campaign/limited-time-offer-campaign.validation.d.ts +851 -0
- package/dist/lib/modules/limited-time-offer/campaign/limited-time-offer-campaign.validation.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/campaign/limited-time-offer-campaign.validation.js +100 -0
- package/dist/lib/modules/limited-time-offer/campaign/limited-time-offer-campaign.validation.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.d.ts +10 -0
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.js +70 -0
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.d.ts +9 -0
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.js +42 -0
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.d.ts +43 -0
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.js +185 -0
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.builder.d.ts +8 -0
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.builder.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.builder.js +13 -0
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.builder.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.repository.d.ts +14 -0
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.repository.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.repository.js +77 -0
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.repository.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.service.d.ts +11 -0
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.service.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.service.js +87 -0
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.service.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.validation.d.ts +189 -0
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.validation.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.validation.js +24 -0
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.validation.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer.router.d.ts +122 -0
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer.router.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer.router.js +37 -0
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer.router.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/limited-time-offer.router.d.ts +601 -0
- package/dist/lib/modules/limited-time-offer/limited-time-offer.router.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/limited-time-offer.router.js +13 -0
- package/dist/lib/modules/limited-time-offer/limited-time-offer.router.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.builder.d.ts +53 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.builder.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.builder.js +55 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.builder.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.repository.d.ts +18 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.repository.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.repository.js +126 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.repository.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.router.d.ts +170 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.router.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.router.js +50 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.router.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.service.d.ts +1 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.service.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.service.js +2 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.service.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.validation.d.ts +603 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.validation.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.validation.js +85 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.validation.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant-marketing.service.d.ts +14 -0
- package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant-marketing.service.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant-marketing.service.js +73 -0
- package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant-marketing.service.js.map +1 -0
- package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.d.ts +32 -0
- package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.d.ts.map +1 -0
- package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.js +125 -0
- package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.js.map +1 -0
- package/dist/lib/modules/marketing/patterns/repository/MarketingMetricsRepository.d.ts +2 -1
- package/dist/lib/modules/marketing/patterns/repository/MarketingMetricsRepository.d.ts.map +1 -1
- package/dist/lib/modules/marketing/patterns/repository/MarketingMetricsRepository.js +23 -15
- package/dist/lib/modules/marketing/patterns/repository/MarketingMetricsRepository.js.map +1 -1
- package/dist/lib/modules/marketing/routers/marketing.router.d.ts +12 -3
- package/dist/lib/modules/marketing/routers/marketing.router.d.ts.map +1 -1
- package/dist/lib/modules/marketing/routers/marketing.router.js +7 -0
- package/dist/lib/modules/marketing/routers/marketing.router.js.map +1 -1
- package/dist/lib/modules/marketing/services/buy1-get1-marketing.service.d.ts +0 -2
- package/dist/lib/modules/marketing/services/buy1-get1-marketing.service.d.ts.map +1 -1
- package/dist/lib/modules/marketing/services/buy1-get1-marketing.service.js +20 -39
- package/dist/lib/modules/marketing/services/buy1-get1-marketing.service.js.map +1 -1
- package/dist/lib/modules/marketing/services/discount-marketing.service.d.ts +0 -3
- package/dist/lib/modules/marketing/services/discount-marketing.service.d.ts.map +1 -1
- package/dist/lib/modules/marketing/services/discount-marketing.service.js +28 -52
- package/dist/lib/modules/marketing/services/discount-marketing.service.js.map +1 -1
- package/dist/lib/modules/marketing/services/marketing.service.d.ts +2 -0
- package/dist/lib/modules/marketing/services/marketing.service.d.ts.map +1 -1
- package/dist/lib/modules/marketing/services/marketing.service.js +111 -31
- package/dist/lib/modules/marketing/services/marketing.service.js.map +1 -1
- package/dist/lib/modules/marketing/services/product-marketing.service.d.ts +20 -2
- package/dist/lib/modules/marketing/services/product-marketing.service.d.ts.map +1 -1
- package/dist/lib/modules/marketing/services/product-marketing.service.js +155 -7
- package/dist/lib/modules/marketing/services/product-marketing.service.js.map +1 -1
- package/dist/lib/modules/marketing/services/synchronize-product-marketing.service.d.ts.map +1 -1
- package/dist/lib/modules/marketing/services/synchronize-product-marketing.service.js +36 -55
- package/dist/lib/modules/marketing/services/synchronize-product-marketing.service.js.map +1 -1
- package/dist/lib/modules/marketing/transformers/buy1-get1-marketing.transformer.d.ts +3 -0
- package/dist/lib/modules/marketing/transformers/buy1-get1-marketing.transformer.d.ts.map +1 -1
- package/dist/lib/modules/marketing/transformers/discount-marketing.transformer.d.ts +3 -0
- package/dist/lib/modules/marketing/transformers/discount-marketing.transformer.d.ts.map +1 -1
- package/dist/lib/modules/marketing/transformers/product-marketing.transformer.d.ts +1 -0
- package/dist/lib/modules/marketing/transformers/product-marketing.transformer.d.ts.map +1 -1
- package/dist/lib/modules/marketing/validations/buy1-get1-marketing.validation.d.ts +30 -0
- package/dist/lib/modules/marketing/validations/buy1-get1-marketing.validation.d.ts.map +1 -1
- package/dist/lib/modules/marketing/validations/discount-marketing.validation.d.ts +45 -9
- package/dist/lib/modules/marketing/validations/discount-marketing.validation.d.ts.map +1 -1
- package/dist/lib/modules/marketing/validations/marketing.validation.d.ts +2 -2
- package/dist/lib/modules/marketing/validations/product-marketing.validation.d.ts +77 -0
- package/dist/lib/modules/marketing/validations/product-marketing.validation.d.ts.map +1 -1
- package/dist/lib/modules/marketing/validations/product-marketing.validation.js +20 -1
- package/dist/lib/modules/marketing/validations/product-marketing.validation.js.map +1 -1
- package/dist/lib/modules/punch-marketing-history/routers/punch-marketing-history.router.d.ts +2 -2
- package/dist/lib/modules/punch-marketing-history/routers/punch-marketing-history.router.d.ts.map +1 -1
- package/dist/lib/modules/punch-marketing-history/validations/punch-marketing-history.validation.d.ts +4 -4
- package/dist/types/event/event-initializations.d.ts.map +1 -1
- package/dist/types/event/event-listeners/event-listeners.d.ts +1 -0
- package/dist/types/event/event-listeners/event-listeners.d.ts.map +1 -1
- package/dist/types/event/events/marketing-product-seed.event.d.ts +17 -0
- package/dist/types/event/events/marketing-product-seed.event.d.ts.map +1 -0
- package/dist/types/index.d.ts +730 -5
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/modules/coupon/routers/coupon.router.d.ts +116 -0
- package/dist/types/modules/coupon/routers/coupon.router.d.ts.map +1 -1
- package/dist/types/modules/coupon/services/coupon.service.d.ts +1 -0
- package/dist/types/modules/coupon/services/coupon.service.d.ts.map +1 -1
- package/dist/types/modules/coupon/services/helper.service.d.ts.map +1 -1
- package/dist/types/modules/coupon/services/patterns/repository/CouponMetricsRepository.d.ts +32 -0
- package/dist/types/modules/coupon/services/patterns/repository/CouponMetricsRepository.d.ts.map +1 -0
- package/dist/types/modules/coupon/services/patterns/repository/CouponRepository.d.ts.map +1 -1
- package/dist/types/modules/coupon/services/referral-code-coupon.service.d.ts.map +1 -1
- package/dist/types/modules/coupon/services/referral-reward-coupon.service.d.ts.map +1 -1
- package/dist/types/modules/coupon/validations/coupon.validation.d.ts +407 -1
- package/dist/types/modules/coupon/validations/coupon.validation.d.ts.map +1 -1
- package/dist/types/modules/coupon/validations/create-coupon.validation.d.ts +1118 -0
- package/dist/types/modules/coupon/validations/create-coupon.validation.d.ts.map +1 -0
- package/dist/types/modules/coupon/validations/index.d.ts +1 -0
- package/dist/types/modules/coupon/validations/index.d.ts.map +1 -1
- package/dist/types/modules/deal-setting/routers/deal-setting.router.d.ts.map +1 -1
- package/dist/types/modules/featured-setting/routers/featured-setting.router.d.ts.map +1 -1
- package/dist/types/modules/limited-time-offer/campaign/campaign.router.d.ts +296 -0
- package/dist/types/modules/limited-time-offer/campaign/campaign.router.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/campaign/jobs/index.d.ts +4 -0
- package/dist/types/modules/limited-time-offer/campaign/jobs/index.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.producer.d.ts +12 -0
- package/dist/types/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.producer.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.worker.d.ts +8 -0
- package/dist/types/modules/limited-time-offer/campaign/jobs/limited-time-offer-campaign.worker.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/campaign/limited-time-offer-campaign.builder.d.ts +36 -0
- package/dist/types/modules/limited-time-offer/campaign/limited-time-offer-campaign.builder.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/campaign/limited-time-offer-campaign.repository.d.ts +22 -0
- package/dist/types/modules/limited-time-offer/campaign/limited-time-offer-campaign.repository.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/campaign/limited-time-offer-campaign.validation.d.ts +851 -0
- package/dist/types/modules/limited-time-offer/campaign/limited-time-offer-campaign.validation.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.d.ts +10 -0
- package/dist/types/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.d.ts +9 -0
- package/dist/types/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.d.ts +43 -0
- package/dist/types/modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/config/limited-time-offer-config.builder.d.ts +8 -0
- package/dist/types/modules/limited-time-offer/config/limited-time-offer-config.builder.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/config/limited-time-offer-config.repository.d.ts +14 -0
- package/dist/types/modules/limited-time-offer/config/limited-time-offer-config.repository.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/config/limited-time-offer-config.service.d.ts +11 -0
- package/dist/types/modules/limited-time-offer/config/limited-time-offer-config.service.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/config/limited-time-offer-config.validation.d.ts +189 -0
- package/dist/types/modules/limited-time-offer/config/limited-time-offer-config.validation.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/config/limited-time-offer.router.d.ts +122 -0
- package/dist/types/modules/limited-time-offer/config/limited-time-offer.router.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/limited-time-offer.router.d.ts +601 -0
- package/dist/types/modules/limited-time-offer/limited-time-offer.router.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.builder.d.ts +53 -0
- package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.builder.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.repository.d.ts +18 -0
- package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.repository.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.router.d.ts +170 -0
- package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.router.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.service.d.ts +1 -0
- package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.service.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.validation.d.ts +603 -0
- package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.validation.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/participant/services/limited-time-offer-participant-marketing.service.d.ts +14 -0
- package/dist/types/modules/limited-time-offer/participant/services/limited-time-offer-participant-marketing.service.d.ts.map +1 -0
- package/dist/types/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.d.ts +32 -0
- package/dist/types/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.d.ts.map +1 -0
- package/dist/types/modules/marketing/patterns/repository/MarketingMetricsRepository.d.ts +2 -1
- package/dist/types/modules/marketing/patterns/repository/MarketingMetricsRepository.d.ts.map +1 -1
- package/dist/types/modules/marketing/routers/marketing.router.d.ts +12 -3
- package/dist/types/modules/marketing/routers/marketing.router.d.ts.map +1 -1
- package/dist/types/modules/marketing/services/buy1-get1-marketing.service.d.ts +0 -2
- package/dist/types/modules/marketing/services/buy1-get1-marketing.service.d.ts.map +1 -1
- package/dist/types/modules/marketing/services/discount-marketing.service.d.ts +0 -3
- package/dist/types/modules/marketing/services/discount-marketing.service.d.ts.map +1 -1
- package/dist/types/modules/marketing/services/marketing.service.d.ts +2 -0
- package/dist/types/modules/marketing/services/marketing.service.d.ts.map +1 -1
- package/dist/types/modules/marketing/services/product-marketing.service.d.ts +24 -2
- package/dist/types/modules/marketing/services/product-marketing.service.d.ts.map +1 -1
- package/dist/types/modules/marketing/services/synchronize-product-marketing.service.d.ts.map +1 -1
- package/dist/types/modules/marketing/transformers/buy1-get1-marketing.transformer.d.ts +3 -0
- package/dist/types/modules/marketing/transformers/buy1-get1-marketing.transformer.d.ts.map +1 -1
- package/dist/types/modules/marketing/transformers/discount-marketing.transformer.d.ts +3 -0
- package/dist/types/modules/marketing/transformers/discount-marketing.transformer.d.ts.map +1 -1
- package/dist/types/modules/marketing/transformers/product-marketing.transformer.d.ts +1 -0
- package/dist/types/modules/marketing/transformers/product-marketing.transformer.d.ts.map +1 -1
- package/dist/types/modules/marketing/validations/buy1-get1-marketing.validation.d.ts +30 -0
- package/dist/types/modules/marketing/validations/buy1-get1-marketing.validation.d.ts.map +1 -1
- package/dist/types/modules/marketing/validations/discount-marketing.validation.d.ts +45 -9
- package/dist/types/modules/marketing/validations/discount-marketing.validation.d.ts.map +1 -1
- package/dist/types/modules/marketing/validations/marketing.validation.d.ts +2 -2
- package/dist/types/modules/marketing/validations/product-marketing.validation.d.ts +77 -0
- package/dist/types/modules/marketing/validations/product-marketing.validation.d.ts.map +1 -1
- package/dist/types/modules/punch-marketing-history/routers/punch-marketing-history.router.d.ts +2 -2
- package/dist/types/modules/punch-marketing-history/routers/punch-marketing-history.router.d.ts.map +1 -1
- package/dist/types/modules/punch-marketing-history/validations/punch-marketing-history.validation.d.ts +4 -4
- package/package.json +3 -3
- package/dist/lib/events/event-initializations.d.ts +0 -2
- package/dist/lib/events/event-initializations.d.ts.map +0 -1
- package/dist/lib/events/event-initializations.js +0 -5
- package/dist/lib/events/event-initializations.js.map +0 -1
- package/dist/types/events/event-initializations.d.ts +0 -2
- package/dist/types/events/event-initializations.d.ts.map +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"coupon.service.js","sourceRoot":"/","sources":["modules/coupon/services/coupon.service.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,iDAA4C;AAC5C,yCAAyC;AACzC,oDAA4F;AAC5F,sEAqBmD;AAenD,wEAIiD;AAEjD,wBAOW;AACX,4DAQ2C;AAC3C,sEAAwF;AACxF,wEAGmD;AACnD,wCAA6C;AAE7C,6EAA0E;AAC1E,4EAMmD;AACnD,uFAAiF;AACjF,qDAA4E;AAC5E,8DAAkE;AAClE,oEAAwE;AACxE,gEAA6E;AAC7E,gHAAkH;AAG3G,IAAM,aAAa,GAAnB,MAAM,aAAa;IACjB,KAAK,CAA8C;IACnD,eAAe,CAAuD;IACtE,SAAS,CAA2C;IACpD,UAAU,CAA2D;IACrE,SAAS,CAA2C;IACpD,mBAAmB,CAA2E;IAC9F,mBAAmB,CAA+B;IAClD,cAAc,GAA+C,IAAI,CAAC;IAClE,YAAY,CAAsB;IACzB,qBAAqB,CAAiE;IAEvG;QACC,IAAI,CAAC,KAAK,GAAG,oBAA0D,CAAC;QACxE,IAAI,CAAC,eAAe,GAAG,wBAAuE,CAAC;QAC/F,IAAI,CAAC,SAAS,GAAG,kBAAqD,CAAC;QACvE,IAAI,CAAC,UAAU,GAAG,0BAA6E,CAAC;QAChG,IAAI,CAAC,SAAS,GAAG,kBAAqD,CAAC;QACvE,IAAI,CAAC,mBAAmB,GAAG,kCACW,CAAC;QACvC,IAAI,CAAC,mBAAmB,GAAG,uCAA4B,CAAC;QACxD,IAAI,CAAC,YAAY,GAAG,oCAAmB,CAAC;QACxC,IAAI,CAAC,qBAAqB,GAAG,6BACI,CAAC;IACnC,CAAC;IAED,IAAY,aAAa;QACxB,IAAI,CAAC,IAAI,CAAC,cAAc,EAAE,CAAC;YAC1B,IAAI,CAAC,cAAc,GAAG,IAAA,yBAAgB,GAAE,CAAC;QAC1C,CAAC;QACD,OAAO,IAAI,CAAC,cAAc,CAAC;IAC5B,CAAC;IAMM,KAAK,CAAC,MAAM,CAAC,IAA6B;QAChD,IAAI,MAA2B,CAAC;QAEhC,IACC,IAAI,CAAC,UAAU,IAAI,iBAAU,CAAC,aAAa;YAC3C,IAAI,EAAE,QAAQ;YACd,CAAC,IAAI,CAAC,YAAY,CAAC,eAAe,CAAC,IAAA,aAAK,EAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,EAAE,IAAA,aAAK,EAAC,IAAI,EAAE,QAAQ,EAAE,GAAG,CAAC,CAAC,EAC3F,CAAC;YACF,IAAA,4BAAa,EAAC,wCAAwC,CAAC,CAAC;QACzD,CAAC;QAED,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;YAC5C,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,SAAS,EAAE,IAAI;SACf,CAAC,CAAC;QAEH,IAAI,WAAW;YAAE,IAAA,4BAAa,EAAC,4BAA4B,CAAC,CAAC;QAE7D,QAAQ,IAAI,CAAC,UAAU,EAAE,CAAC;YACzB,KAAK,iBAAU,CAAC,MAAM,CAAC,CAAC,CAAC;gBACxB,MAAM,GAAG,MAAM,sBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAChD,IAAI,MAAM,EAAE,CAAC;oBACZ,MAAM,YAAY,GAAG,MAAoC,CAAC;oBAC1D,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE,CAAC;wBAClC,MAAM,IAAI,CAAC,0BAA0B,CAAC,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;oBACvD,CAAC;yBAAM,CAAC;wBACP,MAAM,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBAC/C,CAAC;gBACF,CAAC;gBACD,MAAM;YACP,CAAC;YAED,KAAK,iBAAU,CAAC,aAAa,CAAC,CAAC,CAAC;gBAC/B,MAAM,GAAG,MAAM,4BAAyB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACtD,MAAM;YACP,CAAC;YAED,KAAK,iBAAU,CAAC,eAAe,CAAC,CAAC,CAAC;gBACjC,MAAM,GAAG,MAAM,8BAA2B,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACxD,MAAM;YACP,CAAC;YAED,KAAK,iBAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC;gBAClC,MAAM,GAAG,MAAM,8DAA4B,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACzD,IAAI,MAAM,EAAE,CAAC;oBACZ,MAAM,qBAAqB,GAAG,MAA6C,CAAC;oBAC5E,IAAI,CAAC,qBAAqB,CAAC,cAAc,EAAE,CAAC;wBAC3C,MAAM,IAAI,CAAC,0BAA0B,CAAC,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;oBACvD,CAAC;yBAAM,CAAC;wBACP,MAAM,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBAC/C,CAAC;gBACF,CAAC;gBACD,MAAM;YACP,CAAC;YAED,KAAK,iBAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC;gBAClC,MAAM,GAAG,MAAM,+BAA4B,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACzD,IAAI,MAAM,EAAE,CAAC;oBACZ,MAAM,qBAAqB,GAAG,MAA6C,CAAC;oBAC5E,IAAI,CAAC,qBAAqB,CAAC,cAAc,EAAE,CAAC;wBAC3C,MAAM,IAAI,CAAC,0BAA0B,CAAC,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;oBACvD,CAAC;yBAAM,CAAC;wBACP,MAAM,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;oBAC/C,CAAC;gBACF,CAAC;gBACD,MAAM;YACP,CAAC;YAED,KAAK,iBAAU,CAAC,eAAe,CAAC,CAAC,CAAC;gBACjC,MAAM,GAAG,MAAM,8BAA2B,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACxD,IAAI,MAAM,EAAE,CAAC;oBACZ,MAAM,oBAAoB,GAAG,MAA4C,CAAC;oBAC1E,MAAM,KAAK,GAAG,oBAAoB,CAAC,KAAK,CAAC;oBACzC,MAAM,IAAI,CAAC,0BAA0B,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,KAAK,EAAE,EAAE,EAAE,MAAM,CAAC,GAAG,CAAC,CAAC;gBAC5E,CAAC;gBACD,MAAM;YACP,CAAC;YAED,KAAK,iBAAU,CAAC,aAAa,CAAC,CAAC,CAAC;gBAC/B,MAAM,GAAG,MAAM,sBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAChD,MAAM;YACP,CAAC;YAED,OAAO,CAAC,CAAC,CAAC;gBACT,IAAA,8BAAe,EAAC,0BAA0B,CAAC,CAAC;YAC7C,CAAC;QACF,CAAC;QAED,IAAI,CAAC,MAAM;YAAE,IAAA,kCAAmB,EAAC,yBAAyB,CAAC,CAAC;QAG5D,MAAM,UAAU,GAAG,IAAA,mBAAY,GAAE,CAAC,yBAAyB,EAAE,CAAC;QAC9D,MAAM,kBAAkB,GACvB,MAAM,UAAU,CAAC,eAAe,CAAiC,cAAc,CAAC,CAAC;QAElF,MAAM,kBAAkB,CAAC,kBAAkB,CAAC,6BAA6B,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAE7F,OAAO,MAAM,CAAC;IACf,CAAC;IAMM,KAAK,CAAC,QAAQ,CAAC,EAAoC;QACzD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK;aAC7B,OAAO,CAAC;YACR,GAAG,EAAE,EAAE;YACP,SAAS,EAAE,IAAI;SACf,CAAC;aACD,QAAQ,CAAC;YACT;gBACC,IAAI,EAAE,kBAAkB;aACxB;SACD,CAAC,CAAC;QACJ,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,MAAM,IAAI,kBAAS,CAAC;gBACnB,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,kBAAkB;aAC3B,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC;IAMM,KAAK,CAAC,IAAI,CAAC,IAAyB;QAC1C,IAAI,CAAC;YACJ,MAAM,QAAQ,GAAG;gBAChB,GAAG,IAAI,EAAE,QAAQ;gBACjB;oBACC,IAAI,EAAE,OAAO;oBACb,QAAQ,EAAE;wBACT;4BACC,IAAI,EAAE,UAAU;4BAChB,KAAK,EAAE,IAAI,CAAC,aAAa;4BACzB,MAAM,EAAE,wBAAwB;yBAChC;qBACD;oBACD,MAAM,EAAE,sBAAsB;iBAC9B;gBACD;oBACC,IAAI,EAAE,YAAY;oBAClB,QAAQ,EAAE;wBACT;4BACC,IAAI,EAAE,UAAU;4BAChB,KAAK,EAAE,IAAI,CAAC,aAAa;4BACzB,MAAM,EAAE,wBAAwB;yBAChC;qBACD;oBACD,MAAM,EAAE,sBAAsB;iBAC9B;gBACD;oBACC,IAAI,EAAE,cAAc;oBACpB,QAAQ,EAAE;wBACT;4BACC,IAAI,EAAE,UAAU;4BAChB,KAAK,EAAE,IAAI,CAAC,aAAa;4BACzB,MAAM,EAAE,wBAAwB;yBAChC;qBACD;oBACD,MAAM,EAAE,sBAAsB;iBAC9B;gBACD;oBACC,IAAI,EAAE,MAAM;oBACZ,QAAQ,EAAE;wBACT;4BACC,IAAI,EAAE,UAAU;4BAChB,KAAK,EAAE,IAAI,CAAC,aAAa;4BACzB,MAAM,EAAE,wBAAwB;yBAChC;qBACD;oBACD,MAAM,EAAE,sBAAsB;iBAC9B;gBACD;oBACC,IAAI,EAAE,oBAAoB;oBAC1B,QAAQ,EAAE;wBACT;4BACC,IAAI,EAAE,UAAU;4BAChB,KAAK,EAAE,IAAI,CAAC,aAAa;4BACzB,MAAM,EAAE,wBAAwB;yBAChC;qBACD;oBACD,MAAM,EAAE,sBAAsB;iBAC9B;aACD,CAAC;YAEF,MAAM,QAAQ,GAAG,IAAA,6CAAgC,EAAC,IAAI,CAAC,KAA2C,CAAC,CAAC;YACpG,MAAM,OAAO,GAAmC;gBAC/C,IAAI,EAAE,IAAI,EAAE,IAAI;gBAChB,IAAI,EAAE,IAAI,EAAE,IAAI;gBAChB,IAAI,EAAE,IAAI,EAAE,IAAI;gBAChB,KAAK,EAAE,EAAE,GAAG,IAAI,EAAE,KAAK,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;gBAC7D,MAAM,EAAE,IAAI,EAAE,MAAM;gBACpB,QAAQ,EAAE,QAAQ;aAClB,CAAC;YACF,MAAM,eAAe,GAAG,MAAM,QAAQ,CAAC,OAAO,CAAC,CAAC;YAChD,OAAO,eAAe,CAAC;QACxB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,kBAAS,CAAC;gBACnB,IAAI,EAAE,uBAAuB;gBAC7B,OAAO,EAAE,QAAQ,GAAG,EAAE;aACtB,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IAOM,KAAK,CAAC,MAAM,CAAC,EAAU,EAAE,IAA6B;QAC5D,IAAI,MAAuC,CAAC;QAE5C,MAAM,CAAC,SAAS,EAAE,eAAe,EAAE,kBAAkB,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;YAC1E,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;gBAClB,IAAI,EAAE,IAAI,CAAC,IAAI;gBACf,GAAG,EAAE,EAAE,GAAG,EAAE,EAAE,EAAE;gBAChB,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;aAClC,CAAC;YACF,IAAI,CAAC,SAAS;iBACZ,IAAI,CAAC;gBACL,OAAO,EAAE,IAAI,oBAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,CAAC;aACxC,CAAC;iBACD,MAAM,CAAC,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;SAC5B,CAAC,CAAC;QAEH,IAAI,CAAC,SAAS,EAAE,CAAC;YAChB,MAAM,IAAI,kBAAS,CAAC;gBACnB,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,kBAAkB;aAC3B,CAAC,CAAC;QACJ,CAAC;QAED,IACC,IAAI,CAAC,UAAU,IAAI,iBAAU,CAAC,aAAa;YAC3C,SAAS,EAAE,QAAQ;YACnB,IAAA,aAAK,EAAC,SAAS,EAAE,QAAQ,EAAE,KAAK,CAAC,GAAG,IAAA,aAAK,EAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,EAC9D,CAAC;YACF,MAAM,IAAI,kBAAS,CAAC;gBACnB,IAAI,EAAE,aAAa;gBACnB,OAAO,EAAE,sFAAsF;aAC/F,CAAC,CAAC;QACJ,CAAC;QAED,IACC,IAAI,CAAC,UAAU,IAAI,iBAAU,CAAC,aAAa;YAC3C,IAAI,EAAE,QAAQ;YACd,IAAA,aAAK,EAAC,IAAI,EAAE,QAAQ,EAAE,KAAK,CAAC,GAAG,IAAA,aAAK,EAAC,IAAI,EAAE,QAAQ,CAAC,GAAG,CAAC,EACvD,CAAC;YACF,MAAM,IAAI,kBAAS,CAAC;gBACnB,IAAI,EAAE,aAAa;gBACnB,OAAO,EAAE,6CAA6C;aACtD,CAAC,CAAC;QACJ,CAAC;QAED,IAAI,eAAe,EAAE,CAAC;YACrB,MAAM,IAAI,kBAAS,CAAC;gBACnB,IAAI,EAAE,UAAU;gBAChB,OAAO,EAAE,4BAA4B;aACrC,CAAC,CAAC;QACJ,CAAC;QAED,QAAQ,IAAI,CAAC,UAAU,EAAE,CAAC;YACzB,KAAK,iBAAU,CAAC,MAAM,CAAC,CAAC,CAAC;gBACxB,MAAM,GAAG,MAAM,sBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAChD,IAAI,MAAM,EAAE,CAAC;oBACZ,MAAM,YAAY,GAAG,MAAoC,CAAC;oBAC1D,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE,CAAC;wBAClC,MAAM,IAAI,CAAC,6BAA6B,CACvC,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,kBAAkB,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,EACrD,SAAS,CAAC,GAAG,EACb,MAAM,CAAC,GAAG,CACV,CAAC;oBACH,CAAC;gBACF,CAAC;gBACD,MAAM;YACP,CAAC;YACD,KAAK,iBAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC;gBAClC,MAAM,GAAG,MAAM,8DAA4B,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACzD,IAAI,MAAM,EAAE,CAAC;oBACZ,MAAM,qBAAqB,GAAG,MAA6C,CAAC;oBAC5E,IAAI,CAAC,qBAAqB,CAAC,cAAc,EAAE,CAAC;wBAC3C,MAAM,IAAI,CAAC,6BAA6B,CACvC,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,kBAAkB,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,EACrD,SAAS,CAAC,GAAG,EACb,qBAAqB,CAAC,GAAG,CACzB,CAAC;oBACH,CAAC;gBACF,CAAC;gBACD,MAAM;YACP,CAAC;YACD,KAAK,iBAAU,CAAC,gBAAgB,CAAC,CAAC,CAAC;gBAClC,MAAM,GAAG,MAAM,+BAA4B,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACzD,IAAI,MAAM,EAAE,CAAC;oBACZ,MAAM,qBAAqB,GAAG,MAA6C,CAAC;oBAC5E,IAAI,CAAC,qBAAqB,CAAC,cAAc,EAAE,CAAC;wBAC3C,MAAM,IAAI,CAAC,6BAA6B,CACvC,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,kBAAkB,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,EACrD,SAAS,CAAC,GAAG,EACb,qBAAqB,CAAC,GAAG,CACzB,CAAC;oBACH,CAAC;gBACF,CAAC;gBACD,MAAM;YACP,CAAC;YACD,KAAK,iBAAU,CAAC,eAAe,CAAC,CAAC,CAAC;gBACjC,MAAM,GAAG,MAAM,8BAA2B,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBACxD,IAAI,MAAM,EAAE,CAAC;oBACZ,MAAM,oBAAoB,GAAG,MAA4C,CAAC;oBAC1E,MAAM,IAAI,CAAC,4BAA4B,CACtC,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,kBAAkB,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,EACrD,SAAS,CAAC,GAAG,CACb,CAAC;oBACF,MAAM,IAAI,CAAC,0BAA0B,CACpC,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,oBAAoB,CAAC,KAAK,EAAE,EAAE,EAC5C,oBAAoB,CAAC,GAAG,CACxB,CAAC;gBACH,CAAC;gBACD,MAAM;YACP,CAAC;YACD,KAAK,iBAAU,CAAC,aAAa,CAAC,CAAC,CAAC;gBAC/B,MAAM,GAAG,MAAM,sBAAmB,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;gBAChD,IAAI,MAAM,EAAE,CAAC;oBACZ,MAAM,YAAY,GAAG,MAAoC,CAAC;oBAC1D,IAAI,CAAC,YAAY,CAAC,cAAc,EAAE,CAAC;wBAClC,MAAM,IAAI,CAAC,6BAA6B,CACvC,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,kBAAkB,EAAE,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,EACrD,SAAS,CAAC,GAAG,EACb,MAAM,CAAC,GAAG,CACV,CAAC;oBACH,CAAC;gBACF,CAAC;gBAED,MAAM;YACP,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;gBACT,MAAM,IAAI,kBAAS,CAAC;oBACnB,IAAI,EAAE,aAAa;oBACnB,OAAO,EAAE,qBAAqB;iBAC9B,CAAC,CAAC;YACJ,CAAC;QACF,CAAC;QAED,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,MAAM,IAAI,kBAAS,CAAC;gBACnB,IAAI,EAAE,aAAa;gBACnB,OAAO,EAAE,6BAA6B;aACtC,CAAC,CAAC;QACJ,CAAC;QAGD,MAAM,gBAAgB,GAAG,SAAS,EAAE,gBAAgB,IAAI,EAAE,CAAC;QAC3D,gBAAgB,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;QAErC,MAAM,aAAa,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,iBAAiB,CACjE,MAAM,CAAC,GAAG,EACV;YACC,IAAI,EAAE;gBACL,gBAAgB;aAChB;SACD,EACD;YACC,GAAG,EAAE,IAAI;YACT,aAAa,EAAE,IAAI;SACnB,CACD,CAAC;QAEF,IAAI,CAAC,aAAa,EAAE,CAAC;YACpB,MAAM,IAAI,kBAAS,CAAC;gBACnB,IAAI,EAAE,uBAAuB;gBAC7B,OAAO,EAAE,2CAA2C;aACpD,CAAC,CAAC;QACJ,CAAC;QAED,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,iBAAiB,CACpE,SAAS,CAAC,GAAG,EACb;YACC,IAAI,EAAE;gBACL,cAAc,EAAE,MAAM,CAAC,GAAG;gBAC1B,cAAc,EAAE,MAAM,CAAC,QAAQ,CAAC,GAAG;aACnC;SACD,EACD;YACC,GAAG,EAAE,IAAI;YACT,aAAa,EAAE,IAAI;SACnB,CACD,CAAC;QAEF,OAAO,aAAa,CAAC;IACtB,CAAC;IAEM,KAAK,CAAC,YAAY,CAAC,EAAU,EAAE,MAAc;QACnD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,iBAAiB,CAC1D,EAAE,EACF;YACC,IAAI,EAAE,EAAE,MAAM,EAAE;SAChB,EACD;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;QAGD,MAAM,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,CAAC;QACjD,IAAI,gBAAgB,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrD,MAAM,IAAI,CAAC,eAAe,CAAC,UAAU,CACpC,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,gBAAgB,EAAE,EAAE,EAClC;gBACC,IAAI,EAAE,EAAE,MAAM,EAAE;aAChB,CACD,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAC;IACf,CAAC;IAMM,KAAK,CAAC,UAAU,CAAC,IAAe;QACtC,MAAM,EAAE,GAAG,EAAE,UAAU,EAAE,GAAG,IAAI,CAAC;QAEjC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;QAE9C,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,IAAA,4BAAa,EAAC,kBAAkB,CAAC,CAAC;QACnC,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,UAAU,CAAC,CAAC;QACnF,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,MAAM,IAAI,kBAAS,CAAC;gBACnB,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,kBAAkB;aAC3B,CAAC,CAAC;QACJ,CAAC;QAGD,IAAI,CAAC,4BAA4B,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;QAG3C,MAAM,gBAAgB,GAAG,MAAM,CAAC,gBAAgB,CAAC;QACjD,IAAI,gBAAgB,IAAI,gBAAgB,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACrD,MAAM,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,gBAAgB,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,UAAU,CAAC,CAAC;QAChG,CAAC;QAED,OAAO,6BAA6B,CAAC;IACtC,CAAC;IAMM,KAAK,CAAC,cAAc,CAC1B,IAAyC,EACzC,IAAyC,EACzC,OAAe,CAAC,EAChB,OAAe,CAAC;QAMhB,MAAM,gBAAgB,GAAG,IAAI,mCAAgB,EAAE,CAAC;QAChD,IAAI,QAAQ,GAAyB,SAAS,CAAC;QAC/C,IAAI,IAAI,EAAE,CAAC;YACV,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC;YACpF,QAAQ,GAAG,YAAY,EAAE,QAAQ,CAAC;QACnC,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,gBAAgB,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,QAAQ,CAAC,CAAC;QAE5E,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;YAClB,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,mBAAmB,CAAC,cAAc,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YACxE,IAAI,KAAK,EAAE,CAAC;gBACX,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YAC/B,CAAC;QACF,CAAC;QAED,OAAO,gBAAgB,CAAC,qBAAqB,CAAC,OAAO,CAAC,CAAC;IACxD,CAAC;IAEM,KAAK,CAAC,cAAc,CAAC,IAAuB;QAClD,IAAI,IAAI,CAAC,MAAM,KAAK,OAAO,EAAE,CAAC;YAC7B,OAAO,MAAM,uCAA4B,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAClE,CAAC;QAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACtD,IAAI,CAAC,IAAI;YAAE,IAAA,4BAAa,EAAC,gBAAgB,CAAC,CAAC;QAE3C,IAAI,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;YACrC,IAAI,EAAE,IAAI,CAAC,MAAM;YACjB,GAAG,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE,EAAE;YAChC,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,aAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE;SACtC,CAAC,CAAC;QAEH,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC;gBACjC,IAAI,EAAE,IAAI,CAAC,MAAM;gBACjB,MAAM,EAAE,EAAE,GAAG,EAAE,CAAC,aAAM,CAAC,MAAM,EAAE,IAAI,CAAC,EAAE;gBACtC,UAAU,EAAE,EAAE,GAAG,EAAE,CAAC,iBAAU,CAAC,aAAa,EAAE,iBAAU,CAAC,aAAa,CAAC,EAAE;gBACzE,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;aAClC,CAAC,CAAC;YAEH,IAAI,CAAC,MAAM,EAAE,CAAC;gBACb,IAAA,4BAAa,EAAC,kBAAkB,CAAC,CAAC;YACnC,CAAC;YAGD,IAAI,CAAC,SAAS,CAAC,iBAAiB,CAAC,IAAI,CAAC,GAAG,EAAE;gBAC1C,SAAS,EAAE,EAAE,OAAO,EAAE,MAAM,CAAC,GAAG,EAAE;aAClC,CAAC,CAAC;QACJ,CAAC;QAED,IAAI,MAAM,CAAC,UAAU,IAAI,iBAAU,CAAC,aAAa,EAAE,CAAC;YACnD,OAAO,MAAM,4BAAyB,CAAC,cAAc,CAAC,IAAI,EAAE,MAA0C,CAAC,CAAC;QACzG,CAAC;QAED,MAAM,UAAU,GAAG,MAAkC,CAAC;QAEtD,MAAM,EAAE,OAAO,EAAE,cAAc,EAAE,GAAG,MAAM,IAAI,CAAC,kBAAkB,CAChE,UAAU,EACV,IAAI,CAAC,GAAG,EACR,IAAI,CAAC,kBAAkB,EACvB,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,IAAA,aAAK,EAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAC/D,CAAC;QAEF,IAAI,CAAC,OAAO,EAAE,CAAC;YACd,OAAO;gBACN,OAAO;gBACP,OAAO,EAAE,cAAc;aACvB,CAAC;QACH,CAAC;QAED,QAAQ,MAAM,CAAC,UAAU,EAAE,CAAC;YAC3B,KAAK,iBAAU,CAAC,eAAe;gBAC9B,OAAO,MAAM,8BAA2B,CAAC,cAAc,CACtD,IAAI,EACJ,MAA4C,CAC5C,CAAC;YACH,KAAK,iBAAU,CAAC,MAAM;gBACrB,OAAO,MAAM,sBAAmB,CAAC,cAAc,CAAC,IAAI,EAAE,MAAoC,CAAC,CAAC;YAC7F,KAAK,iBAAU,CAAC,gBAAgB;gBAC/B,OAAO,MAAM,8DAA4B,CAAC,cAAc,CACvD,IAAI,EACJ,MAA6C,CAC7C,CAAC;YACH,KAAK,iBAAU,CAAC,gBAAgB;gBAC/B,OAAO,MAAM,+BAA4B,CAAC,cAAc,CACvD,IAAI,EACJ,MAA6C,CAC7C,CAAC;YACH,KAAK,iBAAU,CAAC,eAAe;gBAC9B,OAAO,MAAM,8BAA2B,CAAC,cAAc,CACtD,IAAI,EACJ,MAA4C,CAC5C,CAAC;YACH,KAAK,iBAAU,CAAC,aAAa;gBAC5B,OAAO,MAAM,sBAAmB,CAAC,cAAc,CAAC,IAAI,EAAE,MAAoC,CAAC,CAAC;YAC7F;gBACC,IAAA,kCAAmB,EAAC,kCAAkC,MAAM,CAAC,UAAU,UAAU,CAAC,CAAC;QACrF,CAAC;IACF,CAAC;IAEO,eAAe,CAAC,MAAgC;QACvD,IAAI,MAAM,CAAC,gBAAgB,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,IAAI,IAAI,IAAI,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,CAAC,GAAG,IAAI,IAAI,EAAE,CAAC,EAAE,CAAC;YACxG,OAAO,IAAI,CAAC;QACb,CAAC;QACD,OAAO,KAAK,CAAC;IACd,CAAC;IASO,KAAK,CAAC,kBAAkB,CAC/B,MAAgC,EAChC,IAA6B,EAC7B,WAAmB,EACnB,cAAiC,SAAS;QAE1C,MAAM,iBAAiB,GAAG;YACzB,IAAI,CAAC,eAAe,CAAC,MAAM,CAAC;YAC5B,MAAM,CAAC,QAAQ,CAAC,KAAK,GAAG,IAAA,aAAK,GAAE,CAAC,MAAM,EAAE;YACxC,MAAM,CAAC,sBAAsB,IAAI,MAAM,CAAC,aAAa,IAAI,WAAW,GAAG,MAAM,CAAC,aAAa;YAC3F,MAAM,CAAC,cAAc,IAAI,CAAC,CAAC,MAAM,IAAI,CAAC,uBAAuB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;YAC5E,MAAM,CAAC,0BAA0B;gBAChC,MAAM,CAAC,iBAAiB;gBACxB,CAAC,MAAM,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,IAAI,MAAM,CAAC,iBAAiB;YACnF,WAAW,IAAI,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,IAAA,aAAK,EAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,QAAQ,CAAC,WAAW,CAAC;SAC/F,CAAC;QAEF,MAAM,eAAe,GAAG;YACvB,wBAAwB;YACxB,kCAAkC;YAClC,qDAAqD;YACrD,mCAAmC;YACnC,kDAAkD;YAClD,oDAAoD;SACpD,CAAC;QAEF,MAAM,OAAO,GAAG,iBAAiB,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,CAAC;QAC1E,MAAM,cAAc,GAAG,eAAe,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC,iBAAiB,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;QAE3F,OAAO,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC;IACpC,CAAC;IAGO,KAAK,CAAC,uBAAuB,CACpC,MAAgC,EAChC,IAA6B;QAE7B,MAAM,cAAc,GAAG,MAAM,CAAC,cAAc,CAAC;QAC7C,MAAM,0BAA0B,GAAG,MAAM,CAAC,0BAA0B,CAAC;QACrE,MAAM,iBAAiB,GAAG,MAAM,CAAC,iBAAiB,CAAC;QAEnD,IAAI,cAAc,EAAE,CAAC;YACpB,IAAI,0BAA0B,IAAI,iBAAiB,EAAE,CAAC;gBACrD,MAAM,UAAU,GAAG,MAAM,oCAAmB,CAAC,6BAA6B,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;gBACzF,OAAO,iBAAiB,GAAG,UAAU,CAAC;YACvC,CAAC;YACD,OAAO,MAAM,oCAAmB,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;QAClD,CAAC;QAED,OAAO,IAAI,CAAC;IACb,CAAC;IAEO,KAAK,CAAC,sBAAsB,CAAC,IAA6B,EAAE,UAAkB;QACrF,MAAM,MAAM,GAAG,CAAC,MAAM,IAAI,CAAC,UAAU;aACnC,IAAI,CAAC;YACL,IAAI,EAAE,IAAI;YACV,MAAM,EAAE,EAAE,GAAG,EAAE,yBAAkB,CAAC,SAAS,EAAE;YAC7C,SAAS,EAAE,gBAAS,CAAC,OAAO;SAC5B,CAAC;aACD,QAAQ,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC,CAAqE,CAAC;QAEpG,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,UAAU,IAAI,UAAU,CAAC,CAAC,MAAM,CAAC;QAEjF,OAAO,KAAK,CAAC;IACd,CAAC;IAEM,KAAK,CAAC,kBAAkB,CAAC,QAAiC;QAChE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACnD,IAAI,CAAC,MAAM,IAAI,MAAM,CAAC,UAAU,IAAI,iBAAU,CAAC,aAAa,EAAE,CAAC;YAC9D,OAAO;QACR,CAAC;QAED,MAAM,WAAW,GAAG,MAAkC,CAAC;QACvD,MAAM,IAAI,CAAC,sBAAsB,CAAC,WAAW,CAAC,CAAC;IAChD,CAAC;IAEO,KAAK,CAAC,sBAAsB,CAAC,MAAgC;QACpE,IAAI,gBAAgB,GAAkB,IAAI,CAAC;QAE3C,IAAI,MAAM,CAAC,wBAAwB,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;YAK/D,MAAM,QAAQ,GAAG;gBAChB;oBACC,MAAM,EAAE;wBACP,MAAM,EAAE,EAAE,GAAG,EAAE,yBAAkB,CAAC,SAAS,EAAE;wBAC7C,wCAAwC,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE;qBACpD;iBACD;gBACD;oBACC,OAAO,EAAE;wBACR,IAAI,EAAE,OAAO;wBACb,UAAU,EAAE,MAAM;wBAClB,YAAY,EAAE,KAAK;wBACnB,EAAE,EAAE,MAAM;qBACV;iBACD;gBACD;oBACC,OAAO,EAAE,OAAO;iBAChB;gBACD;oBACC,MAAM,EAAE;wBACP,iBAAiB,EAAE,MAAM,CAAC,IAAI;qBAC9B;iBACD;gBACD;oBACC,MAAM,EAAE,YAAY;iBACpB;aACD,CAAC;YACF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;YACzD,MAAM,UAAU,GAAG,MAAM,CAAC,CAAC,CAAC,EAAE,UAAU,IAAI,CAAC,CAAC;YAE9C,IAAI,UAAU,IAAI,MAAM,CAAC,eAAe,EAAE,CAAC;gBAC1C,gBAAgB,GAAG,6BAAsB,CAAC,iBAAiB,CAAC;YAC7D,CAAC;QACF,CAAC;QACD,IAAI,MAAM,CAAC,mBAAmB,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YAGrD,MAAM,EAAE,mBAAmB,EAAE,4BAA4B,EAAE,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAC/F,MAAM,CAAC,IAAI,CACX,CAAC;YAEF,IAAI,mBAAmB,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;gBAC9C,gBAAgB,GAAG,6BAAsB,CAAC,WAAW,CAAC;YACvD,CAAC;QACF,CAAC;QAED,MAAM,IAAI,CAAC,eAAe,CAAC,iBAAiB,CAC3C,MAAM,CAAC,GAAG,EACV;YACC,IAAI,EAAE;gBACL,gBAAgB;aAChB;SACD,EACD;YACC,GAAG,EAAE,IAAI;YACT,aAAa,EAAE,IAAI;SACnB,CACD,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,gBAAgB;QAC5B,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC;YAC/C,UAAU,EAAE,EAAE,GAAG,EAAE,iBAAU,CAAC,aAAa,EAAE;YAC7C,gBAAgB,EAAE,IAAI;SACtB,CAAC,CAAC;QAEH,OAAO,CAAC,GAAG,CAAC,sBAAsB,OAAO,CAAC,MAAM,UAAU,CAAC,CAAC;QAE5D,OAAO,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;QACjC,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;YAC9B,OAAO,CAAC,IAAI,CAAC,qBAAqB,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;YACjD,MAAM,IAAI,CAAC,sBAAsB,CAAC,MAAM,CAAC,CAAC;YAC1C,OAAO,CAAC,OAAO,CAAC,qBAAqB,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC;QACrD,CAAC;QACD,OAAO,CAAC,OAAO,CAAC,kBAAkB,CAAC,CAAC;IACrC,CAAC;IAEO,KAAK,CAAC,gBAAgB,CAAC,IAAY;QAC1C,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;QAC5F,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,MAAM,IAAI,kBAAS,CAAC;gBACnB,IAAI,EAAE,WAAW;gBACjB,OAAO,EAAE,kBAAkB;aAC3B,CAAC,CAAC;QACJ,CAAC;QACD,OAAO,MAAM,CAAC;IACf,CAAC;IAEO,KAAK,CAAC,uBAAuB,CAAC,UAAkB;QACvD,MAAM,QAAQ,GAAG;YAChB;gBACC,MAAM,EAAE;oBACP,MAAM,EAAE,EAAE,GAAG,EAAE,yBAAkB,CAAC,SAAS,EAAE;oBAC7C,wCAAwC,EAAE,EAAE,GAAG,EAAE,CAAC,EAAE;iBACpD;aACD;YACD;gBACC,OAAO,EAAE;oBACR,IAAI,EAAE,OAAO;oBACb,UAAU,EAAE,MAAM;oBAClB,YAAY,EAAE,KAAK;oBACnB,EAAE,EAAE,MAAM;iBACV;aACD;YACD;gBACC,OAAO,EAAE,OAAO;aAChB;YACD;gBACC,MAAM,EAAE;oBACP,iBAAiB,EAAE,UAAU;iBAC7B;aACD;YACD;gBACC,MAAM,EAAE;oBACP,GAAG,EAAE,IAAI;oBACT,mBAAmB,EAAE;wBACpB,IAAI,EAAE;4BACL,SAAS,EAAE;gCACV,OAAO,EAAE,CAAC,yCAAyC,EAAE,CAAC,CAAC;6BACvD;yBACD;qBACD;oBACD,4BAA4B,EAAE;wBAC7B,IAAI,EAAE;4BACL,SAAS,EAAE;gCACV,OAAO,EAAE,CAAC,kDAAkD,EAAE,CAAC,CAAC;6BAChE;yBACD;qBACD;iBACD;aACD;SACD,CAAC;QAEF,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC;QAEzD,OAAO;YACN,mBAAmB,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,mBAAmB,IAAI,CAAC;YACxD,4BAA4B,EAAE,MAAM,CAAC,CAAC,CAAC,EAAE,4BAA4B,IAAI,CAAC;SAC1E,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,kBAAkB,CAAC,IAA6B,EAAE,MAA+B;QAC9F,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,iBAAiB,CACzD,IAAI,EACJ;YACC,KAAK,EAAE;gBACN,OAAO,EAAE,MAAM;aACf;SACD,EACD;YACC,GAAG,EAAE,IAAI;YACT,aAAa,EAAE,IAAI;SACnB,CACD,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,0BAA0B,CACvC,KAAiC,EACjC,MAA+B;QAE/B,OAAO,CAAC,GAAG,CAAC,iDAAiD,EAAE,MAAM,CAAC,CAAC;QACvE,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,EAAE;YAC3D,KAAK,EAAE;gBACN,OAAO,EAAE,MAAM;aACf;SACD,CAAC,CAAC;IACJ,CAAC;IAEO,KAAK,CAAC,sBAAsB,CAAC,MAA+B;QACnE,OAAO,CAAC,GAAG,CAAC,+BAA+B,EAAE,MAAM,CAAC,CAAC;QAErD,MAAM,QAAQ,GAAG,MAAM,oCAAmB,CAAC,WAAW,EAAE,CAAC;QACzD,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,CACnD,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,EAChD;YACC,KAAK,EAAE;gBACN,OAAO,EAAE,MAAM;aACf;SACD,CACD,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,oBAAoB,CAAC,IAA6B,EAAE,MAA+B;QAChG,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,iBAAiB,CACzD,IAAI,EACJ;YACC,KAAK,EAAE;gBACN,OAAO,EAAE,MAAM;aACf;SACD,EACD;YACC,GAAG,EAAE,IAAI;YACT,aAAa,EAAE,IAAI;SACnB,CACD,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,4BAA4B,CACzC,KAAiC,EACjC,MAA+B;QAE/B,MAAM,YAAY,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,KAAK,EAAE;YAC3D,KAAK,EAAE;gBACN,OAAO,EAAE,MAAM;aACf;SACD,CAAC,CAAC;IACJ,CAAC;IAEO,eAAe,CAAC,OAAe;QACtC,MAAM,IAAI,kBAAS,CAAC;YACnB,IAAI,EAAE,aAAa;YACnB,OAAO;SACP,CAAC,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,eAAe,CAAC,IAAS,EAAE,UAAkB;QACzD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,gBAAgB,CAAC,UAAU,CAAC,CAAC;QACvD,IAAI,CAAC,MAAM,EAAE,CAAC;YACb,IAAI,CAAC,eAAe,CAAC,kBAAkB,CAAC,CAAC;QAC1C,CAAC;QACD,MAAM,SAAS,GAAG,MAAM,oCAAmB,CAAC,SAAS,CAAC,IAAI,oBAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;QAEzF,IAAI,MAAM,CAAC,UAAU,IAAI,iBAAU,CAAC,aAAa,IAAI,CAAC,SAAS,EAAE,CAAC;YACjE,IAAI,CAAC,eAAe,CAAC,yCAAyC,CAAC,CAAC;QACjE,CAAC;QAED,IAAI,MAAM,CAAC,UAAU,IAAI,iBAAU,CAAC,aAAa,EAAE,CAAC;YACnD,IAAK,MAA2C,CAAC,YAAY,CAAC,QAAQ,EAAE,IAAI,IAAI,EAAE,CAAC;gBAClF,IAAI,CAAC,eAAe,CAAC,uCAAuC,CAAC,CAAC;YAC/D,CAAC;QACF,CAAC;QAED,MAAM,WAAW,GAAG,MAAkC,CAAC;QAEvD,IAAI,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,EAAE,CAAC;YACvC,IAAI,CAAC,eAAe,CAAC,6CAA6C,CAAC,CAAC;QACrE,CAAC;QAED,IAAI,WAAW,CAAC,cAAc,IAAI,CAAC,SAAS,EAAE,CAAC;YAC9C,IAAI,CAAC,eAAe,CAAC,yCAAyC,CAAC,CAAC;QACjE,CAAC;QAED,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,2BAA2B,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC;QACjF,IAAI,cAAc,EAAE,CAAC;YACpB,IAAI,CAAC,eAAe,CAAC,gCAAgC,CAAC,CAAC;QACxD,CAAC;QAED,IAAI,WAAW,CAAC,UAAU,IAAI,iBAAU,CAAC,eAAe,EAAE,CAAC;YAC1D,IAAI,CAAE,WAAkD,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;gBAChF,IAAI,CAAC,eAAe,CAAC,0CAA0C,CAAC,CAAC;YAClE,CAAC;QACF,CAAC;QAED,MAAM,IAAI,CAAC,SAAS,CAAC,iBAAiB,CACrC,IAAI,EACJ,EAAE,KAAK,EAAE,EAAE,OAAO,EAAE,WAAW,CAAC,GAAG,EAAE,EAAE,EACvC,EAAE,GAAG,EAAE,IAAI,EAAE,aAAa,EAAE,IAAI,EAAE,CAClC,CAAC;QAEF,OAAO,MAAM,CAAC;IACf,CAAC;IAEO,KAAK,CAAC,2BAA2B,CACxC,MAA+B,EAC/B,MAAgC;QAEhC,MAAM,SAAS,GAAG,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,CAAC,gBAAgB,IAAI,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;QAEnF,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;YACxC,GAAG,EAAE,MAAM;YACX,OAAO,EAAE,EAAE,GAAG,EAAE,SAAS,EAAE;SAC3B,CAAC,CAAC;QAEH,OAAO,CAAC,CAAC,IAAI,CAAC;IACf,CAAC;IAEO,KAAK,CAAC,6BAA6B,CAC1C,KAAiC,EACjC,SAAkC,EAClC,SAAkC;QAElC,MAAM,IAAI,CAAC,4BAA4B,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;QAC1D,MAAM,IAAI,CAAC,0BAA0B,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC;IACzD,CAAC;IAEM,gBAAgB,GAAG,KAAK,EAAE,IAAY,EAA6B,EAAE;QAC3E,MAAM,cAAc,GAAG,IAAA,mBAAY,GAAE,CAAC,iBAAiB,EAAE,CAAC;QAC1D,MAAM,WAAW,GAAG,CAAC,MAAM,cAAc,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,IAAI,sBAAsB,CAAC;QAE7F,MAAM,IAAI,GAAG,GAAG,WAAW,WAAW,IAAI,EAAE,CAAC;QAE7C,MAAM,OAAO,GAAG,6HAA6H,IAAI;IAC/I,IAAI,EAAE,CAAC;QAET,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC1B,CAAC,CAAC;IAEK,KAAK,CAAC,iBAAiB,CAAC,IAAyB;QACvD,IAAI,CAAC;YACJ,IAAI,KAAK,GAAG,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;YAE9B,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;gBACjB,IAAA,8BAAe,EAAC,8BAA8B,CAAC,CAAC;YACjD,CAAC;YAED,MAAM,MAAM,GAAG,IAAI,EAAE,MAAM,IAAI;gBAC9B,GAAG,EAAE,CAAC;gBACN,gBAAgB,EAAE,CAAC;gBACnB,gBAAgB,EAAE,CAAC;gBACnB,cAAc,EAAE,CAAC;gBACjB,IAAI,EAAE,CAAC;gBACP,MAAM,EAAE,CAAC;gBACT,SAAS,EAAE,CAAC;gBACZ,UAAU,EAAE,CAAC;aACb,CAAC;YAEF,IAAI,cAAc,GAAG,IAAI,CAAC;YAE1B,IAAI,KAAK,CAAC,MAAM,EAAE,CAAC;gBAClB,IAAI,KAAK,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;oBAChC,cAAc,GAAG,IAAI,CAAC;oBACtB,OAAO,KAAK,CAAC,MAAM,CAAC;gBACrB,CAAC;YACF,CAAC;YAED,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;gBAErB,IAAI,MAAM,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;oBAC/B,KAAK,CAAC,SAAS,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBACvD,CAAC;gBACD,IAAI,MAAM,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;oBAC/B,KAAK,CAAC,SAAS,CAAC,IAAI,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;gBACvD,CAAC;gBACD,IAAI,KAAK,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;oBAC9B,KAAK,CAAC,SAAS,CAAC,GAAG,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBACrD,CAAC;gBACD,IAAI,KAAK,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;oBAC9B,KAAK,CAAC,SAAS,CAAC,GAAG,GAAG,IAAI,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC;gBACrD,CAAC;YACF,CAAC;YAED,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;YACzE,KAAK,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,IAAI,EAAE,EAAE,CAAC;YACzC,OAAO,KAAK,CAAC,IAAI,CAAC;YAElB,MAAM,QAAQ,GAAU;gBACvB,EAAE,MAAM,EAAE,EAAE,GAAG,KAAK,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE;gBACzC;oBACC,OAAO,EAAE;wBAER,IAAI,EAAE,QAAQ;wBACd,UAAU,EAAE,WAAW;wBACvB,YAAY,EAAE,KAAK;wBACnB,EAAE,EAAE,WAAW;qBACf;iBACD;gBACD,EAAE,OAAO,EAAE,EAAE,IAAI,EAAE,YAAY,EAAE,0BAA0B,EAAE,IAAI,EAAE,EAAE;gBACrE;oBACC,UAAU,EAAE;wBACX,SAAS,EAAE;4BACV,KAAK,EAAE;gCACN,EAAE,EAAE;oCACH,GAAG,EAAE;wCACJ;4CACC,IAAI,EAAE;gDACL,EAAE,OAAO,EAAE,CAAC,eAAe,EAAE,KAAK,CAAC,EAAE;gDACrC,EAAE,GAAG,EAAE,CAAC,eAAe,EAAE,IAAA,aAAK,GAAE,CAAC,MAAM,EAAE,CAAC,EAAE;6CAC5C;yCACD;wCACD,EAAE,OAAO,EAAE,CAAC,mBAAmB,EAAE,KAAK,CAAC,EAAE;qCACzC;iCACD;gCACD,IAAI,EAAE,IAAI;gCACV,IAAI,EAAE,KAAK;6BACX;yBACD;qBACD;iBACD;gBACD;oBACC,MAAM,EAAE,cAAc;wBACrB,CAAC,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE;wBACrB,CAAC,CAAC,KAAK,CAAC,MAAM,KAAK,QAAQ;4BAC1B,CAAC,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE;4BACtB,CAAC,CAAC,EAAE;iBACN;gBACD;oBACC,UAAU,EAAE;wBACX,MAAM,EAAE;4BACP,KAAK,EAAE;gCACN,EAAE,EAAE,EAAE,GAAG,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,EAAE;gCACjC,IAAI,EAAE,SAAS;gCACf,IAAI,EAAE,SAAS;6BACf;yBACD;qBACD;iBACD;gBACD;oBACC,QAAQ,EAAE,MAAM;iBAChB;aACD,CAAC;YAEF,IAAI,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC;gBAC7B,MAAM,SAAS,GAAG,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC;gBACxC,MAAM,KAAK,GAAG,IAAI,MAAM,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;gBACzC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;gBAEtF,QAAQ,CAAC,IAAI,CAAC;oBACb,MAAM,EAAE;wBACP,GAAG,EAAE,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC;qBAC1D;iBACD,CAAC,CAAC;YACJ,CAAC;YAGD,MAAM,OAAO,GAAG,MAAM,IAAA,gCAAmB,EAAC,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,CAAC;YAEpG,OAAO,OAAsD,CAAC;QAC/D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACd,MAAM,IAAI,kBAAS,CAAC;gBACnB,IAAI,EAAE,uBAAuB;gBAC7B,OAAO,EAAE,QAAQ,GAAG,EAAE;aACtB,CAAC,CAAC;QACJ,CAAC;IACF,CAAC;IAEM,KAAK,CAAC,2BAA2B,CAAC,MAA+B;QACvE,MAAM,SAAS,GAAG,MAAM,oCAAmB,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAE9D,MAAM,KAAK,GAAQ;YAClB,UAAU,EAAE,EAAE,GAAG,EAAE,CAAC,iBAAU,CAAC,MAAM,EAAE,iBAAU,CAAC,gBAAgB,EAAE,iBAAU,CAAC,gBAAgB,CAAC,EAAE;YAClG,SAAS,EAAE,IAAI;YACf,gBAAgB,EAAE,IAAI;YACtB,GAAG,EAAE;gBACJ,EAAE,cAAc,EAAE,EAAE,GAAG,EAAE,IAAA,aAAK,GAAE,CAAC,MAAM,EAAE,EAAE,EAAE;gBAC7C,EAAE,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE;gBACtC,EAAE,cAAc,EAAE,IAAI,EAAE;aACxB;YACD,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;SAClC,CAAC;QAEF,IAAI,CAAC,SAAS,EAAE,CAAC;YAChB,KAAK,CAAC,cAAc,GAAG,EAAE,GAAG,EAAE,IAAI,EAAE,CAAC;QACtC,CAAC;QAGD,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAEvD,MAAM,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAEpD,MAAM,IAAI,CAAC,SAAS,CAAC,iBAAiB,CACrC,MAAM,EACN;YACC,SAAS,EAAE;gBACV,OAAO,EAAE,EAAE,KAAK,EAAE,SAAS,EAAE;aAC7B;SACD,EACD;YACC,GAAG,EAAE,IAAI;YACT,aAAa,EAAE,IAAI;SACnB,CACD,CAAC;IACH,CAAC;IAEM,KAAK,CAAC,sBAAsB;QAClC,MAAM,WAAW,GAAG,IAAA,aAAK,GAAE,CAAC,MAAM,EAAE,CAAC;QACrC,MAAM,sBAAsB,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC;YACjE,UAAU,EAAE,iBAAU,CAAC,MAAM;YAC7B,cAAc,EAAE,IAAI;YACpB,SAAS,EAAE,IAAI;YACf,GAAG,EAAE;gBACJ;oBACC,gBAAgB,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;iBACpC;gBACD;oBACC,gBAAgB,EAAE,IAAI;iBACtB;aACD;YACD,cAAc,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;YACrC,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;SAClC,CAAC,CAAC;QAEH,OAAO,sBAAsB,CAAC;IAC/B,CAAC;IAEM,KAAK,CAAC,2CAA2C;QACvD,MAAM,YAAY,GAAG,MAAM,IAAA,0BAAe,GAAE,CAAC;QAC7C,MAAM,WAAW,GAAG,IAAA,aAAK,GAAE,CAAC,MAAM,EAAE,CAAC;QAErC,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,qBAAqB,CAAC,OAAO,EAAE,CAAC;QAEpE,MAAM,8BAA8B,GACnC,gBAAgB,EAAE,QAAQ,EAAE,SAAS,IAAI,gBAAS,CAAC,UAAU;YAC5D,CAAC,CAAC,IAAI;YACN,CAAC,CAAC,IAAA,+BAAsB,EAAC,CAAC,gBAAgB,EAAE,QAAQ,EAAE,KAAK,IAAI,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC;QAEpF,MAAM,uCAAuC,GAAG,IAAA,+BAAsB,EACrE,CAAC,gBAAgB,EAAE,QAAQ,EAAE,iBAAiB,IAAI,CAAC,CAAC,GAAG,YAAY,CACnE,CAAC;QAEF,MAAM,sBAAsB,GAAG,MAAM,IAAI,CAAC,eAAe,CAAC,SAAS,CAAC;YAEnE;gBACC,MAAM,EAAE;oBACP,UAAU,EAAE,iBAAU,CAAC,MAAM;oBAC7B,cAAc,EAAE,IAAI;oBACpB,SAAS,EAAE,IAAI;oBACf,GAAG,EAAE,CAAC,EAAE,gBAAgB,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,EAAE,gBAAgB,EAAE,IAAI,EAAE,CAAC;oBAC3E,cAAc,EAAE,EAAE,IAAI,EAAE,WAAW,EAAE;oBACrC,cAAc,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;iBAClC;aACD;YAGD;gBACC,UAAU,EAAE;oBACX,sBAAsB,EAAE;wBACvB,KAAK,EAAE;4BACN;gCACC,GAAG,EAAE,CAAC,YAAY,EAAE,gBAAS,CAAC,UAAU,CAAC;6BACzC;4BACD,IAAI;4BACJ;gCACC,OAAO,EAAE;oCACR,QAAQ,EAAE;wCACT;4CACC,IAAI,EAAE;gDACL,GAAG,EAAE,CAAC,aAAa,EAAE,iBAAU,CAAC,aAAa,CAAC;6CAC9C;4CACD,IAAI,EAAE,8BAA8B;yCACpC;qCACD;oCACD,OAAO,EAAE,IAAA,0DAA8B,EAAC;wCACvC,SAAS,EAAE,CAAC,QAAQ,EAAE,YAAY,CAAC;qCACnC,CAAC;iCACF;6BACD;yBACD;qBACD;oBAED,iCAAiC,EAAE;wBAClC,OAAO,EAAE;4BACR,QAAQ,EAAE;gCACT;oCACC,IAAI,EAAE;wCACL,GAAG,EAAE,CAAC,aAAa,EAAE,iBAAU,CAAC,aAAa,CAAC;qCAC9C;oCACD,IAAI,EAAE,IAAI;iCACV;6BACD;4BACD,OAAO,EAAE,IAAA,0DAA8B,EAAC;gCACvC,SAAS,EAAE,CAAC,mBAAmB,EAAE,YAAY,CAAC;6BAC9C,CAAC;yBACF;qBACD;oBAED,8BAA8B,EAAE;wBAC/B,OAAO,EAAE;4BACR,QAAQ,EAAE;gCACT;oCACC,IAAI,EAAE;wCACL,GAAG,EAAE,CAAC,aAAa,EAAE,iBAAU,CAAC,aAAa,CAAC;qCAC9C;oCACD,IAAI,EAAE,uCAAuC;iCAC7C;6BACD;4BACD,OAAO,EAAE,IAAA,0DAA8B,EAAC;gCACvC,SAAS,EAAE,CAAC,gBAAgB,EAAE,YAAY,CAAC;6BAC3C,CAAC;yBACF;qBACD;iBACD;aACD;YAGD,EAAE,MAAM,EAAE,CAAC,EAAE;SACb,CAAC,CAAC;QAEH,OAAO,sBAAsB,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IAC1C,CAAC;IAEM,KAAK,CAAC,0BAA0B;QACtC,MAAM,6BAA6B,GAAG,MAAM,IAAI,CAAC,sBAAsB,EAAE,CAAC;QAE1E,IAAI,6BAA6B,EAAE,CAAC;YACnC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC;QACzB,CAAC;QAED,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;IAC1B,CAAC;IAEO,KAAK,CAAC,YAAY,CAAC,OAAkC;QAC5D,OAAO,MAAM,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC;YAC3C,IAAI,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE;YACtB,MAAM,EAAE,EAAE,GAAG,EAAE,yBAAkB,CAAC,SAAS,EAAE;YAC7C,SAAS,EAAE,gBAAS,CAAC,OAAO;SAC5B,CAAC,CAAC;IACJ,CAAC;IAEM,KAAK,CAAC,mBAAmB,CAC/B,QAAgB,EAChB,MAAsC;QAEtC,MAAM,gBAAgB,GAAG,IAAI,mCAAgB,EAAE,CAAC;QAGhD,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAGvE,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAG/C,IAAI,MAAM,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,IAAI,oBAAQ,CAAC,KAAK,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC;QACnD,CAAC;QAGD,MAAM,cAAc,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC;YAClD,GAAG,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE;YACrB,qBAAqB,EAAE,IAAI;SAC3B,CAAC,CAAC;QAEH,IAAI,cAAc,EAAE,CAAC;YAEpB,OAAO,EAAE,CAAC;QACX,CAAC;QAGD,MAAM,WAAW,GAAG,MAAM,IAAI,CAAC,YAAY,CAAC,OAAO,CAAC,CAAC;QAGrD,MAAM,mBAAmB,GAAG,MAAM,IAAI,CAAC,2CAA2C,EAAE,CAAC;QACrF,IAAI,CAAC,mBAAmB,EAAE,CAAC;YAE1B,OAAO,EAAE,CAAC;QACX,CAAC;QAGD,IACC,mBAAmB,CAAC,0BAA0B;YAC9C,WAAW,GAAG,CAAC,mBAAmB,CAAC,iBAAiB,IAAI,CAAC,CAAC,EACzD,CAAC;YAKF,OAAO,gBAAgB,CAAC,kBAAkB,CAAC,CAAC,mBAAmB,CAAC,CAAC,CAAC;QACnE,CAAC;QAED,OAAO,EAAE,CAAC;IACX,CAAC;IAEO,KAAK,CAAC,wBAAwB,CAAC,OAAkC;QAExE,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,CAC7C,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EACzB;YACC,IAAI,EAAE;gBACL,qBAAqB,EAAE,KAAK;aAC5B;SACD,CACD,CAAC;QAEF,OAAO,MAAM,CAAC,aAAa,CAAC;IAC7B,CAAC;IAEM,KAAK,CAAC,wBAAwB,CAAC,MAA+B,EAAE,IAAS;QAE/E,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;QAGnD,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;QAG3F,MAAM,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;QAGtC,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,UAAU,CAC7C,EAAE,GAAG,EAAE,EAAE,GAAG,EAAE,OAAO,EAAE,EAAE,EACzB;YACC,IAAI,EAAE;gBACL,qBAAqB,EAAE,IAAI,CAAC,qBAAqB;aACjD;SACD,CACD,CAAC;QAEF,OAAO,MAAM,CAAC,aAAa,CAAC;IAC7B,CAAC;CACD,CAAA;AAr3CY,sCAAa;wBAAb,aAAa;IADzB,IAAA,gBAAO,GAAE;;GACG,aAAa,CAq3CzB;AAEY,QAAA,aAAa,GAAG,gBAAS,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC","sourcesContent":["import Container, { Service } from 'typedi';\nimport { TRPCError } from '@trpc/server';\nimport { DocumentType, mongoose, queryMethod, ReturnModelType } from '@typegoose/typegoose';\nimport {\n\tCart,\n\tCouponModel,\n\tCustomCoupon,\n\tgetCoreUserModel,\n\tGlobalCoupon,\n\tIndividualStoreCoupon,\n\tIndividualUserCoupon,\n\tCoupon as Model,\n\tReferralRewardCoupon,\n\tReferralRewardCouponModel,\n\tRegularOrder,\n\tRegularOrderModel,\n\tShopModel,\n\tShop,\n\tShopsCategoriesCoupon,\n\tUser,\n\tUserModel,\n\tReferralCodeCoupon,\n\tReferralSetting,\n\tReferralSettingModel,\n} from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport {\n\tAllCouponsValidationDTO,\n\tCouponValidationOutputDTO,\n\tValidateCouponDTO,\n\tAllCouponsDTO,\n\tCheckExistingNewUserCouponOutputDTO,\n} from '@modules/coupon/validations';\nimport { SoftDeleteModel } from '@lyxa.ai/core/dist/libraries/mongo/plugins/soft-delete-plugin';\nimport {\n\tFilterDTO,\n\tPaginatedResponse,\n\tDeleteDTO,\n\tShareableLinkDTO,\n} from '@lyxa.ai/core/dist/utilities/validation';\nimport {\n\tcreateRawDocumentPaginatorObject,\n\tpaginateAggregation,\n\tPaginatorOptions,\n} from '@lyxa.ai/core/dist/utilities/pagination';\nimport { ModelType } from '@typegoose/typegoose/lib/types';\nimport {\n\tcustomCouponService,\n\tglobalCouponService,\n\tindividualStoreCouponService,\n\tindividualUserCouponService,\n\treferralCodeCouponService,\n\treferralRewardCouponService,\n} from '.';\nimport {\n\tCouponExpirationReason,\n\tCouponType,\n\tItemType,\n\tOrderType,\n\tRegularOrderStatus,\n\tStatus,\n\tValueType,\n} from '@lyxa.ai/core/dist/utilities/enum';\nimport { BaseCoupon, BaseCouponModel } from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport {\n\tPunchMarketingHistoryService,\n\tpunchMarketingHistoryService,\n} from '@modules/punch-marketing-history/services';\nimport { getLibraries } from '@lyxa.ai/core';\nimport { NotificationMicroserviceRouter } from '@lyxa.ai/notification';\nimport { CouponRepository } from './patterns/repository/CouponRepository';\nimport {\n\tbadRequestError,\n\tconflictError,\n\tinternalServerError,\n\tnotFoundError,\n\tnotImplementedError,\n} from '@lyxa.ai/core/dist/utilities/error-common';\nimport { shopsCategoriesCouponService } from './shops-categories-coupon.service';\nimport { CouponHelperService, couponHelperService } from './helper.service';\nimport { Dayjs, dayjs } from '@lyxa.ai/core/dist/utilities/dayjs';\nimport { getExchangeRate } from '@lyxa.ai/core/dist/utilities/currency';\nimport { roundSecondaryCurrency } from '@lyxa.ai/core/dist/utilities/shared';\nimport { getRoundSecondaryCurrencyStage } from '@lyxa.ai/core/dist/utilities/pipelines/common-pipeline-functions';\n\n@Service()\nexport class CouponService {\n\tprivate model: typeof CouponModel & SoftDeleteModel<Model>;\n\tprivate baseCouponModel: typeof BaseCouponModel & SoftDeleteModel<BaseCoupon>;\n\tprivate userModel: typeof UserModel & SoftDeleteModel<User>;\n\tprivate orderModel: typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\tprivate shopModel: typeof ShopModel & SoftDeleteModel<Shop>;\n\tprivate referralRewardModel: typeof ReferralRewardCouponModel & SoftDeleteModel<ReferralRewardCoupon>;\n\tprivate punchHistoryService: PunchMarketingHistoryService;\n\tprivate _coreUserModel: ReturnType<typeof getCoreUserModel> | null = null;\n\tprivate couponHelper: CouponHelperService;\n\tprivate readonly referralSettingsModel: typeof ReferralSettingModel & SoftDeleteModel<ReferralSetting>;\n\n\tconstructor() {\n\t\tthis.model = CouponModel as typeof CouponModel & SoftDeleteModel<Model>;\n\t\tthis.baseCouponModel = BaseCouponModel as typeof BaseCouponModel & SoftDeleteModel<BaseCoupon>;\n\t\tthis.userModel = UserModel as typeof UserModel & SoftDeleteModel<User>;\n\t\tthis.orderModel = RegularOrderModel as typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\t\tthis.shopModel = ShopModel as typeof ShopModel & SoftDeleteModel<Shop>;\n\t\tthis.referralRewardModel = ReferralRewardCouponModel as typeof ReferralRewardCouponModel &\n\t\t\tSoftDeleteModel<ReferralRewardCoupon>;\n\t\tthis.punchHistoryService = punchMarketingHistoryService;\n\t\tthis.couponHelper = couponHelperService;\n\t\tthis.referralSettingsModel = ReferralSettingModel as typeof ReferralSettingModel &\n\t\t\tSoftDeleteModel<ReferralSetting>;\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: AllCouponsValidationDTO): Promise<DocumentType<Model>> {\n\t\tlet coupon: DocumentType<Model>;\n\n\t\tif (\n\t\t\tdata.couponType != CouponType.REFERRAL_CODE &&\n\t\t\tdata?.duration &&\n\t\t\t!this.couponHelper.isDurationValid(dayjs(data?.duration?.start), dayjs(data?.duration?.end))\n\t\t) {\n\t\t\tconflictError(`Start date/time cannot be in the past `);\n\t\t}\n\n\t\tconst checkCoupon = await this.model.findOne({\n\t\t\tcode: data.code,\n\t\t\tdeletedAt: null,\n\t\t});\n\n\t\tif (checkCoupon) conflictError('Coupon code already exists');\n\n\t\tswitch (data.couponType) {\n\t\t\tcase CouponType.GLOBAL: {\n\t\t\t\tcoupon = await globalCouponService.create(data);\n\t\t\t\tif (coupon) {\n\t\t\t\t\tconst globalCoupon = coupon as DocumentType<GlobalCoupon>;\n\t\t\t\t\tif (!globalCoupon.forNewUserOnly) {\n\t\t\t\t\t\tawait this.assignCouponToMultipleUser({}, coupon._id);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tawait this.assignCouponToNewUsers(coupon._id);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase CouponType.REFERRAL_CODE: {\n\t\t\t\tcoupon = await referralCodeCouponService.create(data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase CouponType.REFERRAL_REWARD: {\n\t\t\t\tcoupon = await referralRewardCouponService.create(data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase CouponType.SHOPS_CATEGORIES: {\n\t\t\t\tcoupon = await shopsCategoriesCouponService.create(data);\n\t\t\t\tif (coupon) {\n\t\t\t\t\tconst shopsCategoriesCoupon = coupon as DocumentType<ShopsCategoriesCoupon>;\n\t\t\t\t\tif (!shopsCategoriesCoupon.forNewUserOnly) {\n\t\t\t\t\t\tawait this.assignCouponToMultipleUser({}, coupon._id);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tawait this.assignCouponToNewUsers(coupon._id);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase CouponType.INDIVIDUAL_STORE: {\n\t\t\t\tcoupon = await individualStoreCouponService.create(data);\n\t\t\t\tif (coupon) {\n\t\t\t\t\tconst individualStoreCoupon = coupon as DocumentType<IndividualStoreCoupon>;\n\t\t\t\t\tif (!individualStoreCoupon.forNewUserOnly) {\n\t\t\t\t\t\tawait this.assignCouponToMultipleUser({}, coupon._id);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tawait this.assignCouponToNewUsers(coupon._id);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase CouponType.INDIVIDUAL_USER: {\n\t\t\t\tcoupon = await individualUserCouponService.create(data);\n\t\t\t\tif (coupon) {\n\t\t\t\t\tconst individualUserCoupon = coupon as DocumentType<IndividualUserCoupon>;\n\t\t\t\t\tconst users = individualUserCoupon.users;\n\t\t\t\t\tawait this.assignCouponToMultipleUser({ _id: { $in: users } }, coupon._id);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase CouponType.CUSTOM_COUPON: {\n\t\t\t\tcoupon = await customCouponService.create(data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tbadRequestError('Coupon type is not valid');\n\t\t\t}\n\t\t}\n\n\t\tif (!coupon) internalServerError('Could not create coupon');\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(coupon._id);\n\n\t\treturn coupon;\n\t}\n\n\t/**\n\t * Get record by ID\n\t * @param id ID of the record\n\t */\n\tpublic async findById(id: string | mongoose.Types.ObjectId): Promise<DocumentType<Model>> {\n\t\tconst result = await this.model\n\t\t\t.findOne({\n\t\t\t\t_id: id,\n\t\t\t\tdeletedAt: null,\n\t\t\t})\n\t\t\t.populate([\n\t\t\t\t{\n\t\t\t\t\tpath: 'previousVersions',\n\t\t\t\t},\n\t\t\t]);\n\t\tif (!result) {\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\t\treturn result;\n\t}\n\n\t/**\n\t * Get records\n\t * @param query Query to find records\n\t */\n\tpublic async find(data?: Partial<FilterDTO>): Promise<PaginatedResponse<DocumentType<ModelType<Model>>>> {\n\t\ttry {\n\t\t\tconst populate = [\n\t\t\t\t...data?.populate,\n\t\t\t\t{\n\t\t\t\t\tpath: 'users',\n\t\t\t\t\tpopulate: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpath: 'coreUser',\n\t\t\t\t\t\t\tmodel: this.coreUserModel,\n\t\t\t\t\t\t\tselect: 'name profilePhoto -_id',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tselect: 'coreUser phoneNumber',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tpath: 'influencer',\n\t\t\t\t\tpopulate: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpath: 'coreUser',\n\t\t\t\t\t\t\tmodel: this.coreUserModel,\n\t\t\t\t\t\t\tselect: 'name profilePhoto -_id',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tselect: 'coreUser phoneNumber',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tpath: 'referralUser',\n\t\t\t\t\tpopulate: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpath: 'coreUser',\n\t\t\t\t\t\t\tmodel: this.coreUserModel,\n\t\t\t\t\t\t\tselect: 'name profilePhoto -_id',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tselect: 'coreUser phoneNumber',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tpath: 'user',\n\t\t\t\t\tpopulate: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpath: 'coreUser',\n\t\t\t\t\t\t\tmodel: this.coreUserModel,\n\t\t\t\t\t\t\tselect: 'name profilePhoto -_id',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tselect: 'coreUser phoneNumber',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tpath: 'referralCodeUsedBy',\n\t\t\t\t\tpopulate: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpath: 'coreUser',\n\t\t\t\t\t\t\tmodel: this.coreUserModel,\n\t\t\t\t\t\t\tselect: 'name profilePhoto -_id',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tselect: 'coreUser phoneNumber',\n\t\t\t\t},\n\t\t\t];\n\n\t\t\tconst paginate = createRawDocumentPaginatorObject(this.model as ReturnModelType<typeof this.model>);\n\t\t\tconst options: PaginatorOptions<typeof Model> = {\n\t\t\t\tpage: data?.page,\n\t\t\t\tsize: data?.size,\n\t\t\t\tsort: data?.sort,\n\t\t\t\tquery: { ...data?.query, updatedVersion: { $exists: false } },\n\t\t\t\tselect: data?.select,\n\t\t\t\tpopulate: populate,\n\t\t\t};\n\t\t\tconst paginatedResult = await paginate(options);\n\t\t\treturn paginatedResult;\n\t\t} catch (err) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'INTERNAL_SERVER_ERROR',\n\t\t\t\tmessage: `err: ${err}`,\n\t\t\t});\n\t\t}\n\t}\n\n\t/**\n\t * Update record\n\t * @param id ID of the old coupon\n\t * @param data Data of the updated coupon\n\t */\n\tpublic async update(id: string, data: AllCouponsValidationDTO): Promise<DocumentType<Model>> {\n\t\tlet coupon: DocumentType<BaseCoupon> | null;\n\n\t\tconst [oldCoupon, checkCouponCode, usersWithOldCoupon] = await Promise.all([\n\t\t\tthis.baseCouponModel.findById(id),\n\t\t\tthis.model.findOne({\n\t\t\t\tcode: data.code,\n\t\t\t\t_id: { $ne: id },\n\t\t\t\tupdatedVersion: { $exists: false },\n\t\t\t}),\n\t\t\tthis.userModel\n\t\t\t\t.find({\n\t\t\t\t\tcoupons: new mongoose.Types.ObjectId(id),\n\t\t\t\t})\n\t\t\t\t.select(['_id', 'coupons']),\n\t\t]);\n\n\t\tif (!oldCoupon) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'NOT_FOUND',\n\t\t\t\tmessage: `Coupon not found`,\n\t\t\t});\n\t\t}\n\n\t\tif (\n\t\t\tdata.couponType != CouponType.REFERRAL_CODE &&\n\t\t\toldCoupon?.duration &&\n\t\t\tdayjs(oldCoupon?.duration?.start) > dayjs(data?.duration.start)\n\t\t) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'BAD_REQUEST',\n\t\t\t\tmessage: `Don't allow updating coupon to have earlier start date/time than the original coupon`,\n\t\t\t});\n\t\t}\n\n\t\tif (\n\t\t\tdata.couponType != CouponType.REFERRAL_CODE &&\n\t\t\tdata?.duration &&\n\t\t\tdayjs(data?.duration?.start) > dayjs(data?.duration.end)\n\t\t) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'BAD_REQUEST',\n\t\t\t\tmessage: `End date/time must be after start date/time`,\n\t\t\t});\n\t\t}\n\n\t\tif (checkCouponCode) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'CONFLICT',\n\t\t\t\tmessage: `Coupon code already exists`,\n\t\t\t});\n\t\t}\n\n\t\tswitch (data.couponType) {\n\t\t\tcase CouponType.GLOBAL: {\n\t\t\t\tcoupon = await globalCouponService.create(data);\n\t\t\t\tif (coupon) {\n\t\t\t\t\tconst globalCoupon = coupon as DocumentType<GlobalCoupon>;\n\t\t\t\t\tif (!globalCoupon.forNewUserOnly) {\n\t\t\t\t\t\tawait this.exchangeCouponForMultipleUser(\n\t\t\t\t\t\t\t{ _id: { $in: usersWithOldCoupon?.map(u => u._id) } },\n\t\t\t\t\t\t\toldCoupon._id,\n\t\t\t\t\t\t\tcoupon._id\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase CouponType.SHOPS_CATEGORIES: {\n\t\t\t\tcoupon = await shopsCategoriesCouponService.create(data);\n\t\t\t\tif (coupon) {\n\t\t\t\t\tconst shopsCategoriesCoupon = coupon as DocumentType<ShopsCategoriesCoupon>;\n\t\t\t\t\tif (!shopsCategoriesCoupon.forNewUserOnly) {\n\t\t\t\t\t\tawait this.exchangeCouponForMultipleUser(\n\t\t\t\t\t\t\t{ _id: { $in: usersWithOldCoupon?.map(u => u._id) } },\n\t\t\t\t\t\t\toldCoupon._id,\n\t\t\t\t\t\t\tshopsCategoriesCoupon._id\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase CouponType.INDIVIDUAL_STORE: {\n\t\t\t\tcoupon = await individualStoreCouponService.create(data);\n\t\t\t\tif (coupon) {\n\t\t\t\t\tconst individualStoreCoupon = coupon as DocumentType<IndividualStoreCoupon>;\n\t\t\t\t\tif (!individualStoreCoupon.forNewUserOnly) {\n\t\t\t\t\t\tawait this.exchangeCouponForMultipleUser(\n\t\t\t\t\t\t\t{ _id: { $in: usersWithOldCoupon?.map(u => u._id) } },\n\t\t\t\t\t\t\toldCoupon._id,\n\t\t\t\t\t\t\tindividualStoreCoupon._id\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase CouponType.INDIVIDUAL_USER: {\n\t\t\t\tcoupon = await individualUserCouponService.create(data);\n\t\t\t\tif (coupon) {\n\t\t\t\t\tconst individualUserCoupon = coupon as DocumentType<IndividualUserCoupon>;\n\t\t\t\t\tawait this.removeCouponFromMultipleUser(\n\t\t\t\t\t\t{ _id: { $in: usersWithOldCoupon?.map(u => u._id) } },\n\t\t\t\t\t\toldCoupon._id\n\t\t\t\t\t);\n\t\t\t\t\tawait this.assignCouponToMultipleUser(\n\t\t\t\t\t\t{ _id: { $in: individualUserCoupon.users } },\n\t\t\t\t\t\tindividualUserCoupon._id\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase CouponType.CUSTOM_COUPON: {\n\t\t\t\tcoupon = await customCouponService.create(data);\n\t\t\t\tif (coupon) {\n\t\t\t\t\tconst customCoupon = coupon as DocumentType<CustomCoupon>;\n\t\t\t\t\tif (!customCoupon.forNewUserOnly) {\n\t\t\t\t\t\tawait this.exchangeCouponForMultipleUser(\n\t\t\t\t\t\t\t{ _id: { $in: usersWithOldCoupon?.map(u => u._id) } },\n\t\t\t\t\t\t\toldCoupon._id,\n\t\t\t\t\t\t\tcoupon._id\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tthrow new TRPCError({\n\t\t\t\t\tcode: 'BAD_REQUEST',\n\t\t\t\t\tmessage: `Invalid coupon type`,\n\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (!coupon) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'BAD_REQUEST',\n\t\t\t\tmessage: `Could create updated coupon`,\n\t\t\t});\n\t\t}\n\n\t\t// add previous version to new coupon\n\t\tconst previousVersions = oldCoupon?.previousVersions || [];\n\t\tpreviousVersions.push(oldCoupon._id);\n\n\t\tconst updatedCoupon = await this.baseCouponModel.findByIdAndUpdate(\n\t\t\tcoupon._id,\n\t\t\t{\n\t\t\t\t$set: {\n\t\t\t\t\tpreviousVersions,\n\t\t\t\t},\n\t\t\t},\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 (!updatedCoupon) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'INTERNAL_SERVER_ERROR',\n\t\t\t\tmessage: `Could not set previous versions of coupon`,\n\t\t\t});\n\t\t}\n\t\t// update old coupon\n\t\tconst updatedOldCoupon = await this.baseCouponModel.findByIdAndUpdate(\n\t\t\toldCoupon._id,\n\t\t\t{\n\t\t\t\t$set: {\n\t\t\t\t\tupdatedVersion: coupon._id,\n\t\t\t\t\t'duration.end': coupon.duration.end,\n\t\t\t\t},\n\t\t\t},\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\treturn updatedCoupon;\n\t}\n\n\tpublic async updateStatus(id: string, status: Status): Promise<DocumentType<Model>> {\n\t\tconst coupon = await this.baseCouponModel.findByIdAndUpdate(\n\t\t\tid,\n\t\t\t{\n\t\t\t\t$set: { status },\n\t\t\t},\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 (!coupon) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'NOT_FOUND',\n\t\t\t\tmessage: 'Coupon not found',\n\t\t\t});\n\t\t}\n\n\t\t// also update the status of previous versions of the coupon\n\t\tconst previousVersions = coupon.previousVersions;\n\t\tif (previousVersions && previousVersions.length > 0) {\n\t\t\tawait this.baseCouponModel.updateMany(\n\t\t\t\t{ _id: { $in: previousVersions } },\n\t\t\t\t{\n\t\t\t\t\t$set: { status },\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\n\t\treturn coupon;\n\t}\n\n\t/**\n\t * Delete record\n\t * @param data Data for delete\n\t */\n\tpublic async deleteById(data: DeleteDTO): Promise<string> {\n\t\tconst { _id, softDelete } = data;\n\n\t\tconst coupon = await this.model.findById(_id);\n\n\t\tif (!coupon) {\n\t\t\tnotFoundError('Coupon not found');\n\t\t}\n\n\t\tconst result = await this.model.deleteRecord({ _id, deletedAt: null }, softDelete);\n\t\tif (!result) {\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\t// remove coupons from users' coupon lists\n\t\tthis.removeCouponFromMultipleUser({}, _id);\n\n\t\t// also delete previous versions of the coupon\n\t\tconst previousVersions = coupon.previousVersions;\n\t\tif (previousVersions && previousVersions.length > 0) {\n\t\t\tawait this.model.deleteRecord({ _id: { $in: previousVersions }, deletedAt: null }, softDelete);\n\t\t}\n\n\t\treturn 'Record deleted successfully';\n\t}\n\n\t/**\n\t * Get User Coupons\n\t * @param data User and pagination data\n\t */\n\tpublic async getUserCoupons(\n\t\tuser: mongoose.Types.ObjectId | undefined,\n\t\tshop: mongoose.Types.ObjectId | undefined,\n\t\tpage: number = 0,\n\t\tsize: number = 0\n\t): Promise<{\n\t\tavailable: Array<DocumentType<Model>>;\n\t\tused: Array<DocumentType<Model>>;\n\t\texpired: Array<DocumentType<Model>>;\n\t}> {\n\t\tconst couponRepository = new CouponRepository();\n\t\tlet itemType: ItemType | undefined = undefined;\n\t\tif (shop) {\n\t\t\tconst shopDocument = await this.shopModel.findOne({ _id: shop }).select('itemType');\n\t\t\titemType = shopDocument?.itemType;\n\t\t}\n\t\tconst coupons = await couponRepository.getUserCoupons(user, shop, itemType);\n\n\t\tif (shop && user) {\n\t\t\tconst punch = await this.punchHistoryService.getPunchCoupon(user, shop);\n\t\t\tif (punch) {\n\t\t\t\tcoupons.available.push(punch);\n\t\t\t}\n\t\t}\n\n\t\treturn couponRepository.addLabelsToAllCoupons(coupons);\n\t}\n\n\tpublic async validateCoupon(data: ValidateCouponDTO): Promise<CouponValidationOutputDTO> {\n\t\tif (data.coupon === 'punch') {\n\t\t\treturn await punchMarketingHistoryService.getPunchDiscount(data);\n\t\t}\n\n\t\tconst user = await this.userModel.findById(data.user);\n\t\tif (!user) notFoundError('User not found');\n\n\t\tlet coupon = await this.model.findOne({\n\t\t\tcode: data.coupon,\n\t\t\t_id: { $in: user.coupons ?? [] },\n\t\t\tstatus: { $in: [Status.ACTIVE, null] },\n\t\t});\n\n\t\tif (!coupon) {\n\t\t\tcoupon = await this.model.findOne({\n\t\t\t\tcode: data.coupon,\n\t\t\t\tstatus: { $in: [Status.ACTIVE, null] },\n\t\t\t\tcouponType: { $in: [CouponType.REFERRAL_CODE, CouponType.CUSTOM_COUPON] },\n\t\t\t\tupdatedVersion: { $exists: false },\n\t\t\t});\n\n\t\t\tif (!coupon) {\n\t\t\t\tnotFoundError('Coupon not found');\n\t\t\t}\n\n\t\t\t// add coupon to user list if it's referral code or custom coupon and not already added\n\t\t\tthis.userModel.findByIdAndUpdate(user._id, {\n\t\t\t\t$addToSet: { coupons: coupon._id },\n\t\t\t});\n\t\t}\n\n\t\tif (coupon.couponType == CouponType.REFERRAL_CODE) {\n\t\t\treturn await referralCodeCouponService.validateCoupon(data, coupon as DocumentType<ReferralCodeCoupon>);\n\t\t}\n\n\t\tconst baseCoupon = coupon as DocumentType<BaseCoupon>;\n\n\t\tconst { isValid, invalidMessage } = await this.validateBaseCoupon(\n\t\t\tbaseCoupon,\n\t\t\tuser._id,\n\t\t\tdata.amountBeforeCoupon,\n\t\t\tBoolean(data.scheduledAt) ? dayjs(data.scheduledAt) : undefined\n\t\t);\n\n\t\tif (!isValid) {\n\t\t\treturn {\n\t\t\t\tisValid,\n\t\t\t\tmessage: invalidMessage,\n\t\t\t};\n\t\t}\n\n\t\tswitch (coupon.couponType) {\n\t\t\tcase CouponType.REFERRAL_REWARD:\n\t\t\t\treturn await referralRewardCouponService.validateCoupon(\n\t\t\t\t\tdata,\n\t\t\t\t\tcoupon as DocumentType<ReferralRewardCoupon>\n\t\t\t\t);\n\t\t\tcase CouponType.GLOBAL:\n\t\t\t\treturn await globalCouponService.validateCoupon(data, coupon as DocumentType<GlobalCoupon>);\n\t\t\tcase CouponType.SHOPS_CATEGORIES:\n\t\t\t\treturn await shopsCategoriesCouponService.validateCoupon(\n\t\t\t\t\tdata,\n\t\t\t\t\tcoupon as DocumentType<ShopsCategoriesCoupon>\n\t\t\t\t);\n\t\t\tcase CouponType.INDIVIDUAL_STORE:\n\t\t\t\treturn await individualStoreCouponService.validateCoupon(\n\t\t\t\t\tdata,\n\t\t\t\t\tcoupon as DocumentType<IndividualStoreCoupon>\n\t\t\t\t);\n\t\t\tcase CouponType.INDIVIDUAL_USER:\n\t\t\t\treturn await individualUserCouponService.validateCoupon(\n\t\t\t\t\tdata,\n\t\t\t\t\tcoupon as DocumentType<IndividualUserCoupon>\n\t\t\t\t);\n\t\t\tcase CouponType.CUSTOM_COUPON:\n\t\t\t\treturn await customCouponService.validateCoupon(data, coupon as DocumentType<CustomCoupon>);\n\t\t\tdefault:\n\t\t\t\tnotImplementedError(`Validation not implemented for ${coupon.couponType} coupons`);\n\t\t}\n\t}\n\n\tprivate isCouponExpired(coupon: DocumentType<BaseCoupon>): Boolean {\n\t\tif (coupon.expirationReason || (coupon?.duration?.end && new Date(coupon?.duration?.end) < new Date())) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t *\n\t * @param coupon Base coupon document\n\t * @param user ID of the user trying to user the coupon\n\t * @param orderAmount Order subtotal\n\t * @returns True if coupon is valid\n\t */\n\tprivate async validateBaseCoupon(\n\t\tcoupon: DocumentType<BaseCoupon>,\n\t\tuser: mongoose.Types.ObjectId,\n\t\torderAmount: number,\n\t\tscheduledAt: Dayjs | undefined = undefined\n\t): Promise<{ isValid: boolean; invalidMessage?: string }> {\n\t\tconst invalidConditions = [\n\t\t\tthis.isCouponExpired(coupon), // check coupon expired\n\t\t\tcoupon.duration.start > dayjs().toDate(), // check coupon start\n\t\t\tcoupon.isMinOrderValueEnabled && coupon.minOrderValue && orderAmount < coupon.minOrderValue, // check minimum order value\n\t\t\tcoupon.forNewUserOnly && !(await this.verifyNewUserConditions(coupon, user)), // check if new user\n\t\t\tcoupon.isOrderLimitPerUserEnabled &&\n\t\t\t\tcoupon.orderLimitPerUser &&\n\t\t\t\t(await this.getCouponOrdersForUser(user, coupon.code)) >= coupon.orderLimitPerUser, // check order limit for user\n\t\t\tscheduledAt && Boolean(coupon.duration.end) && dayjs(coupon.duration.end).isBefore(scheduledAt), // check scheduledAt is before coupon end date\n\t\t];\n\n\t\tconst invalidMessages = [\n\t\t\t'This coupon is expired',\n\t\t\t'This coupon is not available yet',\n\t\t\t'The minimum order amount for this coupon is not met',\n\t\t\t'This coupon is for new users only',\n\t\t\t'You have reached the order limit for this coupon',\n\t\t\t'This coupon is not valid for this scheduled orders',\n\t\t];\n\n\t\tconst isValid = invalidConditions.every(value => Boolean(value) == false);\n\t\tconst invalidMessage = invalidMessages.filter((_, index) => invalidConditions[index])?.[0];\n\n\t\treturn { isValid, invalidMessage };\n\t}\n\n\t// Returns true if new user conditions are met. False otherwise\n\tprivate async verifyNewUserConditions(\n\t\tcoupon: DocumentType<BaseCoupon>,\n\t\tuser: mongoose.Types.ObjectId\n\t): Promise<boolean> {\n\t\tconst forNewUserOnly = coupon.forNewUserOnly;\n\t\tconst isOrderLimitPerUserEnabled = coupon.isOrderLimitPerUserEnabled;\n\t\tconst orderLimitPerUser = coupon.orderLimitPerUser;\n\n\t\tif (forNewUserOnly) {\n\t\t\tif (isOrderLimitPerUserEnabled && orderLimitPerUser) {\n\t\t\t\tconst orderCount = await couponHelperService.getSameDeviceOrdersWithCoupon(user, coupon);\n\t\t\t\treturn orderLimitPerUser > orderCount;\n\t\t\t}\n\t\t\treturn await couponHelperService.isNewUser(user);\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tprivate async getCouponOrdersForUser(user: mongoose.Types.ObjectId, couponCode: string): Promise<number> {\n\t\tconst orders = (await this.orderModel\n\t\t\t.find({\n\t\t\t\tuser: user,\n\t\t\t\tstatus: { $ne: RegularOrderStatus.CANCELLED },\n\t\t\t\torderType: OrderType.REGULAR,\n\t\t\t})\n\t\t\t.populate([{ path: 'cart' }])) as Array<DocumentType<RegularOrder> & { cart: DocumentType<Cart> }>;\n\n\t\tconst count = orders.filter(order => order.cart.couponCode == couponCode).length;\n\n\t\treturn count;\n\t}\n\n\tpublic async handleCouponExpiry(couponId: mongoose.Types.ObjectId) {\n\t\tconst coupon = await this.model.findById(couponId);\n\t\tif (!coupon || coupon.couponType == CouponType.REFERRAL_CODE) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst typedCoupon = coupon as DocumentType<BaseCoupon>;\n\t\tawait this.processCouponForExpiry(typedCoupon);\n\t}\n\n\tprivate async processCouponForExpiry(coupon: DocumentType<BaseCoupon>) {\n\t\tlet expirationReason: string | null = null;\n\n\t\tif (coupon.isTotalOrderLimitEnabled && coupon.totalOrderLimit) {\n\t\t\t// find the order count by aggregating the order collection,\n\t\t\t// checking orders that have adjustedFinance.pricing.couponDiscount > 0,\n\t\t\t// populating cart collection to match coupon code\n\n\t\t\tconst pipeline = [\n\t\t\t\t{\n\t\t\t\t\t$match: {\n\t\t\t\t\t\tstatus: { $ne: RegularOrderStatus.CANCELLED },\n\t\t\t\t\t\t'adjustedFinance.pricing.couponDiscount': { $gt: 0 },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$lookup: {\n\t\t\t\t\t\tfrom: 'carts',\n\t\t\t\t\t\tlocalField: 'cart',\n\t\t\t\t\t\tforeignField: '_id',\n\t\t\t\t\t\tas: 'cart',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$unwind: '$cart',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$match: {\n\t\t\t\t\t\t'cart.couponCode': coupon.code,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$count: 'orderCount',\n\t\t\t\t},\n\t\t\t];\n\t\t\tconst result = await this.orderModel.aggregate(pipeline);\n\t\t\tconst orderCount = result[0]?.orderCount ?? 0;\n\n\t\t\tif (orderCount >= coupon.totalOrderLimit) {\n\t\t\t\texpirationReason = CouponExpirationReason.TOTAL_ORDER_LIMIT;\n\t\t\t}\n\t\t}\n\t\tif (coupon.isSpendLimitEnabled && coupon.spendLimit) {\n\t\t\t// spend limit\n\n\t\t\tconst { totalCouponDiscount, totalSecondaryCouponDiscount } = await this.getCouponDiscountTotals(\n\t\t\t\tcoupon.code\n\t\t\t);\n\n\t\t\tif (totalCouponDiscount >= coupon.spendLimit) {\n\t\t\t\texpirationReason = CouponExpirationReason.SPEND_LIMIT;\n\t\t\t}\n\t\t}\n\n\t\tawait this.baseCouponModel.findByIdAndUpdate(\n\t\t\tcoupon._id,\n\t\t\t{\n\t\t\t\t$set: {\n\t\t\t\t\texpirationReason,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tnew: true,\n\t\t\t\trunValidators: true,\n\t\t\t}\n\t\t);\n\t}\n\n\tpublic async syncCouponExpiry() {\n\t\tconst coupons = await this.baseCouponModel.find({\n\t\t\tcouponType: { $ne: CouponType.REFERRAL_CODE },\n\t\t\texpirationReason: null,\n\t\t});\n\n\t\tconsole.log(`Syncing expiry for ${coupons.length} coupons`);\n\n\t\tconsole.time('syncCouponExpiry');\n\t\tfor (const coupon of coupons) {\n\t\t\tconsole.time(`Processing coupon ${coupon.code}`);\n\t\t\tawait this.processCouponForExpiry(coupon);\n\t\t\tconsole.timeEnd(`Processing coupon ${coupon.code}`);\n\t\t}\n\t\tconsole.timeEnd('syncCouponExpiry');\n\t}\n\n\tprivate async findCouponByCode(code: string): Promise<DocumentType<Model> | null> {\n\t\tconst coupon = await this.model.findOne({ code: code, updatedVersion: { $exists: false } });\n\t\tif (!coupon) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'NOT_FOUND',\n\t\t\t\tmessage: 'Coupon not found',\n\t\t\t});\n\t\t}\n\t\treturn coupon;\n\t}\n\n\tprivate async getCouponDiscountTotals(couponCode: string) {\n\t\tconst pipeline = [\n\t\t\t{\n\t\t\t\t$match: {\n\t\t\t\t\tstatus: { $ne: RegularOrderStatus.CANCELLED },\n\t\t\t\t\t'adjustedFinance.pricing.couponDiscount': { $gt: 0 },\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t$lookup: {\n\t\t\t\t\tfrom: 'carts',\n\t\t\t\t\tlocalField: 'cart',\n\t\t\t\t\tforeignField: '_id',\n\t\t\t\t\tas: 'cart',\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t$unwind: '$cart',\n\t\t\t},\n\t\t\t{\n\t\t\t\t$match: {\n\t\t\t\t\t'cart.couponCode': couponCode,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t$group: {\n\t\t\t\t\t_id: null,\n\t\t\t\t\ttotalCouponDiscount: {\n\t\t\t\t\t\t$sum: {\n\t\t\t\t\t\t\t$toDouble: {\n\t\t\t\t\t\t\t\t$ifNull: ['$adjustedFinance.pricing.couponDiscount', 0],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\ttotalSecondaryCouponDiscount: {\n\t\t\t\t\t\t$sum: {\n\t\t\t\t\t\t\t$toDouble: {\n\t\t\t\t\t\t\t\t$ifNull: ['$adjustedFinance.pricing.secondaryCouponDiscount', 0],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\n\t\tconst result = await this.orderModel.aggregate(pipeline);\n\n\t\treturn {\n\t\t\ttotalCouponDiscount: result[0]?.totalCouponDiscount ?? 0,\n\t\t\ttotalSecondaryCouponDiscount: result[0]?.totalSecondaryCouponDiscount ?? 0,\n\t\t};\n\t}\n\n\tprivate async assignCouponToUser(user: mongoose.Types.ObjectId, coupon: mongoose.Types.ObjectId) {\n\t\tconst updatedUser = await this.userModel.findByIdAndUpdate(\n\t\t\tuser,\n\t\t\t{\n\t\t\t\t$push: {\n\t\t\t\t\tcoupons: coupon,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tnew: true,\n\t\t\t\trunValidators: true,\n\t\t\t}\n\t\t);\n\t}\n\n\tprivate async assignCouponToMultipleUser(\n\t\tquery: mongoose.FilterQuery<User>,\n\t\tcoupon: mongoose.Types.ObjectId\n\t) {\n\t\tconsole.log('Assigning coupon to multiple users with coupon:', coupon);\n\t\tconst updatedUsers = await this.userModel.updateMany(query, {\n\t\t\t$push: {\n\t\t\t\tcoupons: coupon,\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate async assignCouponToNewUsers(coupon: mongoose.Types.ObjectId) {\n\t\tconsole.log('Assigning coupon to new users', coupon);\n\n\t\tconst newUsers = await couponHelperService.getNewUsers();\n\t\tconst updatedUsers = await this.userModel.updateMany(\n\t\t\t{ _id: { $in: newUsers.map(user => user._id) } },\n\t\t\t{\n\t\t\t\t$push: {\n\t\t\t\t\tcoupons: coupon,\n\t\t\t\t},\n\t\t\t}\n\t\t);\n\t}\n\n\tprivate async removeCouponFromUser(user: mongoose.Types.ObjectId, coupon: mongoose.Types.ObjectId) {\n\t\tconst updatedUser = await this.userModel.findByIdAndUpdate(\n\t\t\tuser,\n\t\t\t{\n\t\t\t\t$pull: {\n\t\t\t\t\tcoupons: coupon,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tnew: true,\n\t\t\t\trunValidators: true,\n\t\t\t}\n\t\t);\n\t}\n\n\tprivate async removeCouponFromMultipleUser(\n\t\tquery: mongoose.FilterQuery<User>,\n\t\tcoupon: mongoose.Types.ObjectId\n\t) {\n\t\tconst updatedUsers = await this.userModel.updateMany(query, {\n\t\t\t$pull: {\n\t\t\t\tcoupons: coupon,\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate throwBadRequest(message: string): never {\n\t\tthrow new TRPCError({\n\t\t\tcode: 'BAD_REQUEST',\n\t\t\tmessage,\n\t\t});\n\t}\n\n\tpublic async addCouponToUser(user: any, couponCode: string): Promise<DocumentType<Model>> {\n\t\tconst coupon = await this.findCouponByCode(couponCode);\n\t\tif (!coupon) {\n\t\t\tthis.throwBadRequest('Coupon not found');\n\t\t}\n\t\tconst isNewUser = await couponHelperService.isNewUser(new mongoose.Types.ObjectId(user));\n\n\t\tif (coupon.couponType == CouponType.REFERRAL_CODE && !isNewUser) {\n\t\t\tthis.throwBadRequest('This coupon is valid for new users only');\n\t\t}\n\n\t\tif (coupon.couponType == CouponType.REFERRAL_CODE) {\n\t\t\tif ((coupon as DocumentType<ReferralCodeCoupon>).referralUser.toString() == user) {\n\t\t\t\tthis.throwBadRequest('You cannot add your own referral code');\n\t\t\t}\n\t\t}\n\n\t\tconst typedCoupon = coupon as DocumentType<BaseCoupon>;\n\n\t\tif (this.isCouponExpired(typedCoupon)) {\n\t\t\tthis.throwBadRequest('This coupon has expired and cannot be added');\n\t\t}\n\n\t\tif (typedCoupon.forNewUserOnly && !isNewUser) {\n\t\t\tthis.throwBadRequest('This coupon is valid for new users only');\n\t\t}\n\n\t\tconst alreadyApplied = await this.hasUserAlreadyAppliedCoupon(user, typedCoupon);\n\t\tif (alreadyApplied) {\n\t\t\tthis.throwBadRequest('Coupon already applied to user');\n\t\t}\n\n\t\tif (typedCoupon.couponType == CouponType.INDIVIDUAL_USER) {\n\t\t\tif (!(typedCoupon as DocumentType<IndividualUserCoupon>).users?.includes(user)) {\n\t\t\t\tthis.throwBadRequest('This coupon is not assigned to this user');\n\t\t\t}\n\t\t}\n\n\t\tawait this.userModel.findByIdAndUpdate(\n\t\t\tuser,\n\t\t\t{ $push: { coupons: typedCoupon._id } },\n\t\t\t{ new: true, runValidators: true }\n\t\t);\n\n\t\treturn coupon;\n\t}\n\n\tprivate async hasUserAlreadyAppliedCoupon(\n\t\tuserId: mongoose.Types.ObjectId,\n\t\tcoupon: DocumentType<BaseCoupon>\n\t): Promise<boolean> {\n\t\tconst couponIds = [coupon._id, ...(coupon.previousVersions ?? []).map(v => v._id)];\n\n\t\tconst user = await this.userModel.exists({\n\t\t\t_id: userId,\n\t\t\tcoupons: { $in: couponIds },\n\t\t});\n\n\t\treturn !!user;\n\t}\n\n\tprivate async exchangeCouponForMultipleUser(\n\t\tquery: mongoose.FilterQuery<User>,\n\t\toldCoupon: mongoose.Types.ObjectId,\n\t\tnewCoupon: mongoose.Types.ObjectId\n\t) {\n\t\tawait this.removeCouponFromMultipleUser(query, oldCoupon);\n\t\tawait this.assignCouponToMultipleUser(query, newCoupon);\n\t}\n\n\tpublic getShareableLink = async (code: string): Promise<ShareableLinkDTO> => {\n\t\tconst secretsService = getLibraries().getSecretsService();\n\t\tconst deepLinkUrl = (await secretsService.getKey('DEEP_LINK_URL')) ?? 'https://link.lyxa.ai';\n\n\t\tconst link = `${deepLinkUrl}/invite/${code}`;\n\n\t\tconst message = `Download Lyxa and explore the wide variety of offerings and benefits! Use my code at checkout to claim a special coupon : ${code}.\n\t\t${link}`;\n\n\t\treturn { link, message };\n\t};\n\n\tpublic async getUserCouponList(data?: Partial<FilterDTO>): Promise<PaginatedResponse<AllCouponsDTO>> {\n\t\ttry {\n\t\t\tlet query = data?.query || {};\n\n\t\t\tif (!query.user) {\n\t\t\t\tbadRequestError('User ID is required in query');\n\t\t\t}\n\n\t\t\tconst select = data?.select || {\n\t\t\t\t_id: 1,\n\t\t\t\t'createdBy.name': 1,\n\t\t\t\t'duration.start': 1,\n\t\t\t\t'duration.end': 1,\n\t\t\t\tcode: 1,\n\t\t\t\tstatus: 1,\n\t\t\t\tcreatedAt: 1,\n\t\t\t\tcouponType: 1,\n\t\t\t};\n\n\t\t\tlet isExpiredField = null;\n\n\t\t\tif (query.status) {\n\t\t\t\tif (query.status === 'expired') {\n\t\t\t\t\tisExpiredField = true;\n\t\t\t\t\tdelete query.status;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (query.createdAt) {\n\t\t\t\t// convert to date range\n\t\t\t\tif ('$gte' in query.createdAt) {\n\t\t\t\t\tquery.createdAt.$gte = new Date(query.createdAt.$gte);\n\t\t\t\t}\n\t\t\t\tif ('$lte' in query.createdAt) {\n\t\t\t\t\tquery.createdAt.$lte = new Date(query.createdAt.$lte);\n\t\t\t\t}\n\t\t\t\tif ('$gt' in query.createdAt) {\n\t\t\t\t\tquery.createdAt.$gt = new Date(query.createdAt.$gt);\n\t\t\t\t}\n\t\t\t\tif ('$lt' in query.createdAt) {\n\t\t\t\t\tquery.createdAt.$lt = new Date(query.createdAt.$lt);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst user = await this.userModel.findById(query.user).select('coupons');\n\t\t\tquery._id = { $in: user?.coupons ?? [] };\n\t\t\tdelete query.user; // remove user from query to avoid issues in aggregation match stage\n\n\t\t\tconst pipeline: any[] = [\n\t\t\t\t{ $match: { ...query, deletedAt: null } }, // Filter by search query\n\t\t\t\t{\n\t\t\t\t\t$lookup: {\n\t\t\t\t\t\t// INNER JOIN on categories\n\t\t\t\t\t\tfrom: 'admins', // Mongoose auto-pluralizes collection names\n\t\t\t\t\t\tlocalField: 'createdBy',\n\t\t\t\t\t\tforeignField: '_id',\n\t\t\t\t\t\tas: 'createdBy',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{ $unwind: { path: '$createdBy', preserveNullAndEmptyArrays: true } }, // Flatten the array\n\t\t\t\t{\n\t\t\t\t\t$addFields: {\n\t\t\t\t\t\tisExpired: {\n\t\t\t\t\t\t\t$cond: {\n\t\t\t\t\t\t\t\tif: {\n\t\t\t\t\t\t\t\t\t$or: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t$and: [\n\t\t\t\t\t\t\t\t\t\t\t\t{ $ifNull: ['$duration.end', false] },\n\t\t\t\t\t\t\t\t\t\t\t\t{ $lt: ['$duration.end', dayjs().toDate()] },\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{ $ifNull: ['$expirationReason', false] },\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tthen: true,\n\t\t\t\t\t\t\t\telse: false,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$match: isExpiredField\n\t\t\t\t\t\t? { isExpired: true }\n\t\t\t\t\t\t: query.status === 'active'\n\t\t\t\t\t\t\t? { isExpired: false }\n\t\t\t\t\t\t\t: {},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$addFields: {\n\t\t\t\t\t\tstatus: {\n\t\t\t\t\t\t\t$cond: {\n\t\t\t\t\t\t\t\tif: { $eq: ['$isExpired', true] },\n\t\t\t\t\t\t\t\tthen: 'expired',\n\t\t\t\t\t\t\t\telse: '$status',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$project: select,\n\t\t\t\t},\n\t\t\t];\n\n\t\t\tif (data?.search?.searchKey) {\n\t\t\t\tconst searchKey = data.search.searchKey;\n\t\t\t\tconst regex = new RegExp(searchKey, 'i'); // case-insensitive search\n\t\t\t\tconst fields = data.search.searchFields?.length ? data.search.searchFields : ['code']; // default field(s) to search in\n\n\t\t\t\tpipeline.push({\n\t\t\t\t\t$match: {\n\t\t\t\t\t\t$or: fields.map(field => ({ [field]: { $regex: regex } })),\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Execute the aggregation with pagination and sorting\n\t\t\tconst results = await paginateAggregation(this.model, pipeline, data?.page, data?.size, data?.sort);\n\n\t\t\treturn results as unknown as PaginatedResponse<AllCouponsDTO>;\n\t\t} catch (err) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'INTERNAL_SERVER_ERROR',\n\t\t\t\tmessage: `err: ${err}`,\n\t\t\t});\n\t\t}\n\t}\n\n\tpublic async addExistingCouponsToNewUser(userId: mongoose.Types.ObjectId) {\n\t\tconst isNewUser = await couponHelperService.isNewUser(userId);\n\n\t\tconst query: any = {\n\t\t\tcouponType: { $in: [CouponType.GLOBAL, CouponType.INDIVIDUAL_STORE, CouponType.SHOPS_CATEGORIES] },\n\t\t\tdeletedAt: null,\n\t\t\texpirationReason: null,\n\t\t\t$or: [\n\t\t\t\t{ 'duration.end': { $gt: dayjs().toDate() } },\n\t\t\t\t{ 'duration.end': { $exists: false } },\n\t\t\t\t{ 'duration.end': null },\n\t\t\t],\n\t\t\tupdatedVersion: { $exists: false },\n\t\t};\n\n\t\tif (!isNewUser) {\n\t\t\tquery.forNewUserOnly = { $ne: true };\n\t\t}\n\n\t\t// assign all coupons that are not expired\n\t\tconst coupons = await this.baseCouponModel.find(query);\n\n\t\tconst couponIds = coupons.map(coupon => coupon._id);\n\n\t\tawait this.userModel.findByIdAndUpdate(\n\t\t\tuserId,\n\t\t\t{\n\t\t\t\t$addToSet: {\n\t\t\t\t\tcoupons: { $each: couponIds },\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tnew: true,\n\t\t\t\trunValidators: true,\n\t\t\t}\n\t\t);\n\t}\n\n\tpublic async getActiveNewUserCoupon(): Promise<DocumentType<BaseCoupon> | null> {\n\t\tconst currentDate = dayjs().toDate();\n\t\tconst activeForNewUserCoupon = await this.baseCouponModel.findOne({\n\t\t\tcouponType: CouponType.GLOBAL,\n\t\t\tforNewUserOnly: true,\n\t\t\tdeletedAt: null,\n\t\t\t$or: [\n\t\t\t\t{\n\t\t\t\t\texpirationReason: { $exists: false },\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\texpirationReason: null,\n\t\t\t\t},\n\t\t\t],\n\t\t\t'duration.end': { $gte: currentDate },\n\t\t\tupdatedVersion: { $exists: false },\n\t\t});\n\n\t\treturn activeForNewUserCoupon;\n\t}\n\n\tpublic async getActiveNewUserCouponWithSecondaryCurrency(): Promise<DocumentType<BaseCoupon> | null> {\n\t\tconst exchangeRate = await getExchangeRate();\n\t\tconst currentDate = dayjs().toDate();\n\n\t\tconst referralSettings = await this.referralSettingsModel.findOne();\n\n\t\tconst secondaryReferralReceiverValue =\n\t\t\treferralSettings?.receiver?.valueType == ValueType.PERCENTAGE\n\t\t\t\t? null\n\t\t\t\t: roundSecondaryCurrency((referralSettings?.receiver?.value ?? 0) * exchangeRate);\n\n\t\tconst secondaryReferralReceiverMinOrderAmount = roundSecondaryCurrency(\n\t\t\t(referralSettings?.receiver?.minimumOrderValue ?? 0) * exchangeRate\n\t\t);\n\n\t\tconst activeForNewUserCoupon = await this.baseCouponModel.aggregate([\n\t\t\t// Match (same as findOne filter)\n\t\t\t{\n\t\t\t\t$match: {\n\t\t\t\t\tcouponType: CouponType.GLOBAL,\n\t\t\t\t\tforNewUserOnly: true,\n\t\t\t\t\tdeletedAt: null,\n\t\t\t\t\t$or: [{ expirationReason: { $exists: false } }, { expirationReason: null }],\n\t\t\t\t\t'duration.end': { $gte: currentDate },\n\t\t\t\t\tupdatedVersion: { $exists: false },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Add computed fields\n\t\t\t{\n\t\t\t\t$addFields: {\n\t\t\t\t\tsecondaryCurrencyValue: {\n\t\t\t\t\t\t$cond: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$eq: ['$valueType', ValueType.PERCENTAGE],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$switch: {\n\t\t\t\t\t\t\t\t\tbranches: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tcase: {\n\t\t\t\t\t\t\t\t\t\t\t\t$eq: ['$couponType', CouponType.REFERRAL_CODE],\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\tthen: secondaryReferralReceiverValue,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\tdefault: getRoundSecondaryCurrencyStage({\n\t\t\t\t\t\t\t\t\t\t$multiply: ['$value', exchangeRate],\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\n\t\t\t\t\tsecondaryCurrencyMaxDiscountLimit: {\n\t\t\t\t\t\t$switch: {\n\t\t\t\t\t\t\tbranches: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tcase: {\n\t\t\t\t\t\t\t\t\t\t$eq: ['$couponType', CouponType.REFERRAL_CODE],\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tthen: null,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tdefault: getRoundSecondaryCurrencyStage({\n\t\t\t\t\t\t\t\t$multiply: ['$maxDiscountLimit', exchangeRate],\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\n\t\t\t\t\tsecondaryCurrencyMinOrderValue: {\n\t\t\t\t\t\t$switch: {\n\t\t\t\t\t\t\tbranches: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tcase: {\n\t\t\t\t\t\t\t\t\t\t$eq: ['$couponType', CouponType.REFERRAL_CODE],\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tthen: secondaryReferralReceiverMinOrderAmount,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tdefault: getRoundSecondaryCurrencyStage({\n\t\t\t\t\t\t\t\t$multiply: ['$minOrderValue', exchangeRate],\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Limit to 1 document (like findOne)\n\t\t\t{ $limit: 1 },\n\t\t]);\n\n\t\treturn activeForNewUserCoupon[0] || null;\n\t}\n\n\tpublic async checkExistingNewUserCoupon(): Promise<CheckExistingNewUserCouponOutputDTO> {\n\t\tconst alreadyActiveForNewUserCoupon = await this.getActiveNewUserCoupon();\n\n\t\tif (alreadyActiveForNewUserCoupon) {\n\t\t\treturn { exists: true };\n\t\t}\n\n\t\treturn { exists: false };\n\t}\n\n\tprivate async getAllOrders(userIds: mongoose.Types.ObjectId[]): Promise<number> {\n\t\treturn await this.orderModel.countDocuments({\n\t\t\tuser: { $in: userIds },\n\t\t\tstatus: { $ne: RegularOrderStatus.CANCELLED },\n\t\t\torderType: OrderType.REGULAR,\n\t\t});\n\t}\n\n\tpublic async handleCouponGiftBox(\n\t\tdeviceId: string,\n\t\tuserId: mongoose.Types.ObjectId | null\n\t): Promise<DocumentType<GlobalCoupon>[]> {\n\t\tconst couponRepository = new CouponRepository();\n\n\t\t// 1. Get all the user id using device id\n\t\tconst allUsers = await this.userModel.find({ deviceId }).select('_id');\n\n\t\t// 2. Make an array using all the user ids\n\t\tconst userIds = allUsers.map(user => user._id);\n\n\t\t// 3. Append the current user id to the array\n\t\tif (userId) {\n\t\t\tuserIds.push(new mongoose.Types.ObjectId(userId));\n\t\t}\n\n\t\t// 4. Check if any user has isNewUserCouponShowed = true\n\t\tconst hasShownCoupon = await this.userModel.exists({\n\t\t\t_id: { $in: userIds },\n\t\t\tisNewUserCouponShowed: true,\n\t\t});\n\n\t\tif (hasShownCoupon) {\n\t\t\t// console.log('At least one user already saw the coupon');\n\t\t\treturn [];\n\t\t}\n\n\t\t// 5. Find how many orders placed by these user ids\n\t\tconst totalOrders = await this.getAllOrders(userIds);\n\n\t\t// 6. Get coupon details\n\t\tconst activeNewUserCoupon = await this.getActiveNewUserCouponWithSecondaryCurrency();\n\t\tif (!activeNewUserCoupon) {\n\t\t\t// notFoundError('No active new user coupon found');\n\t\t\treturn [];\n\t\t}\n\n\t\t// 7. Check the total order quantity less than to order limit per user\n\t\tif (\n\t\t\tactiveNewUserCoupon.isOrderLimitPerUserEnabled &&\n\t\t\ttotalOrders < (activeNewUserCoupon.orderLimitPerUser || 0)\n\t\t) {\n\t\t\t// Update the user document for the new user coupon\n\t\t\t// this.updateNewUserCouponField(userIds);\n\n\t\t\t// Return the coupon details to show in the gift box\n\t\t\treturn couponRepository.addLabelsToCoupons([activeNewUserCoupon]);\n\t\t}\n\n\t\treturn [];\n\t}\n\n\tprivate async updateNewUserCouponField(userIds: mongoose.Types.ObjectId[]): Promise<number> {\n\t\t// Update all the users coupon-shown field\n\t\tconst result = await this.userModel.updateMany(\n\t\t\t{ _id: { $in: userIds } },\n\t\t\t{\n\t\t\t\t$set: {\n\t\t\t\t\tisNewUserCouponShowed: false,\n\t\t\t\t},\n\t\t\t}\n\t\t);\n\n\t\treturn result.modifiedCount;\n\t}\n\n\tpublic async updateCouponGiftBoxShown(userId: mongoose.Types.ObjectId, data: any): Promise<number> {\n\t\t// Get device-id using user-id\n\t\tconst user = await this.userModel.findById(userId);\n\n\t\t// Get all users using device-id\n\t\tconst users = await this.userModel.find({ deviceId: user?.deviceId }).select('_id').lean();\n\n\t\t// Set array of ids\n\t\tconst userIds = users.map(u => u._id);\n\n\t\t// Update all the users coupon-shown field\n\t\tconst result = await this.userModel.updateMany(\n\t\t\t{ _id: { $in: userIds } },\n\t\t\t{\n\t\t\t\t$set: {\n\t\t\t\t\tisNewUserCouponShowed: data.isNewUserGiftBoxShown,\n\t\t\t\t},\n\t\t\t}\n\t\t);\n\n\t\treturn result.modifiedCount;\n\t}\n}\n\nexport const couponService = Container.get(CouponService);\n"]}
|
|
1
|
+
{"version":3,"file":"coupon.service.js","sourceRoot":"/","sources":["modules/coupon/services/coupon.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, { Service } from 'typedi';\nimport { TRPCError } from '@trpc/server';\nimport { DocumentType, mongoose, queryMethod, ReturnModelType } from '@typegoose/typegoose';\nimport {\n\tCart,\n\tCouponModel,\n\tCustomCoupon,\n\tgetCoreUserModel,\n\tGlobalCoupon,\n\tIndividualStoreCoupon,\n\tIndividualUserCoupon,\n\tCoupon as Model,\n\tReferralRewardCoupon,\n\tReferralRewardCouponModel,\n\tRegularOrder,\n\tRegularOrderModel,\n\tShopModel,\n\tShop,\n\tShopsCategoriesCoupon,\n\tUser,\n\tUserModel,\n\tReferralCodeCoupon,\n\tReferralSetting,\n\tReferralSettingModel,\n\tOrder,\n} from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport {\n\tAllCouponsValidationDTO,\n\tCouponValidationOutputDTO,\n\tValidateCouponDTO,\n\tAllCouponsDTO,\n\tCheckExistingNewUserCouponOutputDTO,\n} from '@modules/coupon/validations';\nimport { SoftDeleteModel } from '@lyxa.ai/core/dist/libraries/mongo/plugins/soft-delete-plugin';\nimport {\n\tFilterDTO,\n\tPaginatedResponse,\n\tDeleteDTO,\n\tShareableLinkDTO,\n} from '@lyxa.ai/core/dist/utilities/validation';\nimport {\n\tcreateRawDocumentPaginatorObject,\n\tpaginateAggregation,\n\tPaginatorOptions,\n} from '@lyxa.ai/core/dist/utilities/pagination';\nimport { ModelType } from '@typegoose/typegoose/lib/types';\nimport {\n\tcustomCouponService,\n\tglobalCouponService,\n\tindividualStoreCouponService,\n\tindividualUserCouponService,\n\treferralCodeCouponService,\n\treferralRewardCouponService,\n} from '.';\nimport {\n\tCouponExpirationReason,\n\tCouponType,\n\tItemType,\n\tOrderType,\n\tRegularOrderStatus,\n\tStatus,\n\tValueType,\n} from '@lyxa.ai/core/dist/utilities/enum';\nimport { BaseCoupon, BaseCouponModel } from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport {\n\tPunchMarketingHistoryService,\n\tpunchMarketingHistoryService,\n} from '@modules/punch-marketing-history/services';\nimport { getLibraries } from '@lyxa.ai/core';\nimport { NotificationMicroserviceRouter } from '@lyxa.ai/notification';\nimport { CouponRepository } from './patterns/repository/CouponRepository';\nimport {\n\tbadRequestError,\n\tconflictError,\n\tinternalServerError,\n\tnotFoundError,\n\tnotImplementedError,\n} from '@lyxa.ai/core/dist/utilities/error-common';\nimport { shopsCategoriesCouponService } from './shops-categories-coupon.service';\nimport { CouponHelperService, couponHelperService } from './helper.service';\nimport { Dayjs, dayjs } from '@lyxa.ai/core/dist/utilities/dayjs';\nimport { getExchangeRate } from '@lyxa.ai/core/dist/utilities/currency';\nimport { roundSecondaryCurrency } from '@lyxa.ai/core/dist/utilities/shared';\nimport { getRoundSecondaryCurrencyStage } from '@lyxa.ai/core/dist/utilities/pipelines/common-pipeline-functions';\nimport { Types } from 'mongoose';\n\n@Service()\nexport class CouponService {\n\tprivate model: typeof CouponModel & SoftDeleteModel<Model>;\n\tprivate baseCouponModel: typeof BaseCouponModel & SoftDeleteModel<BaseCoupon>;\n\tprivate userModel: typeof UserModel & SoftDeleteModel<User>;\n\tprivate orderModel: typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\tprivate shopModel: typeof ShopModel & SoftDeleteModel<Shop>;\n\tprivate referralRewardModel: typeof ReferralRewardCouponModel & SoftDeleteModel<ReferralRewardCoupon>;\n\tprivate punchHistoryService: PunchMarketingHistoryService;\n\tprivate _coreUserModel: ReturnType<typeof getCoreUserModel> | null = null;\n\tprivate couponHelper: CouponHelperService;\n\tprivate readonly referralSettingsModel: typeof ReferralSettingModel & SoftDeleteModel<ReferralSetting>;\n\n\tconstructor() {\n\t\tthis.model = CouponModel as typeof CouponModel & SoftDeleteModel<Model>;\n\t\tthis.baseCouponModel = BaseCouponModel as typeof BaseCouponModel & SoftDeleteModel<BaseCoupon>;\n\t\tthis.userModel = UserModel as typeof UserModel & SoftDeleteModel<User>;\n\t\tthis.orderModel = RegularOrderModel as typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\t\tthis.shopModel = ShopModel as typeof ShopModel & SoftDeleteModel<Shop>;\n\t\tthis.referralRewardModel = ReferralRewardCouponModel as typeof ReferralRewardCouponModel &\n\t\t\tSoftDeleteModel<ReferralRewardCoupon>;\n\t\tthis.punchHistoryService = punchMarketingHistoryService;\n\t\tthis.couponHelper = couponHelperService;\n\t\tthis.referralSettingsModel = ReferralSettingModel as typeof ReferralSettingModel &\n\t\t\tSoftDeleteModel<ReferralSetting>;\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: AllCouponsValidationDTO): Promise<DocumentType<Model>> {\n\t\tlet coupon: DocumentType<Model>;\n\n\t\tif (\n\t\t\tdata.couponType != CouponType.REFERRAL_CODE &&\n\t\t\tdata?.duration &&\n\t\t\t!this.couponHelper.isDurationValid(dayjs(data?.duration?.start), dayjs(data?.duration?.end))\n\t\t) {\n\t\t\tconflictError(`Start date/time cannot be in the past `);\n\t\t}\n\n\t\tconst checkCoupon = await this.model.findOne({\n\t\t\tcode: data.code,\n\t\t\tdeletedAt: null,\n\t\t});\n\n\t\tif (checkCoupon) conflictError('Coupon code already exists');\n\n\t\tswitch (data.couponType) {\n\t\t\tcase CouponType.GLOBAL: {\n\t\t\t\tcoupon = await globalCouponService.create(data);\n\t\t\t\tif (coupon) {\n\t\t\t\t\tconst globalCoupon = coupon as DocumentType<GlobalCoupon>;\n\t\t\t\t\tif (!globalCoupon.forNewUserOnly) {\n\t\t\t\t\t\tawait this.assignCouponToMultipleUser({}, coupon._id);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tawait this.assignCouponToNewUsers(coupon._id);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase CouponType.REFERRAL_CODE: {\n\t\t\t\tcoupon = await referralCodeCouponService.create(data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase CouponType.REFERRAL_REWARD: {\n\t\t\t\tcoupon = await referralRewardCouponService.create(data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase CouponType.SHOPS_CATEGORIES: {\n\t\t\t\tcoupon = await shopsCategoriesCouponService.create(data);\n\t\t\t\tif (coupon) {\n\t\t\t\t\tconst shopsCategoriesCoupon = coupon as DocumentType<ShopsCategoriesCoupon>;\n\t\t\t\t\tif (!shopsCategoriesCoupon.forNewUserOnly) {\n\t\t\t\t\t\tawait this.assignCouponToMultipleUser({}, coupon._id);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tawait this.assignCouponToNewUsers(coupon._id);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase CouponType.INDIVIDUAL_STORE: {\n\t\t\t\tcoupon = await individualStoreCouponService.create(data);\n\t\t\t\tif (coupon) {\n\t\t\t\t\tconst individualStoreCoupon = coupon as DocumentType<IndividualStoreCoupon>;\n\t\t\t\t\tif (!individualStoreCoupon.forNewUserOnly) {\n\t\t\t\t\t\tawait this.assignCouponToMultipleUser({}, coupon._id);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tawait this.assignCouponToNewUsers(coupon._id);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase CouponType.INDIVIDUAL_USER: {\n\t\t\t\tcoupon = await individualUserCouponService.create(data);\n\t\t\t\tif (coupon) {\n\t\t\t\t\tconst individualUserCoupon = coupon as DocumentType<IndividualUserCoupon>;\n\t\t\t\t\tconst users = individualUserCoupon.users;\n\t\t\t\t\tawait this.assignCouponToMultipleUser({ _id: { $in: users } }, coupon._id);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase CouponType.CUSTOM_COUPON: {\n\t\t\t\tcoupon = await customCouponService.create(data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tbadRequestError('Coupon type is not valid');\n\t\t\t}\n\t\t}\n\n\t\tif (!coupon) internalServerError('Could not create coupon');\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(coupon._id);\n\n\t\treturn coupon;\n\t}\n\n\t/**\n\t * Get record by ID\n\t * @param id ID of the record\n\t */\n\tpublic async findById(id: string | mongoose.Types.ObjectId): Promise<DocumentType<Model>> {\n\t\tconst result = await this.model\n\t\t\t.findOne({\n\t\t\t\t_id: id,\n\t\t\t\tdeletedAt: null,\n\t\t\t})\n\t\t\t.populate([\n\t\t\t\t{\n\t\t\t\t\tpath: 'previousVersions',\n\t\t\t\t},\n\t\t\t]);\n\t\tif (!result) {\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\t\treturn result;\n\t}\n\n\t/**\n\t * Get records\n\t * @param query Query to find records\n\t */\n\tpublic async find(data?: Partial<FilterDTO>): Promise<PaginatedResponse<DocumentType<ModelType<Model>>>> {\n\t\ttry {\n\t\t\tconst populate = [\n\t\t\t\t...data?.populate,\n\t\t\t\t{\n\t\t\t\t\tpath: 'users',\n\t\t\t\t\tpopulate: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpath: 'coreUser',\n\t\t\t\t\t\t\tmodel: this.coreUserModel,\n\t\t\t\t\t\t\tselect: 'name profilePhoto -_id',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tselect: 'coreUser phoneNumber',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tpath: 'influencer',\n\t\t\t\t\tpopulate: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpath: 'coreUser',\n\t\t\t\t\t\t\tmodel: this.coreUserModel,\n\t\t\t\t\t\t\tselect: 'name profilePhoto -_id',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tselect: 'coreUser phoneNumber',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tpath: 'referralUser',\n\t\t\t\t\tpopulate: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpath: 'coreUser',\n\t\t\t\t\t\t\tmodel: this.coreUserModel,\n\t\t\t\t\t\t\tselect: 'name profilePhoto -_id',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tselect: 'coreUser phoneNumber',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tpath: 'user',\n\t\t\t\t\tpopulate: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpath: 'coreUser',\n\t\t\t\t\t\t\tmodel: this.coreUserModel,\n\t\t\t\t\t\t\tselect: 'name profilePhoto -_id',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tselect: 'coreUser phoneNumber',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\tpath: 'referralCodeUsedBy',\n\t\t\t\t\tpopulate: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tpath: 'coreUser',\n\t\t\t\t\t\t\tmodel: this.coreUserModel,\n\t\t\t\t\t\t\tselect: 'name profilePhoto -_id',\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tselect: 'coreUser phoneNumber',\n\t\t\t\t},\n\t\t\t];\n\n\t\t\tconst paginate = createRawDocumentPaginatorObject(this.model as ReturnModelType<typeof this.model>);\n\t\t\tconst options: PaginatorOptions<typeof Model> = {\n\t\t\t\tpage: data?.page,\n\t\t\t\tsize: data?.size,\n\t\t\t\tsort: data?.sort,\n\t\t\t\tquery: { ...data?.query, updatedVersion: { $exists: false } },\n\t\t\t\tselect: data?.select,\n\t\t\t\tpopulate: populate,\n\t\t\t};\n\n\t\t\tif (data?.search?.searchKey) {\n\t\t\t\tconst keyword = data.search.searchKey.trim();\n\t\t\t\tconst defaultFields = ['code', 'user'];\n\t\t\t\tconst fields = data.search.searchFields || defaultFields;\n\n\t\t\t\tconst orConditions: Record<string, any>[] = [];\n\n\t\t\t\t// For coupons search by code\n\t\t\t\tif (fields.includes('code')) {\n\t\t\t\t\torConditions.push({ code: { $regex: keyword, $options: 'i' } });\n\t\t\t\t}\n\n\t\t\t\t// For users search\n\t\t\t\tif (fields.includes('user')) {\n\t\t\t\t\t// First search core users by name\n\t\t\t\t\tconst coreUsers = await this.coreUserModel\n\t\t\t\t\t\t.find({ name: { $regex: keyword, $options: 'i' } })\n\t\t\t\t\t\t.select('_id');\n\t\t\t\t\tconst coreUserIds = coreUsers.map(u => u._id);\n\n\t\t\t\t\t// Get corresponding user IDs from core users\n\t\t\t\t\tconst users = await this.userModel.find({ coreUser: { $in: coreUserIds } }).select('_id');\n\t\t\t\t\tconst userIds = users.map(u => u._id); // new Types.ObjectId(u._id.toString())\n\t\t\t\t\tif (userIds.length) orConditions.push({ users: { $in: userIds } }, { user: { $in: userIds } });\n\t\t\t\t}\n\n\t\t\t\t// Merge into main query\n\t\t\t\tif (orConditions.length) {\n\t\t\t\t\toptions.query = { ...options.query, $or: orConditions };\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst paginatedResult = await paginate(options);\n\n\t\t\t// for each document, count the number of orders that have used the coupon and add usedCount field to the document\n\t\t\tpaginatedResult.documents = await Promise.all(\n\t\t\t\tpaginatedResult.documents.map(async (doc: any) => {\n\t\t\t\t\tconst plainDoc = doc.toObject();\n\t\t\t\t\tconst allIds = [plainDoc._id, ...(plainDoc.previousVersions || []).filter(Boolean)];\n\n\t\t\t\t\tconst count = await this.orderModel.countDocuments({\n\t\t\t\t\t\t'adjustedFinance.coupon.coupon': { $in: allIds },\n\t\t\t\t\t\tstatus: RegularOrderStatus.DELIVERED,\n\t\t\t\t\t});\n\n\t\t\t\t\treturn { ...plainDoc, usedCount: count };\n\t\t\t\t})\n\t\t\t);\n\n\t\t\treturn paginatedResult;\n\t\t} catch (err) {\n\t\t\tinternalServerError(`err: ${err}`);\n\t\t}\n\t}\n\n\t/**\n\t * Update record\n\t * @param id ID of the old coupon\n\t * @param data Data of the updated coupon\n\t */\n\tpublic async update(id: string, data: AllCouponsValidationDTO): Promise<DocumentType<Model>> {\n\t\tlet coupon: DocumentType<BaseCoupon> | null;\n\n\t\tconst [oldCoupon, checkCouponCode, usersWithOldCoupon] = await Promise.all([\n\t\t\tthis.baseCouponModel.findById(id),\n\t\t\tthis.model.findOne({\n\t\t\t\tcode: data.code,\n\t\t\t\t_id: { $ne: id },\n\t\t\t\tupdatedVersion: { $exists: false },\n\t\t\t}),\n\t\t\tthis.userModel\n\t\t\t\t.find({\n\t\t\t\t\tcoupons: new mongoose.Types.ObjectId(id),\n\t\t\t\t})\n\t\t\t\t.select(['_id', 'coupons']),\n\t\t]);\n\n\t\tif (!oldCoupon) {\n\t\t\tnotFoundError('Coupon not found');\n\t\t}\n\n\t\tconst running = this.isCouponRunning(oldCoupon);\n\n\t\t// Overlapping start date of payload\n\t\tif (running && data && 'duration' in data && data.duration) {\n\t\t\tdata.duration.start = oldCoupon.duration.start;\n\t\t} else {\n\t\t\tif (data.couponType !== CouponType.REFERRAL_CODE && dayjs(data?.duration?.start).isBefore(dayjs())) {\n\t\t\t\tbadRequestError(`Start date/time cannot be earlier than the current time`);\n\t\t\t}\n\t\t}\n\n\t\tif (\n\t\t\tdata.couponType != CouponType.REFERRAL_CODE &&\n\t\t\tdata?.duration &&\n\t\t\tdayjs(data?.duration?.start) > dayjs(data?.duration.end)\n\t\t) {\n\t\t\tbadRequestError(`End date/time must be after start date/time`);\n\t\t}\n\n\t\tif (checkCouponCode) {\n\t\t\tconflictError(`Coupon code already exists`);\n\t\t}\n\n\t\tswitch (data.couponType) {\n\t\t\tcase CouponType.GLOBAL: {\n\t\t\t\tcoupon = await globalCouponService.create(data);\n\t\t\t\tif (coupon) {\n\t\t\t\t\tconst globalCoupon = coupon as DocumentType<GlobalCoupon>;\n\t\t\t\t\tif (!globalCoupon.forNewUserOnly) {\n\t\t\t\t\t\tawait this.exchangeCouponForMultipleUser(\n\t\t\t\t\t\t\t{ _id: { $in: usersWithOldCoupon?.map(u => u._id) } },\n\t\t\t\t\t\t\toldCoupon._id,\n\t\t\t\t\t\t\tcoupon._id\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase CouponType.SHOPS_CATEGORIES: {\n\t\t\t\tcoupon = await shopsCategoriesCouponService.create(data);\n\t\t\t\tif (coupon) {\n\t\t\t\t\tconst shopsCategoriesCoupon = coupon as DocumentType<ShopsCategoriesCoupon>;\n\t\t\t\t\tif (!shopsCategoriesCoupon.forNewUserOnly) {\n\t\t\t\t\t\tawait this.exchangeCouponForMultipleUser(\n\t\t\t\t\t\t\t{ _id: { $in: usersWithOldCoupon?.map(u => u._id) } },\n\t\t\t\t\t\t\toldCoupon._id,\n\t\t\t\t\t\t\tshopsCategoriesCoupon._id\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase CouponType.INDIVIDUAL_STORE: {\n\t\t\t\tcoupon = await individualStoreCouponService.create(data);\n\t\t\t\tif (coupon) {\n\t\t\t\t\tconst individualStoreCoupon = coupon as DocumentType<IndividualStoreCoupon>;\n\t\t\t\t\tif (!individualStoreCoupon.forNewUserOnly) {\n\t\t\t\t\t\tawait this.exchangeCouponForMultipleUser(\n\t\t\t\t\t\t\t{ _id: { $in: usersWithOldCoupon?.map(u => u._id) } },\n\t\t\t\t\t\t\toldCoupon._id,\n\t\t\t\t\t\t\tindividualStoreCoupon._id\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase CouponType.INDIVIDUAL_USER: {\n\t\t\t\tcoupon = await individualUserCouponService.create(data);\n\t\t\t\tif (coupon) {\n\t\t\t\t\tconst individualUserCoupon = coupon as DocumentType<IndividualUserCoupon>;\n\t\t\t\t\tawait this.removeCouponFromMultipleUser(\n\t\t\t\t\t\t{ _id: { $in: usersWithOldCoupon?.map(u => u._id) } },\n\t\t\t\t\t\toldCoupon._id\n\t\t\t\t\t);\n\t\t\t\t\tawait this.assignCouponToMultipleUser(\n\t\t\t\t\t\t{ _id: { $in: individualUserCoupon.users } },\n\t\t\t\t\t\tindividualUserCoupon._id\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tcase CouponType.CUSTOM_COUPON: {\n\t\t\t\tcoupon = await customCouponService.create(data);\n\t\t\t\tif (coupon) {\n\t\t\t\t\tconst customCoupon = coupon as DocumentType<CustomCoupon>;\n\t\t\t\t\tif (!customCoupon.forNewUserOnly) {\n\t\t\t\t\t\tawait this.exchangeCouponForMultipleUser(\n\t\t\t\t\t\t\t{ _id: { $in: usersWithOldCoupon?.map(u => u._id) } },\n\t\t\t\t\t\t\toldCoupon._id,\n\t\t\t\t\t\t\tcoupon._id\n\t\t\t\t\t\t);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\tbreak;\n\t\t\t}\n\t\t\tdefault: {\n\t\t\t\tbadRequestError(`Invalid coupon type`);\n\t\t\t}\n\t\t}\n\n\t\tif (!coupon) {\n\t\t\tbadRequestError(`Could not create updated coupon`);\n\t\t}\n\n\t\t// add previous version to new coupon\n\t\tconst previousVersions = oldCoupon?.previousVersions || [];\n\t\tpreviousVersions.push(oldCoupon._id);\n\n\t\tconst updatedCoupon = await this.baseCouponModel.findByIdAndUpdate(\n\t\t\tcoupon._id,\n\t\t\t{\n\t\t\t\t$set: {\n\t\t\t\t\tpreviousVersions,\n\t\t\t\t},\n\t\t\t},\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 (!updatedCoupon) {\n\t\t\tinternalServerError(`Could not set previous versions of coupon`);\n\t\t}\n\n\t\t// update old coupon\n\t\tconst updatedOldCoupon = await this.baseCouponModel.findByIdAndUpdate(\n\t\t\toldCoupon._id,\n\t\t\t{\n\t\t\t\t$set: {\n\t\t\t\t\tupdatedVersion: coupon._id,\n\t\t\t\t\t'duration.end': coupon.duration.end,\n\t\t\t\t},\n\t\t\t},\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\treturn updatedCoupon;\n\t}\n\n\tprivate isCouponRunning(coupon: any): boolean {\n\t\tconst now = new Date();\n\n\t\tconst start = new Date(coupon.duration.start);\n\t\tconst end = new Date(coupon.duration.end);\n\n\t\treturn coupon.status === 'active' && coupon.deletedAt === null && now >= start && now <= end;\n\t}\n\n\tpublic async updateStatus(id: string, status: Status): Promise<DocumentType<Model>> {\n\t\tconst coupon = await this.baseCouponModel.findByIdAndUpdate(\n\t\t\tid,\n\t\t\t{\n\t\t\t\t$set: { status },\n\t\t\t},\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 (!coupon) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'NOT_FOUND',\n\t\t\t\tmessage: 'Coupon not found',\n\t\t\t});\n\t\t}\n\n\t\t// also update the status of previous versions of the coupon\n\t\tconst previousVersions = coupon.previousVersions;\n\t\tif (previousVersions && previousVersions.length > 0) {\n\t\t\tawait this.baseCouponModel.updateMany(\n\t\t\t\t{ _id: { $in: previousVersions } },\n\t\t\t\t{\n\t\t\t\t\t$set: { status },\n\t\t\t\t}\n\t\t\t);\n\t\t}\n\n\t\treturn coupon;\n\t}\n\n\t/**\n\t * Delete record\n\t * @param data Data for delete\n\t */\n\tpublic async deleteById(data: DeleteDTO): Promise<string> {\n\t\tconst { _id, softDelete } = data;\n\n\t\tconst coupon = await this.model.findById(_id);\n\n\t\tif (!coupon) {\n\t\t\tnotFoundError('Coupon not found');\n\t\t}\n\n\t\tconst result = await this.model.deleteRecord({ _id, deletedAt: null }, softDelete);\n\t\tif (!result) {\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\t// remove coupons from users' coupon lists\n\t\tthis.removeCouponFromMultipleUser({}, _id);\n\n\t\t// also delete previous versions of the coupon\n\t\tconst previousVersions = coupon.previousVersions;\n\t\tif (previousVersions && previousVersions.length > 0) {\n\t\t\tawait this.model.deleteRecord({ _id: { $in: previousVersions }, deletedAt: null }, softDelete);\n\t\t}\n\n\t\treturn 'Record deleted successfully';\n\t}\n\n\t/**\n\t * Get User Coupons\n\t * @param data User and pagination data\n\t */\n\tpublic async getUserCoupons(\n\t\tuser: mongoose.Types.ObjectId | undefined,\n\t\tshop: mongoose.Types.ObjectId | undefined,\n\t\tpage: number = 0,\n\t\tsize: number = 0\n\t): Promise<{\n\t\tavailable: Array<DocumentType<Model>>;\n\t\tused: Array<DocumentType<Model>>;\n\t\texpired: Array<DocumentType<Model>>;\n\t}> {\n\t\tconst couponRepository = new CouponRepository();\n\t\tlet itemType: ItemType | undefined = undefined;\n\t\tif (shop) {\n\t\t\tconst shopDocument = await this.shopModel.findOne({ _id: shop }).select('itemType');\n\t\t\titemType = shopDocument?.itemType;\n\t\t}\n\t\tconst coupons = await couponRepository.getUserCoupons(user, shop, itemType);\n\n\t\tif (shop && user) {\n\t\t\tconst punch = await this.punchHistoryService.getPunchCoupon(user, shop);\n\t\t\tif (punch) {\n\t\t\t\tcoupons.available.push(punch);\n\t\t\t}\n\t\t}\n\n\t\treturn couponRepository.addLabelsToAllCoupons(coupons);\n\t}\n\n\tpublic async validateCoupon(data: ValidateCouponDTO): Promise<CouponValidationOutputDTO> {\n\t\tif (data.coupon === 'punch') {\n\t\t\treturn await punchMarketingHistoryService.getPunchDiscount(data);\n\t\t}\n\n\t\tconst user = await this.userModel.findById(data.user);\n\t\tif (!user) notFoundError('User not found');\n\n\t\tlet coupon = await this.model\n\t\t\t.findOne({\n\t\t\t\tcode: data.coupon,\n\t\t\t\t_id: { $in: user.coupons ?? [] },\n\t\t\t\tstatus: { $in: [Status.ACTIVE, null] },\n\t\t\t})\n\t\t\t.populate('shops', '_id name');\n\n\t\tif (!coupon) {\n\t\t\tcoupon = await this.model\n\t\t\t\t.findOne({\n\t\t\t\t\tcode: data.coupon,\n\t\t\t\t\tstatus: { $in: [Status.ACTIVE, null] },\n\t\t\t\t\tcouponType: { $in: [CouponType.REFERRAL_CODE, CouponType.CUSTOM_COUPON] },\n\t\t\t\t\tupdatedVersion: { $exists: false },\n\t\t\t\t})\n\t\t\t\t.populate('shops', '_id name');\n\n\t\t\tif (!coupon) {\n\t\t\t\tnotFoundError('Coupon not found');\n\t\t\t}\n\n\t\t\t// add coupon to user list if it's referral code or custom coupon and not already added\n\t\t\tthis.userModel.findByIdAndUpdate(user._id, {\n\t\t\t\t$addToSet: { coupons: coupon._id },\n\t\t\t});\n\t\t}\n\n\t\tif (coupon.couponType == CouponType.REFERRAL_CODE) {\n\t\t\treturn await referralCodeCouponService.validateCoupon(data, coupon as DocumentType<ReferralCodeCoupon>);\n\t\t}\n\n\t\tconst baseCoupon = coupon as DocumentType<BaseCoupon>;\n\n\t\tconst { isValid, invalidMessage } = await this.validateBaseCoupon(\n\t\t\tbaseCoupon,\n\t\t\tuser._id,\n\t\t\tdata.amountBeforeCoupon,\n\t\t\tBoolean(data.scheduledAt) ? dayjs(data.scheduledAt) : undefined\n\t\t);\n\n\t\tif (!isValid) {\n\t\t\treturn {\n\t\t\t\tisValid,\n\t\t\t\tmessage: invalidMessage,\n\t\t\t};\n\t\t}\n\n\t\tswitch (coupon.couponType) {\n\t\t\tcase CouponType.REFERRAL_REWARD:\n\t\t\t\treturn await referralRewardCouponService.validateCoupon(\n\t\t\t\t\tdata,\n\t\t\t\t\tcoupon as DocumentType<ReferralRewardCoupon>\n\t\t\t\t);\n\t\t\tcase CouponType.GLOBAL:\n\t\t\t\treturn await globalCouponService.validateCoupon(data, coupon as DocumentType<GlobalCoupon>);\n\t\t\tcase CouponType.SHOPS_CATEGORIES:\n\t\t\t\treturn await shopsCategoriesCouponService.validateCoupon(\n\t\t\t\t\tdata,\n\t\t\t\t\tcoupon as DocumentType<ShopsCategoriesCoupon>\n\t\t\t\t);\n\t\t\tcase CouponType.INDIVIDUAL_STORE:\n\t\t\t\treturn await individualStoreCouponService.validateCoupon(\n\t\t\t\t\tdata,\n\t\t\t\t\tcoupon as DocumentType<IndividualStoreCoupon>\n\t\t\t\t);\n\t\t\tcase CouponType.INDIVIDUAL_USER:\n\t\t\t\treturn await individualUserCouponService.validateCoupon(\n\t\t\t\t\tdata,\n\t\t\t\t\tcoupon as DocumentType<IndividualUserCoupon>\n\t\t\t\t);\n\t\t\tcase CouponType.CUSTOM_COUPON:\n\t\t\t\treturn await customCouponService.validateCoupon(data, coupon as DocumentType<CustomCoupon>);\n\t\t\tdefault:\n\t\t\t\tnotImplementedError(`Validation not implemented for ${coupon.couponType} coupons`);\n\t\t}\n\t}\n\n\tprivate isCouponExpired(coupon: DocumentType<BaseCoupon>): Boolean {\n\t\tif (coupon.expirationReason || (coupon?.duration?.end && new Date(coupon?.duration?.end) < new Date())) {\n\t\t\treturn true;\n\t\t}\n\t\treturn false;\n\t}\n\n\t/**\n\t *\n\t * @param coupon Base coupon document\n\t * @param user ID of the user trying to user the coupon\n\t * @param orderAmount Order subtotal\n\t * @returns True if coupon is valid\n\t */\n\tprivate async validateBaseCoupon(\n\t\tcoupon: DocumentType<BaseCoupon>,\n\t\tuser: mongoose.Types.ObjectId,\n\t\torderAmount: number,\n\t\tscheduledAt: Dayjs | undefined = undefined\n\t): Promise<{ isValid: boolean; invalidMessage?: string }> {\n\t\tconst invalidConditions = [\n\t\t\tthis.isCouponExpired(coupon), // check coupon expired\n\t\t\tcoupon.duration.start > dayjs().toDate(), // check coupon start\n\t\t\tcoupon.isMinOrderValueEnabled && coupon.minOrderValue && orderAmount < coupon.minOrderValue, // check minimum order value\n\t\t\tcoupon.forNewUserOnly && !(await this.verifyNewUserConditions(coupon, user)), // check if new user\n\t\t\tcoupon.isOrderLimitPerUserEnabled &&\n\t\t\t\tcoupon.orderLimitPerUser &&\n\t\t\t\t(await this.getCouponOrdersForUser(user, coupon.code)) >= coupon.orderLimitPerUser, // check order limit for user\n\t\t\tscheduledAt && Boolean(coupon.duration.end) && dayjs(coupon.duration.end).isBefore(scheduledAt), // check scheduledAt is before coupon end date\n\t\t];\n\n\t\tconst invalidMessages = [\n\t\t\t'This coupon is expired',\n\t\t\t'This coupon is not available yet',\n\t\t\t// 'The minimum order amount for this coupon is not met',\n\t\t\t`Minimum order amount ${coupon.minOrderValue}$ is not met!`,\n\t\t\t'This coupon is for new users only',\n\t\t\t'You have reached the order limit for this coupon',\n\t\t\t'This coupon is not valid for this scheduled orders',\n\t\t];\n\n\t\tconst isValid = invalidConditions.every(value => Boolean(value) == false);\n\t\tconst invalidMessage = invalidMessages.filter((_, index) => invalidConditions[index])?.[0];\n\n\t\treturn { isValid, invalidMessage };\n\t}\n\n\t// Returns true if new user conditions are met. False otherwise\n\tprivate async verifyNewUserConditions(\n\t\tcoupon: DocumentType<BaseCoupon>,\n\t\tuser: mongoose.Types.ObjectId\n\t): Promise<boolean> {\n\t\tconst forNewUserOnly = coupon.forNewUserOnly;\n\t\tconst isOrderLimitPerUserEnabled = coupon.isOrderLimitPerUserEnabled;\n\t\tconst orderLimitPerUser = coupon.orderLimitPerUser;\n\n\t\tif (forNewUserOnly) {\n\t\t\tif (isOrderLimitPerUserEnabled && orderLimitPerUser) {\n\t\t\t\tconst orderCount = await couponHelperService.getSameDeviceOrdersWithCoupon(user, coupon);\n\t\t\t\treturn orderLimitPerUser > orderCount;\n\t\t\t}\n\t\t\treturn await couponHelperService.isNewUser(user);\n\t\t}\n\n\t\treturn true;\n\t}\n\n\tprivate async getCouponOrdersForUser(user: mongoose.Types.ObjectId, couponCode: string): Promise<number> {\n\t\tconst orders = (await this.orderModel\n\t\t\t.find({\n\t\t\t\tuser: user,\n\t\t\t\tstatus: { $ne: RegularOrderStatus.CANCELLED },\n\t\t\t\torderType: OrderType.REGULAR,\n\t\t\t})\n\t\t\t.populate([{ path: 'cart' }])) as Array<DocumentType<RegularOrder> & { cart: DocumentType<Cart> }>;\n\n\t\tconst count = orders.filter(order => order.cart.couponCode == couponCode).length;\n\n\t\treturn count;\n\t}\n\n\tpublic async handleCouponExpiry(couponId: mongoose.Types.ObjectId) {\n\t\tconst coupon = await this.model.findById(couponId);\n\t\tif (!coupon || coupon.couponType == CouponType.REFERRAL_CODE) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst typedCoupon = coupon as DocumentType<BaseCoupon>;\n\t\tawait this.processCouponForExpiry(typedCoupon);\n\t}\n\n\tprivate async processCouponForExpiry(coupon: DocumentType<BaseCoupon>) {\n\t\tlet expirationReason: string | null = null;\n\n\t\tif (coupon.isTotalOrderLimitEnabled && coupon.totalOrderLimit) {\n\t\t\t// find the order count by aggregating the order collection,\n\t\t\t// checking orders that have adjustedFinance.pricing.couponDiscount > 0,\n\t\t\t// populating cart collection to match coupon code\n\n\t\t\tconst pipeline = [\n\t\t\t\t{\n\t\t\t\t\t$match: {\n\t\t\t\t\t\tstatus: { $ne: RegularOrderStatus.CANCELLED },\n\t\t\t\t\t\t'adjustedFinance.pricing.couponDiscount': { $gt: 0 },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$lookup: {\n\t\t\t\t\t\tfrom: 'carts',\n\t\t\t\t\t\tlocalField: 'cart',\n\t\t\t\t\t\tforeignField: '_id',\n\t\t\t\t\t\tas: 'cart',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$unwind: '$cart',\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$match: {\n\t\t\t\t\t\t'cart.couponCode': coupon.code,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$count: 'orderCount',\n\t\t\t\t},\n\t\t\t];\n\t\t\tconst result = await this.orderModel.aggregate(pipeline);\n\t\t\tconst orderCount = result[0]?.orderCount ?? 0;\n\n\t\t\tif (orderCount >= coupon.totalOrderLimit) {\n\t\t\t\texpirationReason = CouponExpirationReason.TOTAL_ORDER_LIMIT;\n\t\t\t}\n\t\t}\n\t\tif (coupon.isSpendLimitEnabled && coupon.spendLimit) {\n\t\t\t// spend limit\n\n\t\t\tconst { totalCouponDiscount, totalSecondaryCouponDiscount } = await this.getCouponDiscountTotals(\n\t\t\t\tcoupon.code\n\t\t\t);\n\n\t\t\tif (totalCouponDiscount >= coupon.spendLimit) {\n\t\t\t\texpirationReason = CouponExpirationReason.SPEND_LIMIT;\n\t\t\t}\n\t\t}\n\n\t\tawait this.baseCouponModel.findByIdAndUpdate(\n\t\t\tcoupon._id,\n\t\t\t{\n\t\t\t\t$set: {\n\t\t\t\t\texpirationReason,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tnew: true,\n\t\t\t\trunValidators: true,\n\t\t\t}\n\t\t);\n\t}\n\n\tpublic async syncCouponExpiry() {\n\t\tconst coupons = await this.baseCouponModel.find({\n\t\t\tcouponType: { $ne: CouponType.REFERRAL_CODE },\n\t\t\texpirationReason: null,\n\t\t});\n\n\t\tconsole.log(`Syncing expiry for ${coupons.length} coupons`);\n\n\t\tconsole.time('syncCouponExpiry');\n\t\tfor (const coupon of coupons) {\n\t\t\tconsole.time(`Processing coupon ${coupon.code}`);\n\t\t\tawait this.processCouponForExpiry(coupon);\n\t\t\tconsole.timeEnd(`Processing coupon ${coupon.code}`);\n\t\t}\n\t\tconsole.timeEnd('syncCouponExpiry');\n\t}\n\n\tprivate async findCouponByCode(code: string): Promise<DocumentType<Model> | null> {\n\t\tconst coupon = await this.model.findOne({ code: code, updatedVersion: { $exists: false } });\n\t\tif (!coupon) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'NOT_FOUND',\n\t\t\t\tmessage: 'Coupon not found',\n\t\t\t});\n\t\t}\n\t\treturn coupon;\n\t}\n\n\tprivate async getCouponDiscountTotals(couponCode: string) {\n\t\tconst pipeline = [\n\t\t\t{\n\t\t\t\t$match: {\n\t\t\t\t\tstatus: { $ne: RegularOrderStatus.CANCELLED },\n\t\t\t\t\t'adjustedFinance.pricing.couponDiscount': { $gt: 0 },\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t$lookup: {\n\t\t\t\t\tfrom: 'carts',\n\t\t\t\t\tlocalField: 'cart',\n\t\t\t\t\tforeignField: '_id',\n\t\t\t\t\tas: 'cart',\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t$unwind: '$cart',\n\t\t\t},\n\t\t\t{\n\t\t\t\t$match: {\n\t\t\t\t\t'cart.couponCode': couponCode,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\t$group: {\n\t\t\t\t\t_id: null,\n\t\t\t\t\ttotalCouponDiscount: {\n\t\t\t\t\t\t$sum: {\n\t\t\t\t\t\t\t$toDouble: {\n\t\t\t\t\t\t\t\t$ifNull: ['$adjustedFinance.pricing.couponDiscount', 0],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t\ttotalSecondaryCouponDiscount: {\n\t\t\t\t\t\t$sum: {\n\t\t\t\t\t\t\t$toDouble: {\n\t\t\t\t\t\t\t\t$ifNull: ['$adjustedFinance.pricing.secondaryCouponDiscount', 0],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\n\t\tconst result = await this.orderModel.aggregate(pipeline);\n\n\t\treturn {\n\t\t\ttotalCouponDiscount: result[0]?.totalCouponDiscount ?? 0,\n\t\t\ttotalSecondaryCouponDiscount: result[0]?.totalSecondaryCouponDiscount ?? 0,\n\t\t};\n\t}\n\n\tprivate async assignCouponToUser(user: mongoose.Types.ObjectId, coupon: mongoose.Types.ObjectId) {\n\t\tconst updatedUser = await this.userModel.findByIdAndUpdate(\n\t\t\tuser,\n\t\t\t{\n\t\t\t\t$push: {\n\t\t\t\t\tcoupons: coupon,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tnew: true,\n\t\t\t\trunValidators: true,\n\t\t\t}\n\t\t);\n\t}\n\n\tprivate async assignCouponToMultipleUser(\n\t\tquery: mongoose.FilterQuery<User>,\n\t\tcoupon: mongoose.Types.ObjectId\n\t) {\n\t\tconsole.log('Assigning coupon to multiple users with coupon:', coupon);\n\t\tconst updatedUsers = await this.userModel.updateMany(query, {\n\t\t\t$push: {\n\t\t\t\tcoupons: coupon,\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate async assignCouponToNewUsers(coupon: mongoose.Types.ObjectId) {\n\t\tconsole.log('Assigning coupon to new users', coupon);\n\n\t\tconst newUsers = await couponHelperService.getNewUsers();\n\t\tconst updatedUsers = await this.userModel.updateMany(\n\t\t\t{ _id: { $in: newUsers.map(user => user._id) } },\n\t\t\t{\n\t\t\t\t$push: {\n\t\t\t\t\tcoupons: coupon,\n\t\t\t\t},\n\t\t\t}\n\t\t);\n\t}\n\n\tprivate async removeCouponFromUser(user: mongoose.Types.ObjectId, coupon: mongoose.Types.ObjectId) {\n\t\tconst updatedUser = await this.userModel.findByIdAndUpdate(\n\t\t\tuser,\n\t\t\t{\n\t\t\t\t$pull: {\n\t\t\t\t\tcoupons: coupon,\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tnew: true,\n\t\t\t\trunValidators: true,\n\t\t\t}\n\t\t);\n\t}\n\n\tprivate async removeCouponFromMultipleUser(\n\t\tquery: mongoose.FilterQuery<User>,\n\t\tcoupon: mongoose.Types.ObjectId\n\t) {\n\t\tconst updatedUsers = await this.userModel.updateMany(query, {\n\t\t\t$pull: {\n\t\t\t\tcoupons: coupon,\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate throwBadRequest(message: string): never {\n\t\tthrow new TRPCError({\n\t\t\tcode: 'BAD_REQUEST',\n\t\t\tmessage,\n\t\t});\n\t}\n\n\tpublic async addCouponToUser(user: any, couponCode: string): Promise<DocumentType<Model>> {\n\t\tconst coupon = await this.findCouponByCode(couponCode);\n\t\tif (!coupon) {\n\t\t\tthis.throwBadRequest('Coupon not found');\n\t\t}\n\t\tconst isNewUser = await couponHelperService.isNewUser(new mongoose.Types.ObjectId(user));\n\n\t\tif (coupon.couponType == CouponType.REFERRAL_CODE && !isNewUser) {\n\t\t\tthis.throwBadRequest('This coupon is valid for new users only');\n\t\t}\n\n\t\tif (coupon.couponType == CouponType.REFERRAL_CODE) {\n\t\t\tif ((coupon as DocumentType<ReferralCodeCoupon>).referralUser.toString() == user) {\n\t\t\t\tthis.throwBadRequest('You cannot add your own referral code');\n\t\t\t}\n\t\t}\n\n\t\tconst typedCoupon = coupon as DocumentType<BaseCoupon>;\n\n\t\tif (this.isCouponExpired(typedCoupon)) {\n\t\t\tthis.throwBadRequest('This coupon has expired and cannot be added');\n\t\t}\n\n\t\tif (typedCoupon.forNewUserOnly && !isNewUser) {\n\t\t\tthis.throwBadRequest('This coupon is valid for new users only');\n\t\t}\n\n\t\tconst alreadyApplied = await this.hasUserAlreadyAppliedCoupon(user, typedCoupon);\n\t\tif (alreadyApplied) {\n\t\t\tthis.throwBadRequest('Coupon already applied to user');\n\t\t}\n\n\t\tif (typedCoupon.couponType == CouponType.INDIVIDUAL_USER) {\n\t\t\tif (!(typedCoupon as DocumentType<IndividualUserCoupon>).users?.includes(user)) {\n\t\t\t\tthis.throwBadRequest('This coupon is not assigned to this user');\n\t\t\t}\n\t\t}\n\n\t\tawait this.userModel.findByIdAndUpdate(\n\t\t\tuser,\n\t\t\t{ $push: { coupons: typedCoupon._id } },\n\t\t\t{ new: true, runValidators: true }\n\t\t);\n\n\t\treturn coupon;\n\t}\n\n\tprivate async hasUserAlreadyAppliedCoupon(\n\t\tuserId: mongoose.Types.ObjectId,\n\t\tcoupon: DocumentType<BaseCoupon>\n\t): Promise<boolean> {\n\t\tconst couponIds = [coupon._id, ...(coupon.previousVersions ?? []).map(v => v._id)];\n\n\t\tconst user = await this.userModel.exists({\n\t\t\t_id: userId,\n\t\t\tcoupons: { $in: couponIds },\n\t\t});\n\n\t\treturn !!user;\n\t}\n\n\tprivate async exchangeCouponForMultipleUser(\n\t\tquery: mongoose.FilterQuery<User>,\n\t\toldCoupon: mongoose.Types.ObjectId,\n\t\tnewCoupon: mongoose.Types.ObjectId\n\t) {\n\t\tawait this.removeCouponFromMultipleUser(query, oldCoupon);\n\t\tawait this.assignCouponToMultipleUser(query, newCoupon);\n\t}\n\n\tpublic getShareableLink = async (code: string): Promise<ShareableLinkDTO> => {\n\t\tconst secretsService = getLibraries().getSecretsService();\n\t\tconst deepLinkUrl = (await secretsService.getKey('DEEP_LINK_URL')) ?? 'https://link.lyxa.ai';\n\n\t\tconst link = `${deepLinkUrl}/invite/${code}`;\n\n\t\tconst message = `Download Lyxa and explore the wide variety of offerings and benefits! Use my code at checkout to claim a special coupon : ${code}.\n\t\t${link}`;\n\n\t\treturn { link, message };\n\t};\n\n\tpublic async getUserCouponList(data?: Partial<FilterDTO>): Promise<PaginatedResponse<AllCouponsDTO>> {\n\t\ttry {\n\t\t\tlet query = data?.query || {};\n\n\t\t\tif (!query.user) {\n\t\t\t\tbadRequestError('User ID is required in query');\n\t\t\t}\n\n\t\t\tconst select = data?.select || {\n\t\t\t\t_id: 1,\n\t\t\t\t'createdBy.name': 1,\n\t\t\t\t'duration.start': 1,\n\t\t\t\t'duration.end': 1,\n\t\t\t\tcode: 1,\n\t\t\t\tstatus: 1,\n\t\t\t\tcreatedAt: 1,\n\t\t\t\tcouponType: 1,\n\t\t\t};\n\n\t\t\tlet isExpiredField = null;\n\n\t\t\tif (query.status) {\n\t\t\t\tif (query.status === 'expired') {\n\t\t\t\t\tisExpiredField = true;\n\t\t\t\t\tdelete query.status;\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tif (query.createdAt) {\n\t\t\t\t// convert to date range\n\t\t\t\tif ('$gte' in query.createdAt) {\n\t\t\t\t\tquery.createdAt.$gte = new Date(query.createdAt.$gte);\n\t\t\t\t}\n\t\t\t\tif ('$lte' in query.createdAt) {\n\t\t\t\t\tquery.createdAt.$lte = new Date(query.createdAt.$lte);\n\t\t\t\t}\n\t\t\t\tif ('$gt' in query.createdAt) {\n\t\t\t\t\tquery.createdAt.$gt = new Date(query.createdAt.$gt);\n\t\t\t\t}\n\t\t\t\tif ('$lt' in query.createdAt) {\n\t\t\t\t\tquery.createdAt.$lt = new Date(query.createdAt.$lt);\n\t\t\t\t}\n\t\t\t}\n\n\t\t\tconst user = await this.userModel.findById(query.user).select('coupons');\n\t\t\tquery._id = { $in: user?.coupons ?? [] };\n\t\t\tdelete query.user; // remove user from query to avoid issues in aggregation match stage\n\n\t\t\tconst pipeline: any[] = [\n\t\t\t\t{ $match: { ...query, deletedAt: null } }, // Filter by search query\n\t\t\t\t{\n\t\t\t\t\t$lookup: {\n\t\t\t\t\t\t// INNER JOIN on categories\n\t\t\t\t\t\tfrom: 'admins', // Mongoose auto-pluralizes collection names\n\t\t\t\t\t\tlocalField: 'createdBy',\n\t\t\t\t\t\tforeignField: '_id',\n\t\t\t\t\t\tas: 'createdBy',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{ $unwind: { path: '$createdBy', preserveNullAndEmptyArrays: true } }, // Flatten the array\n\t\t\t\t{\n\t\t\t\t\t$addFields: {\n\t\t\t\t\t\tisExpired: {\n\t\t\t\t\t\t\t$cond: {\n\t\t\t\t\t\t\t\tif: {\n\t\t\t\t\t\t\t\t\t$or: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t$and: [\n\t\t\t\t\t\t\t\t\t\t\t\t{ $ifNull: ['$duration.end', false] },\n\t\t\t\t\t\t\t\t\t\t\t\t{ $lt: ['$duration.end', dayjs().toDate()] },\n\t\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t{ $ifNull: ['$expirationReason', false] },\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\tthen: true,\n\t\t\t\t\t\t\t\telse: false,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$match: isExpiredField\n\t\t\t\t\t\t? { isExpired: true }\n\t\t\t\t\t\t: query.status === 'active'\n\t\t\t\t\t\t\t? { isExpired: false }\n\t\t\t\t\t\t\t: {},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$addFields: {\n\t\t\t\t\t\tstatus: {\n\t\t\t\t\t\t\t$cond: {\n\t\t\t\t\t\t\t\tif: { $eq: ['$isExpired', true] },\n\t\t\t\t\t\t\t\tthen: 'expired',\n\t\t\t\t\t\t\t\telse: '$status',\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$project: select,\n\t\t\t\t},\n\t\t\t];\n\n\t\t\tif (data?.search?.searchKey) {\n\t\t\t\tconst searchKey = data.search.searchKey;\n\t\t\t\tconst regex = new RegExp(searchKey, 'i'); // case-insensitive search\n\t\t\t\tconst fields = data.search.searchFields?.length ? data.search.searchFields : ['code']; // default field(s) to search in\n\n\t\t\t\tpipeline.push({\n\t\t\t\t\t$match: {\n\t\t\t\t\t\t$or: fields.map(field => ({ [field]: { $regex: regex } })),\n\t\t\t\t\t},\n\t\t\t\t});\n\t\t\t}\n\n\t\t\t// Execute the aggregation with pagination and sorting\n\t\t\tconst results = await paginateAggregation(this.model, pipeline, data?.page, data?.size, data?.sort);\n\n\t\t\treturn results as unknown as PaginatedResponse<AllCouponsDTO>;\n\t\t} catch (err) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'INTERNAL_SERVER_ERROR',\n\t\t\t\tmessage: `err: ${err}`,\n\t\t\t});\n\t\t}\n\t}\n\n\tpublic async addExistingCouponsToNewUser(userId: mongoose.Types.ObjectId) {\n\t\tconst isNewUser = await couponHelperService.isNewUser(userId);\n\n\t\tconst query: any = {\n\t\t\tcouponType: { $in: [CouponType.GLOBAL, CouponType.INDIVIDUAL_STORE, CouponType.SHOPS_CATEGORIES] },\n\t\t\tdeletedAt: null,\n\t\t\texpirationReason: null,\n\t\t\t$or: [\n\t\t\t\t{ 'duration.end': { $gt: dayjs().toDate() } },\n\t\t\t\t{ 'duration.end': { $exists: false } },\n\t\t\t\t{ 'duration.end': null },\n\t\t\t],\n\t\t\tupdatedVersion: { $exists: false },\n\t\t};\n\n\t\tif (!isNewUser) {\n\t\t\tquery.forNewUserOnly = { $ne: true };\n\t\t}\n\n\t\t// assign all coupons that are not expired\n\t\tconst coupons = await this.baseCouponModel.find(query);\n\n\t\tconst couponIds = coupons.map(coupon => coupon._id);\n\n\t\tawait this.userModel.findByIdAndUpdate(\n\t\t\tuserId,\n\t\t\t{\n\t\t\t\t$addToSet: {\n\t\t\t\t\tcoupons: { $each: couponIds },\n\t\t\t\t},\n\t\t\t},\n\t\t\t{\n\t\t\t\tnew: true,\n\t\t\t\trunValidators: true,\n\t\t\t}\n\t\t);\n\t}\n\n\tpublic async getActiveNewUserCoupon(): Promise<DocumentType<BaseCoupon> | null> {\n\t\tconst currentDate = dayjs().toDate();\n\t\tconst activeForNewUserCoupon = await this.baseCouponModel.findOne({\n\t\t\tcouponType: CouponType.GLOBAL,\n\t\t\tforNewUserOnly: true,\n\t\t\tdeletedAt: null,\n\t\t\t$or: [\n\t\t\t\t{\n\t\t\t\t\texpirationReason: { $exists: false },\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\texpirationReason: null,\n\t\t\t\t},\n\t\t\t],\n\t\t\t'duration.end': { $gte: currentDate },\n\t\t\tupdatedVersion: { $exists: false },\n\t\t});\n\n\t\treturn activeForNewUserCoupon;\n\t}\n\n\tpublic async getActiveNewUserCouponWithSecondaryCurrency(): Promise<DocumentType<BaseCoupon> | null> {\n\t\tconst exchangeRate = await getExchangeRate();\n\t\tconst currentDate = dayjs().toDate();\n\n\t\tconst referralSettings = await this.referralSettingsModel.findOne();\n\n\t\tconst secondaryReferralReceiverValue =\n\t\t\treferralSettings?.receiver?.valueType == ValueType.PERCENTAGE\n\t\t\t\t? null\n\t\t\t\t: roundSecondaryCurrency((referralSettings?.receiver?.value ?? 0) * exchangeRate);\n\n\t\tconst secondaryReferralReceiverMinOrderAmount = roundSecondaryCurrency(\n\t\t\t(referralSettings?.receiver?.minimumOrderValue ?? 0) * exchangeRate\n\t\t);\n\n\t\tconst activeForNewUserCoupon = await this.baseCouponModel.aggregate([\n\t\t\t// Match (same as findOne filter)\n\t\t\t{\n\t\t\t\t$match: {\n\t\t\t\t\tcouponType: CouponType.GLOBAL,\n\t\t\t\t\tforNewUserOnly: true,\n\t\t\t\t\tdeletedAt: null,\n\t\t\t\t\t$or: [{ expirationReason: { $exists: false } }, { expirationReason: null }],\n\t\t\t\t\t'duration.end': { $gte: currentDate },\n\t\t\t\t\tupdatedVersion: { $exists: false },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Add computed fields\n\t\t\t{\n\t\t\t\t$addFields: {\n\t\t\t\t\tsecondaryCurrencyValue: {\n\t\t\t\t\t\t$cond: [\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$eq: ['$valueType', ValueType.PERCENTAGE],\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\tnull,\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t$switch: {\n\t\t\t\t\t\t\t\t\tbranches: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tcase: {\n\t\t\t\t\t\t\t\t\t\t\t\t$eq: ['$couponType', CouponType.REFERRAL_CODE],\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\tthen: secondaryReferralReceiverValue,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\tdefault: getRoundSecondaryCurrencyStage({\n\t\t\t\t\t\t\t\t\t\t$multiply: ['$value', exchangeRate],\n\t\t\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t],\n\t\t\t\t\t},\n\n\t\t\t\t\tsecondaryCurrencyMaxDiscountLimit: {\n\t\t\t\t\t\t$switch: {\n\t\t\t\t\t\t\tbranches: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tcase: {\n\t\t\t\t\t\t\t\t\t\t$eq: ['$couponType', CouponType.REFERRAL_CODE],\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tthen: null,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tdefault: getRoundSecondaryCurrencyStage({\n\t\t\t\t\t\t\t\t$multiply: ['$maxDiscountLimit', exchangeRate],\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\n\t\t\t\t\tsecondaryCurrencyMinOrderValue: {\n\t\t\t\t\t\t$switch: {\n\t\t\t\t\t\t\tbranches: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\tcase: {\n\t\t\t\t\t\t\t\t\t\t$eq: ['$couponType', CouponType.REFERRAL_CODE],\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\tthen: secondaryReferralReceiverMinOrderAmount,\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tdefault: getRoundSecondaryCurrencyStage({\n\t\t\t\t\t\t\t\t$multiply: ['$minOrderValue', exchangeRate],\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Limit to 1 document (like findOne)\n\t\t\t{ $limit: 1 },\n\t\t]);\n\n\t\treturn activeForNewUserCoupon[0] || null;\n\t}\n\n\tpublic async checkExistingNewUserCoupon(): Promise<CheckExistingNewUserCouponOutputDTO> {\n\t\tconst alreadyActiveForNewUserCoupon = await this.getActiveNewUserCoupon();\n\n\t\tif (alreadyActiveForNewUserCoupon) {\n\t\t\treturn { exists: true };\n\t\t}\n\n\t\treturn { exists: false };\n\t}\n\n\tprivate async getAllOrders(userIds: mongoose.Types.ObjectId[]): Promise<number> {\n\t\treturn await this.orderModel.countDocuments({\n\t\t\tuser: { $in: userIds },\n\t\t\tstatus: { $ne: RegularOrderStatus.CANCELLED },\n\t\t\torderType: OrderType.REGULAR,\n\t\t});\n\t}\n\n\tpublic async handleCouponGiftBox(\n\t\tdeviceId: string,\n\t\tuserId: mongoose.Types.ObjectId | null\n\t): Promise<DocumentType<GlobalCoupon>[]> {\n\t\tconst couponRepository = new CouponRepository();\n\n\t\t// 1. Get all the user id using device id\n\t\tconst allUsers = await this.userModel.find({ deviceId }).select('_id');\n\n\t\t// 2. Make an array using all the user ids\n\t\tconst userIds = allUsers.map(user => user._id);\n\n\t\t// 3. Append the current user id to the array\n\t\tif (userId) {\n\t\t\tuserIds.push(new mongoose.Types.ObjectId(userId));\n\t\t}\n\n\t\t// 4. Check if any user has isNewUserCouponShowed = true\n\t\tconst hasShownCoupon = await this.userModel.exists({\n\t\t\t_id: { $in: userIds },\n\t\t\tisNewUserCouponShowed: true,\n\t\t});\n\n\t\tif (hasShownCoupon) {\n\t\t\t// console.log('At least one user already saw the coupon');\n\t\t\treturn [];\n\t\t}\n\n\t\t// 5. Find how many orders placed by these user ids\n\t\tconst totalOrders = await this.getAllOrders(userIds);\n\n\t\t// 6. Get coupon details\n\t\tconst activeNewUserCoupon = await this.getActiveNewUserCouponWithSecondaryCurrency();\n\t\tif (!activeNewUserCoupon) {\n\t\t\t// notFoundError('No active new user coupon found');\n\t\t\treturn [];\n\t\t}\n\n\t\t// 7. Check the total order quantity less than to order limit per user\n\t\tif (\n\t\t\tactiveNewUserCoupon.isOrderLimitPerUserEnabled &&\n\t\t\ttotalOrders < (activeNewUserCoupon.orderLimitPerUser || 0)\n\t\t) {\n\t\t\t// Update the user document for the new user coupon\n\t\t\t// this.updateNewUserCouponField(userIds);\n\n\t\t\t// Return the coupon details to show in the gift box\n\t\t\treturn couponRepository.addLabelsToCoupons([activeNewUserCoupon]);\n\t\t}\n\n\t\treturn [];\n\t}\n\n\tprivate async updateNewUserCouponField(userIds: mongoose.Types.ObjectId[]): Promise<number> {\n\t\t// Update all the users coupon-shown field\n\t\tconst result = await this.userModel.updateMany(\n\t\t\t{ _id: { $in: userIds } },\n\t\t\t{\n\t\t\t\t$set: {\n\t\t\t\t\tisNewUserCouponShowed: false,\n\t\t\t\t},\n\t\t\t}\n\t\t);\n\n\t\treturn result.modifiedCount;\n\t}\n\n\tpublic async updateCouponGiftBoxShown(userId: mongoose.Types.ObjectId, data: any): Promise<number> {\n\t\t// Get device-id using user-id\n\t\tconst user = await this.userModel.findById(userId);\n\n\t\t// Get all users using device-id\n\t\tconst users = await this.userModel.find({ deviceId: user?.deviceId }).select('_id').lean();\n\n\t\t// Set array of ids\n\t\tconst userIds = users.map(u => u._id);\n\n\t\t// Update all the users coupon-shown field\n\t\tconst result = await this.userModel.updateMany(\n\t\t\t{ _id: { $in: userIds } },\n\t\t\t{\n\t\t\t\t$set: {\n\t\t\t\t\tisNewUserCouponShowed: data.isNewUserGiftBoxShown,\n\t\t\t\t},\n\t\t\t}\n\t\t);\n\n\t\treturn result.modifiedCount;\n\t}\n}\n\nexport const couponService = Container.get(CouponService);\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.service.d.ts","sourceRoot":"/","sources":["modules/coupon/services/helper.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EACN,UAAU,EAIV,IAAI,EAIJ,MAAM,2CAA2C,CAAC;AAGnD,OAAc,EAAE,KAAK,EAAE,MAAM,0CAA0C,CAAC;AACxE,OAAO,EAAE,yBAAyB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAI9E,qBACa,mBAAmB;IAC/B,OAAO,CAAC,SAAS,CAA2C;IAC5D,OAAO,CAAC,UAAU,CAA2D;IAC7E,OAAO,CAAC,SAAS,CAA2C;IAC5D,OAAO,CAAC,cAAc,CAAoD;;IAQ1E,OAAO,KAAK,aAAa,GAKxB;IAEY,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAyB1D,6BAA6B,CACzC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAC7B,MAAM,EAAE,YAAY,CAAC,UAAU,CAAC,GAC9B,OAAO,CAAC,MAAM,CAAC;IA0BL,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;IAwEvD,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,GAAG,OAAO;IAU5C,uBAAuB,CAAC,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,YAAY,CAAC,UAAU,CAAC;;;;IAyBvF,mBAAmB,CACzB,IAAI,EAAE,iBAAiB,EACvB,cAAc,EAAE,MAAM,EACtB,uBAAuB,EAAE,MAAM,EAC/B,mBAAmB,EAAE,OAAO,EAC5B,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACjC,yBAAyB;IAmBf,uBAAuB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;QAAE,IAAI,EAAE,iBAAiB,CAAC;QAAC,MAAM,EAAE,GAAG,CAAA;KAAE;;;;;;;;;;;;;YAoBjF,6BAA6B;IAuB3C,OAAO,CAAC,yBAAyB;
|
|
1
|
+
{"version":3,"file":"helper.service.d.ts","sourceRoot":"/","sources":["modules/coupon/services/helper.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EACN,UAAU,EAIV,IAAI,EAIJ,MAAM,2CAA2C,CAAC;AAGnD,OAAc,EAAE,KAAK,EAAE,MAAM,0CAA0C,CAAC;AACxE,OAAO,EAAE,yBAAyB,EAAE,iBAAiB,EAAE,MAAM,gBAAgB,CAAC;AAI9E,qBACa,mBAAmB;IAC/B,OAAO,CAAC,SAAS,CAA2C;IAC5D,OAAO,CAAC,UAAU,CAA2D;IAC7E,OAAO,CAAC,SAAS,CAA2C;IAC5D,OAAO,CAAC,cAAc,CAAoD;;IAQ1E,OAAO,KAAK,aAAa,GAKxB;IAEY,SAAS,CAAC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,OAAO,CAAC;IAyB1D,6BAA6B,CACzC,IAAI,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAC7B,MAAM,EAAE,YAAY,CAAC,UAAU,CAAC,GAC9B,OAAO,CAAC,MAAM,CAAC;IA0BL,WAAW,IAAI,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,CAAC;IAwEvD,eAAe,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,GAAG,OAAO;IAU5C,uBAAuB,CAAC,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,YAAY,CAAC,UAAU,CAAC;;;;IAyBvF,mBAAmB,CACzB,IAAI,EAAE,iBAAiB,EACvB,cAAc,EAAE,MAAM,EACtB,uBAAuB,EAAE,MAAM,EAC/B,mBAAmB,EAAE,OAAO,EAC5B,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GACjC,yBAAyB;IAmBf,uBAAuB,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE;QAAE,IAAI,EAAE,iBAAiB,CAAC;QAAC,MAAM,EAAE,GAAG,CAAA;KAAE;;;;;;;;;;;;;YAoBjF,6BAA6B;IAuB3C,OAAO,CAAC,yBAAyB;YAuBnB,sBAAsB;IAmBvB,aAAa,CAAC,MAAM,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC;CAS5E;AAED,eAAO,MAAM,mBAAmB,qBAAqC,CAAC"}
|
|
@@ -74,10 +74,10 @@ let CouponHelperService = class CouponHelperService {
|
|
|
74
74
|
const existingUser = await this.userModel.findOne({
|
|
75
75
|
_id: user,
|
|
76
76
|
});
|
|
77
|
-
const sameDeviceUsers = await this.userModel.
|
|
77
|
+
const sameDeviceUsers = await this.userModel.findWithDeleted({
|
|
78
78
|
deviceId: existingUser?.deviceId,
|
|
79
79
|
});
|
|
80
|
-
sameDeviceUsers.forEach(u => {
|
|
80
|
+
sameDeviceUsers.forEach((u) => {
|
|
81
81
|
if (!users.includes(u._id.toString())) {
|
|
82
82
|
users.push(u._id.toString());
|
|
83
83
|
}
|
|
@@ -93,10 +93,10 @@ let CouponHelperService = class CouponHelperService {
|
|
|
93
93
|
const existingUser = await this.userModel.findOne({
|
|
94
94
|
_id: user,
|
|
95
95
|
});
|
|
96
|
-
const sameDeviceUsers = await this.userModel.
|
|
96
|
+
const sameDeviceUsers = await this.userModel.findWithDeleted({
|
|
97
97
|
deviceId: existingUser?.deviceId,
|
|
98
98
|
});
|
|
99
|
-
sameDeviceUsers.forEach(u => {
|
|
99
|
+
sameDeviceUsers.forEach((u) => {
|
|
100
100
|
if (!users.includes(u._id.toString())) {
|
|
101
101
|
users.push(u._id.toString());
|
|
102
102
|
}
|
|
@@ -247,10 +247,15 @@ let CouponHelperService = class CouponHelperService {
|
|
|
247
247
|
const hasItemTypeRestriction = Array.isArray(coupon.itemTypes) && coupon.itemTypes.length > 0;
|
|
248
248
|
if (!hasShopRestriction && !hasItemTypeRestriction)
|
|
249
249
|
return null;
|
|
250
|
-
const shopMatches = hasShopRestriction &&
|
|
250
|
+
const shopMatches = hasShopRestriction &&
|
|
251
|
+
coupon.shops.some((couponShop) => couponShop._id.toString() === shop._id.toString());
|
|
251
252
|
const itemTypeMatches = hasItemTypeRestriction && coupon.itemTypes.includes(shop.itemType);
|
|
252
253
|
if (!shopMatches && !itemTypeMatches) {
|
|
253
|
-
|
|
254
|
+
const shopNames = coupon.shops.map((shop) => shop.name).join(', ');
|
|
255
|
+
return {
|
|
256
|
+
isValid: false,
|
|
257
|
+
message: `This coupon can be used at ${shopNames}`,
|
|
258
|
+
};
|
|
254
259
|
}
|
|
255
260
|
return null;
|
|
256
261
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helper.service.js","sourceRoot":"/","sources":["modules/coupon/services/helper.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, { Service } from 'typedi';\nimport { DocumentType, mongoose } from '@typegoose/typegoose';\nimport {\n\tBaseCoupon,\n\tgetCoreUserModel,\n\tRegularOrder,\n\tRegularOrderModel,\n\tShop,\n\tShopModel,\n\tUser,\n\tUserModel,\n} from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport { SoftDeleteModel } from '@lyxa.ai/core/dist/libraries/mongo/plugins/soft-delete-plugin';\nimport { RegularOrderStatus, ValueType } from '@lyxa.ai/core/dist/utilities/enum';\nimport dayjs, { Dayjs } from '@lyxa.ai/core/dist/utilities/dayjs/dayjs';\nimport { CouponValidationOutputDTO, ValidateCouponDTO } from '../validations';\nimport { convertToSecondary } from '@lyxa.ai/core/dist/utilities/currency';\nimport { roundBaseCurrency, roundSecondaryCurrency } from '@lyxa.ai/core/dist/utilities/shared';\n\n@Service()\nexport class CouponHelperService {\n\tprivate userModel: typeof UserModel & SoftDeleteModel<User>;\n\tprivate orderModel: typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\tprivate shopModel: typeof ShopModel & SoftDeleteModel<Shop>;\n\tprivate _coreUserModel: ReturnType<typeof getCoreUserModel> | null = null;\n\n\tconstructor() {\n\t\tthis.userModel = UserModel as typeof UserModel & SoftDeleteModel<User>;\n\t\tthis.orderModel = RegularOrderModel as typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\t\tthis.shopModel = ShopModel as typeof ShopModel & SoftDeleteModel<Shop>;\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\tpublic async isNewUser(user: mongoose.Types.ObjectId): Promise<boolean> {\n\t\tlet users = [user._id.toString()];\n\n\t\tconst existingUser = await this.userModel.findOne({\n\t\t\t_id: user,\n\t\t});\n\n\t\tconst sameDeviceUsers = await this.userModel.find({\n\t\t\tdeviceId: existingUser?.deviceId,\n\t\t});\n\n\t\tsameDeviceUsers.forEach(u => {\n\t\t\tif (!users.includes(u._id.toString())) {\n\t\t\t\tusers.push(u._id.toString());\n\t\t\t}\n\t\t});\n\n\t\tconst orderCount = await this.orderModel.countDocuments({\n\t\t\tuser: { $in: users },\n\t\t\tstatus: { $ne: RegularOrderStatus.CANCELLED },\n\t\t});\n\n\t\treturn orderCount < 1;\n\t}\n\n\tpublic async getSameDeviceOrdersWithCoupon(\n\t\tuser: mongoose.Types.ObjectId,\n\t\tcoupon: DocumentType<BaseCoupon>\n\t): Promise<number> {\n\t\tlet users = [user._id.toString()];\n\n\t\tconst existingUser = await this.userModel.findOne({\n\t\t\t_id: user,\n\t\t});\n\n\t\tconst sameDeviceUsers = await this.userModel.find({\n\t\t\tdeviceId: existingUser?.deviceId,\n\t\t});\n\n\t\tsameDeviceUsers.forEach(u => {\n\t\t\tif (!users.includes(u._id.toString())) {\n\t\t\t\tusers.push(u._id.toString());\n\t\t\t}\n\t\t});\n\n\t\tconst orderCount = await this.orderModel.countDocuments({\n\t\t\tuser: { $in: users },\n\t\t\tstatus: { $ne: RegularOrderStatus.CANCELLED },\n\t\t\t'adjustedFinance.coupon.coupon': coupon._id,\n\t\t});\n\n\t\treturn orderCount;\n\t}\n\n\tpublic async getNewUsers(): Promise<mongoose.Types.ObjectId[]> {\n\t\tconst pipeline: mongoose.PipelineStage[] = [\n\t\t\t// Step 1: Lookup all users who share the same deviceId\n\t\t\t{\n\t\t\t\t$lookup: {\n\t\t\t\t\tfrom: 'users',\n\t\t\t\t\tlocalField: 'deviceId',\n\t\t\t\t\tforeignField: 'deviceId',\n\t\t\t\t\tas: 'sameDeviceUsers',\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Step 2: Collect the list of userIds belonging to this device\n\t\t\t{\n\t\t\t\t$set: {\n\t\t\t\t\tallUserIds: {\n\t\t\t\t\t\t$map: {\n\t\t\t\t\t\t\tinput: '$sameDeviceUsers',\n\t\t\t\t\t\t\tas: 'u',\n\t\t\t\t\t\t\tin: '$$u._id',\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Step 3: Lookup orders attached to any of these users\n\t\t\t{\n\t\t\t\t$lookup: {\n\t\t\t\t\tfrom: 'orders',\n\t\t\t\t\tlet: { ids: '$allUserIds' },\n\t\t\t\t\tpipeline: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t$match: {\n\t\t\t\t\t\t\t\t$expr: {\n\t\t\t\t\t\t\t\t\t$and: [{ $in: ['$user', '$$ids'] }, { $ne: ['$status', 'CANCELLED'] }],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tas: 'orders',\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Step 4: Count orders\n\t\t\t{\n\t\t\t\t$set: {\n\t\t\t\t\torderCount: { $size: '$orders' },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Step 5: New user = zero or one non-cancelled order\n\t\t\t{\n\t\t\t\t$match: {\n\t\t\t\t\torderCount: { $lte: 1 },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Optional: Remove temporary fields\n\t\t\t{\n\t\t\t\t$project: {\n\t\t\t\t\tsameDeviceUsers: 0,\n\t\t\t\t\tallUserIds: 0,\n\t\t\t\t\torders: 0,\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\n\t\tconst newUsers = await this.userModel.aggregate(pipeline).exec();\n\n\t\treturn newUsers.map(u => u._id);\n\t}\n\n\tpublic isDurationValid(start: Dayjs, end: Dayjs): boolean {\n\t\tconst getRoundedHourBack = (hoursBack = 0) => {\n\t\t\treturn dayjs().subtract(hoursBack, 'hour').startOf('hour');\n\t\t};\n\n\t\tconst cutoffTime = getRoundedHourBack();\n\n\t\treturn start >= cutoffTime && end >= cutoffTime;\n\t}\n\n\tpublic async calculateCouponDiscount(data: ValidateCouponDTO, coupon: DocumentType<BaseCoupon>) {\n\t\tlet discountAmount =\n\t\t\tcoupon.valueType === ValueType.FIXED\n\t\t\t\t? coupon.value\n\t\t\t\t: roundBaseCurrency((data.amountBeforeCoupon * coupon.value) / 100);\n\n\t\tlet secondaryDiscountAmount =\n\t\t\tcoupon.valueType === ValueType.FIXED\n\t\t\t\t? await convertToSecondary(coupon.value)\n\t\t\t\t: roundSecondaryCurrency((data.secondaryAmountBeforeCoupon * coupon.value) / 100);\n\n\t\tif (coupon.isMaxDiscountLimitEnabled && coupon.maxDiscountLimit) {\n\t\t\tconst secondaryMax = await convertToSecondary(coupon.maxDiscountLimit);\n\n\t\t\tdiscountAmount = Math.min(discountAmount, coupon.maxDiscountLimit);\n\t\t\tsecondaryDiscountAmount = Math.min(secondaryDiscountAmount, secondaryMax);\n\t\t}\n\n\t\t// Prevent negative totals\n\t\tdiscountAmount = Math.min(discountAmount, data.amountBeforeCoupon);\n\t\tsecondaryDiscountAmount = Math.min(secondaryDiscountAmount, data.secondaryAmountBeforeCoupon);\n\n\t\treturn { discountAmount, secondaryDiscountAmount };\n\t}\n\n\tpublic buildCouponResponse(\n\t\tdata: ValidateCouponDTO,\n\t\tdiscountAmount: number,\n\t\tsecondaryDiscountAmount: number,\n\t\tisShopCoverExpenses: boolean,\n\t\tcouponDetails?: Record<string, any>\n\t): CouponValidationOutputDTO {\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\tcouponDetails,\n\t\t};\n\t}\n\n\tpublic async validateShopEligibility({ data, coupon }: { data: ValidateCouponDTO; coupon: any }) {\n\t\tconst shop = await this.shopModel.findOne({\n\t\t\t_id: new mongoose.Types.ObjectId(data.shop),\n\t\t\tdeletedAt: null,\n\t\t});\n\n\t\tif (!shop) return { isValid: false, message: 'Shop not found' };\n\n\t\tconst singleShopError = await this.validateSingleShopRestriction(shop, coupon);\n\t\tif (singleShopError) return singleShopError;\n\n\t\tconst restrictionError = this.validateMultiRestrictions(shop, coupon);\n\t\tif (restrictionError) return restrictionError;\n\n\t\tconst firstOrderError = await this.validateFirstOrderOnly(data, shop, coupon);\n\t\tif (firstOrderError) return firstOrderError;\n\n\t\treturn { isValid: true, shop };\n\t}\n\n\tprivate async validateSingleShopRestriction(shop: any, coupon: any) {\n\t\tif (!coupon.shop) return null;\n\n\t\tconst couponShopId = coupon.shop.toString();\n\t\tconst currentShopId = shop._id.toString();\n\n\t\tif (couponShopId === currentShopId) return null;\n\n\t\tconst validShop = await this.shopModel.findOne({ _id: coupon.shop, deletedAt: null }).select('name');\n\n\t\tif (!validShop) {\n\t\t\treturn {\n\t\t\t\tisValid: false,\n\t\t\t\tmessage: 'Coupon is associated with an invalid shop',\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\tmessage: `This coupon can be used at ${validShop.name} only`,\n\t\t};\n\t}\n\n\tprivate validateMultiRestrictions(shop: any, coupon: any) {\n\t\tconst hasShopRestriction = Array.isArray(coupon.shops) && coupon.shops.length > 0;\n\t\tconst hasItemTypeRestriction = Array.isArray(coupon.itemTypes) && coupon.itemTypes.length > 0;\n\n\t\tif (!hasShopRestriction && !hasItemTypeRestriction) return null;\n\n\t\tconst shopMatches =\n\t\t\thasShopRestriction && coupon.shops.some((s: any) => s.toString() === shop._id.toString());\n\n\t\tconst itemTypeMatches = hasItemTypeRestriction && coupon.itemTypes.includes(shop.itemType);\n\n\t\tif (!shopMatches && !itemTypeMatches) {\n\t\t\treturn { isValid: false, message: 'Coupon is not valid for this shop' };\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tprivate async validateFirstOrderOnly(data: ValidateCouponDTO, shop: any, coupon: any) {\n\t\tif (!coupon.firstOrderOnly) return null;\n\n\t\tconst existingOrder = await this.orderModel.exists({\n\t\t\tuser: new mongoose.Types.ObjectId(data.user),\n\t\t\tshop: shop._id,\n\t\t\tstatus: { $ne: RegularOrderStatus.CANCELLED },\n\t\t});\n\n\t\tif (existingOrder) {\n\t\t\treturn {\n\t\t\t\tisValid: false,\n\t\t\t\tmessage: 'This coupon is only valid for the first order in the shop',\n\t\t\t};\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tpublic async fetchUserName(userId: mongoose.Types.ObjectId): Promise<string> {\n\t\tconst user = await this.userModel.findById(userId).select('coreUser').lean();\n\t\t\n\t\tif (!user) return 'Unknown User';\n\n\t\tconst coreUser = await this.coreUserModel.findById(user.coreUser).select('name').lean();\n\n\t\treturn coreUser ? coreUser.name : 'Unknown User';\n\t}\n}\n\nexport const couponHelperService = Container.get(CouponHelperService);\n"]}
|
|
1
|
+
{"version":3,"file":"helper.service.js","sourceRoot":"/","sources":["modules/coupon/services/helper.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, { Service } from 'typedi';\nimport { DocumentType, mongoose } from '@typegoose/typegoose';\nimport {\n\tBaseCoupon,\n\tgetCoreUserModel,\n\tRegularOrder,\n\tRegularOrderModel,\n\tShop,\n\tShopModel,\n\tUser,\n\tUserModel,\n} from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport { SoftDeleteModel } from '@lyxa.ai/core/dist/libraries/mongo/plugins/soft-delete-plugin';\nimport { RegularOrderStatus, ValueType } from '@lyxa.ai/core/dist/utilities/enum';\nimport dayjs, { Dayjs } from '@lyxa.ai/core/dist/utilities/dayjs/dayjs';\nimport { CouponValidationOutputDTO, ValidateCouponDTO } from '../validations';\nimport { convertToSecondary } from '@lyxa.ai/core/dist/utilities/currency';\nimport { roundBaseCurrency, roundSecondaryCurrency } from '@lyxa.ai/core/dist/utilities/shared';\n\n@Service()\nexport class CouponHelperService {\n\tprivate userModel: typeof UserModel & SoftDeleteModel<User>;\n\tprivate orderModel: typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\tprivate shopModel: typeof ShopModel & SoftDeleteModel<Shop>;\n\tprivate _coreUserModel: ReturnType<typeof getCoreUserModel> | null = null;\n\n\tconstructor() {\n\t\tthis.userModel = UserModel as typeof UserModel & SoftDeleteModel<User>;\n\t\tthis.orderModel = RegularOrderModel as typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\t\tthis.shopModel = ShopModel as typeof ShopModel & SoftDeleteModel<Shop>;\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\tpublic async isNewUser(user: mongoose.Types.ObjectId): Promise<boolean> {\n\t\tlet users = [user._id.toString()];\n\n\t\tconst existingUser = await this.userModel.findOne({\n\t\t\t_id: user,\n\t\t});\n\n\t\tconst sameDeviceUsers = await this.userModel.findWithDeleted({\n\t\t\tdeviceId: existingUser?.deviceId,\n\t\t});\n\n\t\tsameDeviceUsers.forEach((u: any) => {\n\t\t\tif (!users.includes(u._id.toString())) {\n\t\t\t\tusers.push(u._id.toString());\n\t\t\t}\n\t\t});\n\n\t\tconst orderCount = await this.orderModel.countDocuments({\n\t\t\tuser: { $in: users },\n\t\t\tstatus: { $ne: RegularOrderStatus.CANCELLED },\n\t\t});\n\n\t\treturn orderCount < 1;\n\t}\n\n\tpublic async getSameDeviceOrdersWithCoupon(\n\t\tuser: mongoose.Types.ObjectId,\n\t\tcoupon: DocumentType<BaseCoupon>\n\t): Promise<number> {\n\t\tlet users = [user._id.toString()];\n\n\t\tconst existingUser = await this.userModel.findOne({\n\t\t\t_id: user,\n\t\t});\n\n\t\tconst sameDeviceUsers = await this.userModel.findWithDeleted({\n\t\t\tdeviceId: existingUser?.deviceId,\n\t\t});\n\n\t\tsameDeviceUsers.forEach((u: any) => {\n\t\t\tif (!users.includes(u._id.toString())) {\n\t\t\t\tusers.push(u._id.toString());\n\t\t\t}\n\t\t});\n\n\t\tconst orderCount = await this.orderModel.countDocuments({\n\t\t\tuser: { $in: users },\n\t\t\tstatus: { $ne: RegularOrderStatus.CANCELLED },\n\t\t\t'adjustedFinance.coupon.coupon': coupon._id,\n\t\t});\n\n\t\treturn orderCount;\n\t}\n\n\tpublic async getNewUsers(): Promise<mongoose.Types.ObjectId[]> {\n\t\tconst pipeline: mongoose.PipelineStage[] = [\n\t\t\t// Step 1: Lookup all users who share the same deviceId\n\t\t\t{\n\t\t\t\t$lookup: {\n\t\t\t\t\tfrom: 'users',\n\t\t\t\t\tlocalField: 'deviceId',\n\t\t\t\t\tforeignField: 'deviceId',\n\t\t\t\t\tas: 'sameDeviceUsers',\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Step 2: Collect the list of userIds belonging to this device\n\t\t\t{\n\t\t\t\t$set: {\n\t\t\t\t\tallUserIds: {\n\t\t\t\t\t\t$map: {\n\t\t\t\t\t\t\tinput: '$sameDeviceUsers',\n\t\t\t\t\t\t\tas: 'u',\n\t\t\t\t\t\t\tin: '$$u._id',\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Step 3: Lookup orders attached to any of these users\n\t\t\t{\n\t\t\t\t$lookup: {\n\t\t\t\t\tfrom: 'orders',\n\t\t\t\t\tlet: { ids: '$allUserIds' },\n\t\t\t\t\tpipeline: [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t$match: {\n\t\t\t\t\t\t\t\t$expr: {\n\t\t\t\t\t\t\t\t\t$and: [{ $in: ['$user', '$$ids'] }, { $ne: ['$status', 'CANCELLED'] }],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t],\n\t\t\t\t\tas: 'orders',\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Step 4: Count orders\n\t\t\t{\n\t\t\t\t$set: {\n\t\t\t\t\torderCount: { $size: '$orders' },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Step 5: New user = zero or one non-cancelled order\n\t\t\t{\n\t\t\t\t$match: {\n\t\t\t\t\torderCount: { $lte: 1 },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Optional: Remove temporary fields\n\t\t\t{\n\t\t\t\t$project: {\n\t\t\t\t\tsameDeviceUsers: 0,\n\t\t\t\t\tallUserIds: 0,\n\t\t\t\t\torders: 0,\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\n\t\tconst newUsers = await this.userModel.aggregate(pipeline).exec();\n\n\t\treturn newUsers.map(u => u._id);\n\t}\n\n\tpublic isDurationValid(start: Dayjs, end: Dayjs): boolean {\n\t\tconst getRoundedHourBack = (hoursBack = 0) => {\n\t\t\treturn dayjs().subtract(hoursBack, 'hour').startOf('hour');\n\t\t};\n\n\t\tconst cutoffTime = getRoundedHourBack();\n\n\t\treturn start >= cutoffTime && end >= cutoffTime;\n\t}\n\n\tpublic async calculateCouponDiscount(data: ValidateCouponDTO, coupon: DocumentType<BaseCoupon>) {\n\t\tlet discountAmount =\n\t\t\tcoupon.valueType === ValueType.FIXED\n\t\t\t\t? coupon.value\n\t\t\t\t: roundBaseCurrency((data.amountBeforeCoupon * coupon.value) / 100);\n\n\t\tlet secondaryDiscountAmount =\n\t\t\tcoupon.valueType === ValueType.FIXED\n\t\t\t\t? await convertToSecondary(coupon.value)\n\t\t\t\t: roundSecondaryCurrency((data.secondaryAmountBeforeCoupon * coupon.value) / 100);\n\n\t\tif (coupon.isMaxDiscountLimitEnabled && coupon.maxDiscountLimit) {\n\t\t\tconst secondaryMax = await convertToSecondary(coupon.maxDiscountLimit);\n\n\t\t\tdiscountAmount = Math.min(discountAmount, coupon.maxDiscountLimit);\n\t\t\tsecondaryDiscountAmount = Math.min(secondaryDiscountAmount, secondaryMax);\n\t\t}\n\n\t\t// Prevent negative totals\n\t\tdiscountAmount = Math.min(discountAmount, data.amountBeforeCoupon);\n\t\tsecondaryDiscountAmount = Math.min(secondaryDiscountAmount, data.secondaryAmountBeforeCoupon);\n\n\t\treturn { discountAmount, secondaryDiscountAmount };\n\t}\n\n\tpublic buildCouponResponse(\n\t\tdata: ValidateCouponDTO,\n\t\tdiscountAmount: number,\n\t\tsecondaryDiscountAmount: number,\n\t\tisShopCoverExpenses: boolean,\n\t\tcouponDetails?: Record<string, any>\n\t): CouponValidationOutputDTO {\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\tcouponDetails,\n\t\t};\n\t}\n\n\tpublic async validateShopEligibility({ data, coupon }: { data: ValidateCouponDTO; coupon: any }) {\n\t\tconst shop = await this.shopModel.findOne({\n\t\t\t_id: new mongoose.Types.ObjectId(data.shop),\n\t\t\tdeletedAt: null,\n\t\t});\n\n\t\tif (!shop) return { isValid: false, message: 'Shop not found' };\n\n\t\tconst singleShopError = await this.validateSingleShopRestriction(shop, coupon);\n\t\tif (singleShopError) return singleShopError;\n\n\t\tconst restrictionError = this.validateMultiRestrictions(shop, coupon);\n\t\tif (restrictionError) return restrictionError;\n\n\t\tconst firstOrderError = await this.validateFirstOrderOnly(data, shop, coupon);\n\t\tif (firstOrderError) return firstOrderError;\n\n\t\treturn { isValid: true, shop };\n\t}\n\n\tprivate async validateSingleShopRestriction(shop: any, coupon: any) {\n\t\tif (!coupon.shop) return null;\n\n\t\tconst couponShopId = coupon.shop.toString();\n\t\tconst currentShopId = shop._id.toString();\n\n\t\tif (couponShopId === currentShopId) return null;\n\n\t\tconst validShop = await this.shopModel.findOne({ _id: coupon.shop, deletedAt: null }).select('name');\n\n\t\tif (!validShop) {\n\t\t\treturn {\n\t\t\t\tisValid: false,\n\t\t\t\tmessage: 'Coupon is associated with an invalid shop',\n\t\t\t};\n\t\t}\n\n\t\treturn {\n\t\t\tisValid: false,\n\t\t\tmessage: `This coupon can be used at ${validShop.name} only`,\n\t\t};\n\t}\n\n\tprivate validateMultiRestrictions(shop: any, coupon: any) {\n\t\tconst hasShopRestriction = Array.isArray(coupon.shops) && coupon.shops.length > 0;\n\t\tconst hasItemTypeRestriction = Array.isArray(coupon.itemTypes) && coupon.itemTypes.length > 0;\n\n\t\tif (!hasShopRestriction && !hasItemTypeRestriction) return null;\n\n\t\tconst shopMatches =\n\t\t\thasShopRestriction &&\n\t\t\tcoupon.shops.some((couponShop: any) => couponShop._id.toString() === shop._id.toString());\n\n\t\tconst itemTypeMatches = hasItemTypeRestriction && coupon.itemTypes.includes(shop.itemType);\n\n\t\tif (!shopMatches && !itemTypeMatches) {\n\t\t\tconst shopNames = coupon.shops.map((shop: any) => shop.name).join(', ');\n\t\t\treturn {\n\t\t\t\tisValid: false,\n\t\t\t\tmessage: `This coupon can be used at ${shopNames}`,\n\t\t\t};\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tprivate async validateFirstOrderOnly(data: ValidateCouponDTO, shop: any, coupon: any) {\n\t\tif (!coupon.firstOrderOnly) return null;\n\n\t\tconst existingOrder = await this.orderModel.exists({\n\t\t\tuser: new mongoose.Types.ObjectId(data.user),\n\t\t\tshop: shop._id,\n\t\t\tstatus: { $ne: RegularOrderStatus.CANCELLED },\n\t\t});\n\n\t\tif (existingOrder) {\n\t\t\treturn {\n\t\t\t\tisValid: false,\n\t\t\t\tmessage: 'This coupon is only valid for the first order in the shop',\n\t\t\t};\n\t\t}\n\n\t\treturn null;\n\t}\n\n\tpublic async fetchUserName(userId: mongoose.Types.ObjectId): Promise<string> {\n\t\tconst user = await this.userModel.findById(userId).select('coreUser').lean();\n\n\t\tif (!user) return 'Unknown User';\n\n\t\tconst coreUser = await this.coreUserModel.findById(user.coreUser).select('name').lean();\n\n\t\treturn coreUser ? coreUser.name : 'Unknown User';\n\t}\n}\n\nexport const couponHelperService = Container.get(CouponHelperService);\n"]}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import { ItemType, OrderType, RegularOrderStatus } from '@lyxa.ai/core/dist/utilities/enum';
|
|
2
|
+
import { CouponMetricsOutputDTO, DateInputDTO, GraphInputDTO } from '../../../../coupon/validations/coupon.validation';
|
|
3
|
+
export declare class CouponMetricsRepository {
|
|
4
|
+
private readonly model;
|
|
5
|
+
private orderModel;
|
|
6
|
+
constructor();
|
|
7
|
+
private getBaseCouponFilter;
|
|
8
|
+
private getCouponCreatedWithinDateRangeFilter;
|
|
9
|
+
private getCouponOrderMatch;
|
|
10
|
+
private getActiveCouponsCount;
|
|
11
|
+
private getTotalCreatedCoupons;
|
|
12
|
+
private getCouponUsageMetrics;
|
|
13
|
+
getCouponMetricsByType(duration: DateInputDTO): Promise<any[]>;
|
|
14
|
+
private getCouponTypeTitle;
|
|
15
|
+
private fillMissingRows;
|
|
16
|
+
private compareCouponTypes;
|
|
17
|
+
private calculateRedemptionRate;
|
|
18
|
+
getCouponMetrics(duration: DateInputDTO): Promise<CouponMetricsOutputDTO>;
|
|
19
|
+
getOrderGraphMatchStage(startDate: Date, endDate: Date, itemType?: ItemType): {
|
|
20
|
+
itemType?: ItemType | undefined;
|
|
21
|
+
placedAt: {
|
|
22
|
+
$gte: Date;
|
|
23
|
+
$lte: Date;
|
|
24
|
+
};
|
|
25
|
+
orderType: OrderType;
|
|
26
|
+
status: RegularOrderStatus;
|
|
27
|
+
};
|
|
28
|
+
getCouponOrdersGraphData(data: GraphInputDTO): Promise<any[]>;
|
|
29
|
+
getUsersNewVsReturningGraphData(data: GraphInputDTO): Promise<any[]>;
|
|
30
|
+
getCouponProfitGraphData(data: GraphInputDTO): Promise<any[]>;
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=CouponMetricsRepository.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CouponMetricsRepository.d.ts","sourceRoot":"/","sources":["modules/coupon/services/patterns/repository/CouponMetricsRepository.ts"],"names":[],"mappings":"AAGA,OAAO,EAGN,QAAQ,EACR,SAAS,EACT,kBAAkB,EAElB,MAAM,mCAAmC,CAAC;AAG3C,OAAO,EAEN,sBAAsB,EACtB,YAAY,EACZ,aAAa,EACb,MAAM,+CAA+C,CAAC;AAIvD,qBAAa,uBAAuB;IACnC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqB;IAC3C,OAAO,CAAC,UAAU,CAAoB;;IAOtC,OAAO,CAAC,mBAAmB;IAQ3B,OAAO,CAAC,qCAAqC;IAa7C,OAAO,CAAC,mBAAmB;YAWb,qBAAqB;YASrB,sBAAsB;YAQtB,qBAAqB;IA+DtB,sBAAsB,CAAC,QAAQ,EAAE,YAAY;IA4I1D,OAAO,CAAC,kBAAkB;IAa1B,OAAO,CAAC,eAAe;IAwBvB,OAAO,CAAC,kBAAkB;IAW1B,OAAO,CAAC,uBAAuB;IAQlB,gBAAgB,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,sBAAsB,CAAC;IA+B/E,uBAAuB,CAAC,SAAS,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE,QAAQ;;;;;;;;;IAgBrE,wBAAwB,CAAC,IAAI,EAAE,aAAa;IAiE5C,+BAA+B,CAAC,IAAI,EAAE,aAAa;IA2HnD,wBAAwB,CAAC,IAAI,EAAE,aAAa;CAwDzD"}
|