@lyxa.ai/marketing 1.0.63 → 1.0.65
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 +0 -1
- package/dist/lib/event/event-initializations.js.map +1 -1
- package/dist/lib/event/event-listeners/event-listeners.d.ts +0 -1
- package/dist/lib/event/event-listeners/event-listeners.d.ts.map +1 -1
- package/dist/lib/event/event-listeners/event-listeners.js +12 -62
- package/dist/lib/event/event-listeners/event-listeners.js.map +1 -1
- package/dist/lib/event/events/marketing-product-seed.event.d.ts +2 -1
- package/dist/lib/event/events/marketing-product-seed.event.d.ts.map +1 -1
- package/dist/lib/event/events/marketing-product-seed.event.js.map +1 -1
- package/dist/lib/index.d.ts +21 -12028
- package/dist/lib/index.d.ts.map +1 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/modules/coupon/routers/coupon.router.d.ts +1101 -27
- package/dist/lib/modules/coupon/routers/coupon.router.d.ts.map +1 -1
- package/dist/lib/modules/coupon/services/coupon.service.d.ts +1 -1
- package/dist/lib/modules/coupon/services/coupon.service.js +1 -1
- package/dist/lib/modules/coupon/services/coupon.service.js.map +1 -1
- package/dist/lib/modules/coupon/services/custom-coupon.service.d.ts +15 -3
- package/dist/lib/modules/coupon/services/custom-coupon.service.d.ts.map +1 -1
- package/dist/lib/modules/coupon/services/helper.service.d.ts +15 -3
- package/dist/lib/modules/coupon/services/helper.service.d.ts.map +1 -1
- package/dist/lib/modules/coupon/services/individual-store-coupon.service.d.ts +15 -3
- package/dist/lib/modules/coupon/services/individual-store-coupon.service.d.ts.map +1 -1
- package/dist/lib/modules/coupon/services/patterns/repository/CouponMetricsRepository.d.ts.map +1 -1
- package/dist/lib/modules/coupon/services/patterns/repository/CouponMetricsRepository.js +21 -6
- package/dist/lib/modules/coupon/services/patterns/repository/CouponMetricsRepository.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 +1 -0
- package/dist/lib/modules/coupon/services/referral-reward-coupon.service.js.map +1 -1
- package/dist/lib/modules/coupon/services/shops-categories-coupon.service.d.ts +15 -3
- package/dist/lib/modules/coupon/services/shops-categories-coupon.service.d.ts.map +1 -1
- package/dist/lib/modules/coupon/transformers/coupon.transformer.d.ts +50 -0
- package/dist/lib/modules/coupon/transformers/coupon.transformer.d.ts.map +1 -1
- package/dist/lib/modules/coupon/validations/all-coupons.validation.d.ts +828 -6
- package/dist/lib/modules/coupon/validations/all-coupons.validation.d.ts.map +1 -1
- package/dist/lib/modules/coupon/validations/coupon.validation.d.ts +30 -30
- package/dist/lib/modules/coupon/validations/create-coupon.validation.d.ts +98 -0
- package/dist/lib/modules/coupon/validations/create-coupon.validation.d.ts.map +1 -1
- package/dist/lib/modules/coupon/validations/referral-reward-coupon.validation.d.ts +374 -0
- package/dist/lib/modules/coupon/validations/referral-reward-coupon.validation.d.ts.map +1 -1
- package/dist/lib/modules/coupon/validations/referral-reward-coupon.validation.js +2 -0
- package/dist/lib/modules/coupon/validations/referral-reward-coupon.validation.js.map +1 -1
- package/dist/lib/modules/deal-setting/routers/deal-setting.router.d.ts +9 -9
- package/dist/lib/modules/deal-setting/routers/deal-setting.router.d.ts.map +1 -1
- package/dist/lib/modules/deal-setting/validations/deal-setting.validation.d.ts +6 -6
- package/dist/lib/modules/featured-setting/routers/featured-setting.router.d.ts +8 -8
- package/dist/lib/modules/featured-setting/routers/featured-setting.router.d.ts.map +1 -1
- package/dist/lib/modules/featured-setting/validations/featured-setting.validation.d.ts +6 -6
- package/dist/lib/modules/limited-time-offer/campaign/campaign.router.d.ts +7 -7
- package/dist/lib/modules/limited-time-offer/campaign/campaign.router.d.ts.map +1 -1
- package/dist/lib/modules/limited-time-offer/campaign/campaign.router.js +2 -0
- package/dist/lib/modules/limited-time-offer/campaign/campaign.router.js.map +1 -1
- package/dist/lib/modules/limited-time-offer/campaign/jobs/index.d.ts.map +1 -1
- package/dist/lib/modules/limited-time-offer/campaign/jobs/index.js +4 -1
- package/dist/lib/modules/limited-time-offer/campaign/jobs/index.js.map +1 -1
- package/dist/lib/modules/limited-time-offer/campaign/limited-time-offer-campaign.validation.d.ts +36 -36
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.d.ts +2 -0
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.d.ts.map +1 -1
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.js +24 -5
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.js.map +1 -1
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.d.ts +1 -0
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.d.ts.map +1 -1
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.js +13 -2
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.js.map +1 -1
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.d.ts.map +1 -1
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.js +10 -1
- package/dist/lib/modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.js.map +1 -1
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer-config.validation.d.ts +6 -6
- package/dist/lib/modules/limited-time-offer/config/limited-time-offer.router.d.ts +3 -3
- package/dist/lib/modules/limited-time-offer/limited-time-offer.router.d.ts +18 -18
- package/dist/lib/modules/limited-time-offer/limited-time-offer.service.d.ts.map +1 -1
- package/dist/lib/modules/limited-time-offer/limited-time-offer.service.js +6 -9
- package/dist/lib/modules/limited-time-offer/limited-time-offer.service.js.map +1 -1
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.builder.d.ts +7 -1
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.builder.d.ts.map +1 -1
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.builder.js +5 -1
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.builder.js.map +1 -1
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.repository.d.ts +8 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.repository.d.ts.map +1 -1
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.repository.js +60 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.repository.js.map +1 -1
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.router.d.ts +7 -7
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.router.d.ts.map +1 -1
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.router.js +5 -0
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.router.js.map +1 -1
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.validation.d.ts +235 -231
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.validation.d.ts.map +1 -1
- package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.validation.js.map +1 -1
- package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant-marketing.service.d.ts +4 -0
- package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant-marketing.service.d.ts.map +1 -1
- package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant-marketing.service.js +14 -8
- package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant-marketing.service.js.map +1 -1
- package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.d.ts +11 -9
- package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.d.ts.map +1 -1
- package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.js +78 -46
- package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.js.map +1 -1
- package/dist/lib/modules/marketing/patterns/repository/MarketingMetricsRepository.d.ts +1 -0
- package/dist/lib/modules/marketing/patterns/repository/MarketingMetricsRepository.d.ts.map +1 -1
- package/dist/lib/modules/marketing/patterns/repository/MarketingMetricsRepository.js +15 -3
- package/dist/lib/modules/marketing/patterns/repository/MarketingMetricsRepository.js.map +1 -1
- package/dist/lib/modules/marketing/routers/marketing.router.d.ts +16 -3
- package/dist/lib/modules/marketing/routers/marketing.router.d.ts.map +1 -1
- package/dist/lib/modules/marketing/routers/marketing.router.js +4 -0
- package/dist/lib/modules/marketing/routers/marketing.router.js.map +1 -1
- package/dist/lib/modules/marketing/services/marketing.service.d.ts +1 -2
- package/dist/lib/modules/marketing/services/marketing.service.d.ts.map +1 -1
- package/dist/lib/modules/marketing/services/marketing.service.js +88 -70
- package/dist/lib/modules/marketing/services/marketing.service.js.map +1 -1
- package/dist/lib/modules/marketing/services/product-marketing.service.d.ts +3 -1
- package/dist/lib/modules/marketing/services/product-marketing.service.d.ts.map +1 -1
- package/dist/lib/modules/marketing/services/product-marketing.service.js +13 -10
- package/dist/lib/modules/marketing/services/product-marketing.service.js.map +1 -1
- package/dist/lib/modules/marketing/services/spend-to-get-progress.service.d.ts +13 -0
- package/dist/lib/modules/marketing/services/spend-to-get-progress.service.d.ts.map +1 -1
- package/dist/lib/modules/marketing/services/spend-to-get-progress.service.js +24 -0
- package/dist/lib/modules/marketing/services/spend-to-get-progress.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 +27 -95
- package/dist/lib/modules/marketing/services/synchronize-product-marketing.service.js.map +1 -1
- package/dist/lib/modules/marketing/validations/all-marketings.validation.d.ts +4 -4
- package/dist/lib/modules/marketing/validations/marketing.validation.d.ts +14 -0
- package/dist/lib/modules/marketing/validations/marketing.validation.d.ts.map +1 -1
- package/dist/lib/modules/marketing/validations/marketing.validation.js +6 -1
- package/dist/lib/modules/marketing/validations/marketing.validation.js.map +1 -1
- package/dist/lib/modules/marketing/validations/punch-marketing.validation.d.ts +4 -4
- package/dist/lib/modules/punch-marketing-history/routers/punch-marketing-history.router.d.ts +11 -11
- 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 +6 -6
- package/dist/lib/modules/referral-setting/routers/referral-setting.router.d.ts +4 -4
- package/dist/lib/modules/referral-setting/validations/referral-setting.validation.d.ts +6 -6
- package/dist/lib/modules/referral-setting/validations/referral-setting.validation.d.ts.map +1 -1
- package/dist/lib/modules/referral-setting/validations/referral-setting.validation.js.map +1 -1
- package/dist/lib/modules/spend-to-get-history/spend-to-get-history.repository.d.ts +3 -2
- package/dist/lib/modules/spend-to-get-history/spend-to-get-history.repository.d.ts.map +1 -1
- package/dist/lib/modules/spend-to-get-history/spend-to-get-history.repository.js +21 -2
- package/dist/lib/modules/spend-to-get-history/spend-to-get-history.repository.js.map +1 -1
- package/dist/lib/modules/spend-to-get-history/spend-to-get-history.router.d.ts +42 -26
- package/dist/lib/modules/spend-to-get-history/spend-to-get-history.router.d.ts.map +1 -1
- package/dist/lib/modules/spend-to-get-history/spend-to-get-history.service.d.ts +2 -2
- package/dist/lib/modules/spend-to-get-history/spend-to-get-history.service.d.ts.map +1 -1
- package/dist/lib/modules/spend-to-get-history/spend-to-get-history.service.js.map +1 -1
- package/dist/lib/modules/spend-to-get-history/spend-to-get-history.validation.d.ts +44 -25
- package/dist/lib/modules/spend-to-get-history/spend-to-get-history.validation.d.ts.map +1 -1
- package/dist/lib/modules/spend-to-get-history/spend-to-get-history.validation.js +2 -1
- package/dist/lib/modules/spend-to-get-history/spend-to-get-history.validation.js.map +1 -1
- package/dist/lib/modules/tournament/config/config.router.d.ts +4 -4
- package/dist/lib/modules/tournament/config/config.validation.d.ts +12 -12
- package/dist/lib/modules/tournament/match/match.router.d.ts +5 -5
- package/dist/lib/modules/tournament/match/match.validation.d.ts +12 -12
- package/dist/lib/modules/tournament/participant/participant.router.d.ts +3 -3
- package/dist/lib/modules/tournament/participant/participant.validation.d.ts +24 -24
- package/dist/lib/modules/tournament/prediction/prediction.router.d.ts +3 -3
- package/dist/lib/modules/tournament/prediction/prediction.validation.d.ts +18 -18
- package/dist/lib/modules/tournament/score/score.router.d.ts +1 -1
- package/dist/lib/modules/tournament/score/score.validation.d.ts +6 -6
- package/dist/lib/modules/tournament/statistics/statistics.router.d.ts +1 -1
- package/dist/lib/modules/tournament/statistics/statistics.validation.d.ts +6 -6
- package/dist/lib/modules/tournament/team/team.router.d.ts +3 -3
- package/dist/lib/modules/tournament/team/team.validation.d.ts +18 -18
- package/dist/lib/modules/tournament/tournament.router.d.ts +21 -21
- package/dist/lib/modules/tournament/tournament.validation.d.ts +6 -6
- package/dist/lib/utility/feature-flags.d.ts +3 -0
- package/dist/lib/utility/feature-flags.d.ts.map +1 -0
- package/dist/lib/utility/feature-flags.js +16 -0
- package/dist/lib/utility/feature-flags.js.map +1 -0
- package/dist/types/event/event-initializations.d.ts.map +1 -1
- package/dist/types/event/event-listeners/event-listeners.d.ts +0 -1
- package/dist/types/event/event-listeners/event-listeners.d.ts.map +1 -1
- package/dist/types/event/events/marketing-product-seed.event.d.ts +2 -1
- package/dist/types/event/events/marketing-product-seed.event.d.ts.map +1 -1
- package/dist/types/index.d.ts +21 -12028
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/modules/coupon/routers/coupon.router.d.ts +1101 -27
- package/dist/types/modules/coupon/routers/coupon.router.d.ts.map +1 -1
- package/dist/types/modules/coupon/services/coupon.service.d.ts +1 -1
- package/dist/types/modules/coupon/services/custom-coupon.service.d.ts +15 -3
- package/dist/types/modules/coupon/services/custom-coupon.service.d.ts.map +1 -1
- package/dist/types/modules/coupon/services/helper.service.d.ts +15 -3
- package/dist/types/modules/coupon/services/helper.service.d.ts.map +1 -1
- package/dist/types/modules/coupon/services/individual-store-coupon.service.d.ts +15 -3
- package/dist/types/modules/coupon/services/individual-store-coupon.service.d.ts.map +1 -1
- package/dist/types/modules/coupon/services/patterns/repository/CouponMetricsRepository.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/services/shops-categories-coupon.service.d.ts +15 -3
- package/dist/types/modules/coupon/services/shops-categories-coupon.service.d.ts.map +1 -1
- package/dist/types/modules/coupon/transformers/coupon.transformer.d.ts +50 -0
- package/dist/types/modules/coupon/transformers/coupon.transformer.d.ts.map +1 -1
- package/dist/types/modules/coupon/validations/all-coupons.validation.d.ts +828 -6
- package/dist/types/modules/coupon/validations/all-coupons.validation.d.ts.map +1 -1
- package/dist/types/modules/coupon/validations/coupon.validation.d.ts +30 -30
- package/dist/types/modules/coupon/validations/create-coupon.validation.d.ts +98 -0
- package/dist/types/modules/coupon/validations/create-coupon.validation.d.ts.map +1 -1
- package/dist/types/modules/coupon/validations/referral-reward-coupon.validation.d.ts +374 -0
- package/dist/types/modules/coupon/validations/referral-reward-coupon.validation.d.ts.map +1 -1
- package/dist/types/modules/deal-setting/routers/deal-setting.router.d.ts +9 -9
- package/dist/types/modules/deal-setting/routers/deal-setting.router.d.ts.map +1 -1
- package/dist/types/modules/deal-setting/validations/deal-setting.validation.d.ts +6 -6
- package/dist/types/modules/featured-setting/routers/featured-setting.router.d.ts +8 -8
- package/dist/types/modules/featured-setting/routers/featured-setting.router.d.ts.map +1 -1
- package/dist/types/modules/featured-setting/validations/featured-setting.validation.d.ts +6 -6
- package/dist/types/modules/limited-time-offer/campaign/campaign.router.d.ts +7 -7
- package/dist/types/modules/limited-time-offer/campaign/campaign.router.d.ts.map +1 -1
- package/dist/types/modules/limited-time-offer/campaign/jobs/index.d.ts.map +1 -1
- package/dist/types/modules/limited-time-offer/campaign/limited-time-offer-campaign.validation.d.ts +36 -36
- package/dist/types/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.d.ts +2 -0
- package/dist/types/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-lifecycle.service.d.ts.map +1 -1
- package/dist/types/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.d.ts +1 -0
- package/dist/types/modules/limited-time-offer/campaign/services/limited-time-offer-campaign-scheduler.service.d.ts.map +1 -1
- package/dist/types/modules/limited-time-offer/campaign/services/limited-time-offer-campaign.service.d.ts.map +1 -1
- package/dist/types/modules/limited-time-offer/config/limited-time-offer-config.validation.d.ts +6 -6
- package/dist/types/modules/limited-time-offer/config/limited-time-offer.router.d.ts +3 -3
- package/dist/types/modules/limited-time-offer/limited-time-offer.router.d.ts +18 -18
- package/dist/types/modules/limited-time-offer/limited-time-offer.service.d.ts.map +1 -1
- package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.builder.d.ts +7 -1
- package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.builder.d.ts.map +1 -1
- package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.repository.d.ts +8 -0
- package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.repository.d.ts.map +1 -1
- package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.router.d.ts +7 -7
- package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.router.d.ts.map +1 -1
- package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.validation.d.ts +235 -231
- package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.validation.d.ts.map +1 -1
- package/dist/types/modules/limited-time-offer/participant/services/limited-time-offer-participant-marketing.service.d.ts +4 -0
- package/dist/types/modules/limited-time-offer/participant/services/limited-time-offer-participant-marketing.service.d.ts.map +1 -1
- package/dist/types/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.d.ts +11 -9
- package/dist/types/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.d.ts.map +1 -1
- package/dist/types/modules/marketing/patterns/repository/MarketingMetricsRepository.d.ts +1 -0
- package/dist/types/modules/marketing/patterns/repository/MarketingMetricsRepository.d.ts.map +1 -1
- package/dist/types/modules/marketing/routers/marketing.router.d.ts +16 -3
- package/dist/types/modules/marketing/routers/marketing.router.d.ts.map +1 -1
- package/dist/types/modules/marketing/services/marketing.service.d.ts +1 -2
- package/dist/types/modules/marketing/services/marketing.service.d.ts.map +1 -1
- package/dist/types/modules/marketing/services/product-marketing.service.d.ts +3 -1
- package/dist/types/modules/marketing/services/product-marketing.service.d.ts.map +1 -1
- package/dist/types/modules/marketing/services/spend-to-get-progress.service.d.ts +18 -0
- package/dist/types/modules/marketing/services/spend-to-get-progress.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/validations/all-marketings.validation.d.ts +4 -4
- package/dist/types/modules/marketing/validations/marketing.validation.d.ts +14 -0
- package/dist/types/modules/marketing/validations/marketing.validation.d.ts.map +1 -1
- package/dist/types/modules/marketing/validations/punch-marketing.validation.d.ts +4 -4
- package/dist/types/modules/punch-marketing-history/routers/punch-marketing-history.router.d.ts +11 -11
- 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 +6 -6
- package/dist/types/modules/referral-setting/routers/referral-setting.router.d.ts +4 -4
- package/dist/types/modules/referral-setting/validations/referral-setting.validation.d.ts +6 -6
- package/dist/types/modules/referral-setting/validations/referral-setting.validation.d.ts.map +1 -1
- package/dist/types/modules/spend-to-get-history/spend-to-get-history.repository.d.ts +3 -2
- package/dist/types/modules/spend-to-get-history/spend-to-get-history.repository.d.ts.map +1 -1
- package/dist/types/modules/spend-to-get-history/spend-to-get-history.router.d.ts +42 -26
- package/dist/types/modules/spend-to-get-history/spend-to-get-history.router.d.ts.map +1 -1
- package/dist/types/modules/spend-to-get-history/spend-to-get-history.service.d.ts +2 -2
- package/dist/types/modules/spend-to-get-history/spend-to-get-history.service.d.ts.map +1 -1
- package/dist/types/modules/spend-to-get-history/spend-to-get-history.validation.d.ts +44 -25
- package/dist/types/modules/spend-to-get-history/spend-to-get-history.validation.d.ts.map +1 -1
- package/dist/types/modules/tournament/config/config.router.d.ts +4 -4
- package/dist/types/modules/tournament/config/config.validation.d.ts +12 -12
- package/dist/types/modules/tournament/match/match.router.d.ts +5 -5
- package/dist/types/modules/tournament/match/match.validation.d.ts +12 -12
- package/dist/types/modules/tournament/participant/participant.router.d.ts +3 -3
- package/dist/types/modules/tournament/participant/participant.validation.d.ts +24 -24
- package/dist/types/modules/tournament/prediction/prediction.router.d.ts +3 -3
- package/dist/types/modules/tournament/prediction/prediction.validation.d.ts +18 -18
- package/dist/types/modules/tournament/score/score.router.d.ts +1 -1
- package/dist/types/modules/tournament/score/score.validation.d.ts +6 -6
- package/dist/types/modules/tournament/statistics/statistics.router.d.ts +1 -1
- package/dist/types/modules/tournament/statistics/statistics.validation.d.ts +6 -6
- package/dist/types/modules/tournament/team/team.router.d.ts +3 -3
- package/dist/types/modules/tournament/team/team.validation.d.ts +18 -18
- package/dist/types/modules/tournament/tournament.router.d.ts +21 -21
- package/dist/types/modules/tournament/tournament.validation.d.ts +6 -6
- package/dist/types/utility/feature-flags.d.ts +12 -0
- package/dist/types/utility/feature-flags.d.ts.map +1 -0
- package/package.json +2 -2
|
@@ -55,14 +55,13 @@ const admin_logs_event_1 = require("@lyxa.ai/core/dist/libraries/event/events/ad
|
|
|
55
55
|
const enum_1 = require("@lyxa.ai/core/dist/utilities/enum");
|
|
56
56
|
const event_1 = require("@lyxa.ai/core/dist/libraries/event");
|
|
57
57
|
const marketing_product_seed_event_1 = require("../../../event/events/marketing-product-seed.event");
|
|
58
|
-
const marketing_product_sync_event_1 = require("../../../event/events/marketing-product-sync.event");
|
|
59
58
|
const _1 = require(".");
|
|
60
|
-
const enum_2 = require("@lyxa.ai/core/dist/utilities/enum");
|
|
61
59
|
const error_common_1 = require("@lyxa.ai/core/dist/utilities/error-common");
|
|
62
60
|
const mongo_stream_changes_batch_process_shops_event_1 = require("@lyxa.ai/core/dist/libraries/event/events/mongo-stream-changes-batch-process-shops-event");
|
|
63
61
|
const MarketingMetricsRepository_1 = require("../patterns/repository/MarketingMetricsRepository");
|
|
64
62
|
const marketing_product_sync_queue_1 = require("../queues/marketing-product-sync.queue");
|
|
65
63
|
const limited_time_offer_participant_service_1 = require("../../limited-time-offer/participant/services/limited-time-offer-participant.service");
|
|
64
|
+
const feature_flags_1 = require("../../../utility/feature-flags");
|
|
66
65
|
let MarketingService = class MarketingService {
|
|
67
66
|
model;
|
|
68
67
|
shopModel;
|
|
@@ -79,20 +78,25 @@ let MarketingService = class MarketingService {
|
|
|
79
78
|
}
|
|
80
79
|
async create(data, admin, options) {
|
|
81
80
|
const now = (0, dayjs_1.dayjs)().toDate();
|
|
82
|
-
|
|
83
|
-
|
|
81
|
+
const ltoScheduleEnabled = await (0, feature_flags_1.isLtoScheduleEnabled)();
|
|
82
|
+
if (ltoScheduleEnabled &&
|
|
83
|
+
!options?.skipLimitedTimeOfferGuard &&
|
|
84
|
+
data.marketingType === enum_1.MarketingType.DISCOUNT &&
|
|
84
85
|
(await limited_time_offer_participant_service_1.ltoParticipantService.isActiveParticipant(data.shop))) {
|
|
85
86
|
(0, error_common_1.forbiddenError)('You are currently participating in a Limited Time Offer. Please manage your discount from the Limited Time Offer section or withdraw first.');
|
|
86
87
|
}
|
|
87
|
-
const
|
|
88
|
+
const existingRecordQuery = {
|
|
88
89
|
shop: data.shop,
|
|
89
90
|
marketingType: data.marketingType,
|
|
90
91
|
'duration.end': { $gt: now },
|
|
91
92
|
status: enum_1.MarketingStatus.ACTIVE,
|
|
92
93
|
isAppliedByCompany: data.isAppliedByCompany,
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
};
|
|
95
|
+
if (ltoScheduleEnabled) {
|
|
96
|
+
existingRecordQuery.campaignType = data.campaignType;
|
|
97
|
+
existingRecordQuery.admin = admin ? { $ne: null } : null;
|
|
98
|
+
}
|
|
99
|
+
const existingRecord = await this.model.findOne(existingRecordQuery);
|
|
96
100
|
if (existingRecord) {
|
|
97
101
|
throw new server_1.TRPCError({
|
|
98
102
|
code: 'CONFLICT',
|
|
@@ -113,7 +117,7 @@ let MarketingService = class MarketingService {
|
|
|
113
117
|
'duration.start': { $lt: now },
|
|
114
118
|
'duration.end': { $gt: now },
|
|
115
119
|
status: enum_1.MarketingStatus.ACTIVE,
|
|
116
|
-
marketingType: { $in: [
|
|
120
|
+
marketingType: { $in: [enum_1.MarketingType.BUY1GET1, enum_1.MarketingType.DISCOUNT], $ne: data.marketingType },
|
|
117
121
|
});
|
|
118
122
|
if (existingMarketing) {
|
|
119
123
|
throw new server_1.TRPCError({
|
|
@@ -131,7 +135,7 @@ let MarketingService = class MarketingService {
|
|
|
131
135
|
message: `Product list contains duplicate products`,
|
|
132
136
|
});
|
|
133
137
|
}
|
|
134
|
-
if (data.campaignType === enum_1.MarketingCampaignType.LIMITED_TIME_OFFER) {
|
|
138
|
+
if (ltoScheduleEnabled && data.campaignType === enum_1.MarketingCampaignType.LIMITED_TIME_OFFER) {
|
|
135
139
|
await _1.productMarketingService.pauseConflictingMarketings(productIds);
|
|
136
140
|
}
|
|
137
141
|
else {
|
|
@@ -149,15 +153,15 @@ let MarketingService = class MarketingService {
|
|
|
149
153
|
}
|
|
150
154
|
let marketing;
|
|
151
155
|
switch (data.marketingType) {
|
|
152
|
-
case
|
|
156
|
+
case enum_1.MarketingType.DISCOUNT: {
|
|
153
157
|
marketing = await _1.discountMarketingService.create(data);
|
|
154
158
|
break;
|
|
155
159
|
}
|
|
156
|
-
case
|
|
160
|
+
case enum_1.MarketingType.BUY1GET1: {
|
|
157
161
|
marketing = await _1.buy1Get1MarketingService.create(data);
|
|
158
162
|
break;
|
|
159
163
|
}
|
|
160
|
-
case
|
|
164
|
+
case enum_1.MarketingType.FEATURED: {
|
|
161
165
|
if (!admin) {
|
|
162
166
|
throw new server_1.TRPCError({
|
|
163
167
|
code: 'UNAUTHORIZED',
|
|
@@ -167,15 +171,15 @@ let MarketingService = class MarketingService {
|
|
|
167
171
|
marketing = await _1.featuredMarketingService.create(data);
|
|
168
172
|
break;
|
|
169
173
|
}
|
|
170
|
-
case
|
|
174
|
+
case enum_1.MarketingType.FREE_DELIVERY: {
|
|
171
175
|
marketing = await _1.freeDeliveryMarketingService.create(data);
|
|
172
176
|
break;
|
|
173
177
|
}
|
|
174
|
-
case
|
|
178
|
+
case enum_1.MarketingType.PUNCH_MARKETING: {
|
|
175
179
|
marketing = await _1.punchMarketingService.create(data);
|
|
176
180
|
break;
|
|
177
181
|
}
|
|
178
|
-
case
|
|
182
|
+
case enum_1.MarketingType.SPEND_TO_GET: {
|
|
179
183
|
marketing = await _1.spendToGetMarketingService.create(data);
|
|
180
184
|
break;
|
|
181
185
|
}
|
|
@@ -252,39 +256,41 @@ let MarketingService = class MarketingService {
|
|
|
252
256
|
if (!oldMarketing) {
|
|
253
257
|
(0, error_common_1.notFoundError)('Could not find marketing');
|
|
254
258
|
}
|
|
255
|
-
if (data.status &&
|
|
256
|
-
|
|
257
|
-
|
|
259
|
+
if (data.status &&
|
|
260
|
+
data.status === enum_1.MarketingStatus.ACTIVE &&
|
|
261
|
+
oldMarketing.status !== enum_1.MarketingStatus.ACTIVE) {
|
|
262
|
+
if ((await (0, feature_flags_1.isLtoScheduleEnabled)()) &&
|
|
263
|
+
oldMarketing.marketingType === enum_1.MarketingType.DISCOUNT &&
|
|
258
264
|
(await limited_time_offer_participant_service_1.ltoParticipantService.isActiveParticipant(oldMarketing.shop._id))) {
|
|
259
265
|
(0, error_common_1.forbiddenError)('You are currently participating in a Limited Time Offer. Please manage your discount from the Limited Time Offer section or withdraw first.');
|
|
260
266
|
}
|
|
261
267
|
await this.verifyUnpauseConditions(_id);
|
|
262
268
|
}
|
|
263
269
|
switch (oldMarketing.marketingType) {
|
|
264
|
-
case
|
|
270
|
+
case enum_1.MarketingType.DISCOUNT: {
|
|
265
271
|
marketing = await _1.discountMarketingService.update(_id, data);
|
|
266
272
|
break;
|
|
267
273
|
}
|
|
268
|
-
case
|
|
274
|
+
case enum_1.MarketingType.BUY1GET1: {
|
|
269
275
|
marketing = await _1.buy1Get1MarketingService.update(_id, data);
|
|
270
276
|
break;
|
|
271
277
|
}
|
|
272
|
-
case
|
|
278
|
+
case enum_1.MarketingType.FEATURED: {
|
|
273
279
|
if (!admin) {
|
|
274
280
|
(0, error_common_1.unauthorizedError)(`Only admin is allowed to update ${data.marketingType} marketing`);
|
|
275
281
|
}
|
|
276
282
|
marketing = await _1.featuredMarketingService.update(_id, data);
|
|
277
283
|
break;
|
|
278
284
|
}
|
|
279
|
-
case
|
|
285
|
+
case enum_1.MarketingType.FREE_DELIVERY: {
|
|
280
286
|
marketing = await _1.freeDeliveryMarketingService.update(_id, data);
|
|
281
287
|
break;
|
|
282
288
|
}
|
|
283
|
-
case
|
|
289
|
+
case enum_1.MarketingType.PUNCH_MARKETING: {
|
|
284
290
|
marketing = await _1.punchMarketingService.update(_id, data);
|
|
285
291
|
break;
|
|
286
292
|
}
|
|
287
|
-
case
|
|
293
|
+
case enum_1.MarketingType.SPEND_TO_GET: {
|
|
288
294
|
marketing = await _1.spendToGetMarketingService.update(_id, data);
|
|
289
295
|
break;
|
|
290
296
|
}
|
|
@@ -330,7 +336,18 @@ let MarketingService = class MarketingService {
|
|
|
330
336
|
const marketing = await this.model.findOne({ _id: marketingId, deletedAt: null }).populate('products');
|
|
331
337
|
if (!marketing)
|
|
332
338
|
return;
|
|
333
|
-
if (
|
|
339
|
+
if (await (0, feature_flags_1.isLtoScheduleEnabled)()) {
|
|
340
|
+
const hasActiveLto = await this.model.exists({
|
|
341
|
+
shop: marketing.shop,
|
|
342
|
+
campaignType: enum_1.MarketingCampaignType.LIMITED_TIME_OFFER,
|
|
343
|
+
status: enum_1.MarketingStatus.ACTIVE,
|
|
344
|
+
deletedAt: null,
|
|
345
|
+
});
|
|
346
|
+
if (hasActiveLto) {
|
|
347
|
+
(0, error_common_1.conflictError)("Can't resume this discount while a limited time offer is active");
|
|
348
|
+
}
|
|
349
|
+
}
|
|
350
|
+
if ([enum_1.MarketingType.BUY1GET1, enum_1.MarketingType.DISCOUNT].includes(marketing.marketingType)) {
|
|
334
351
|
const typedMarketing = marketing;
|
|
335
352
|
const productIds = typedMarketing.products.map((product) => product.product);
|
|
336
353
|
const isAvailable = await _1.productMarketingService.checkProductMarketingAvailability(productIds, marketing.isAppliedByCompany);
|
|
@@ -359,7 +376,7 @@ let MarketingService = class MarketingService {
|
|
|
359
376
|
}
|
|
360
377
|
async deleteById(data, admin, options) {
|
|
361
378
|
const { _id, softDelete } = data;
|
|
362
|
-
if (!options?.skipLimitedTimeOfferGuard) {
|
|
379
|
+
if ((await (0, feature_flags_1.isLtoScheduleEnabled)()) && !options?.skipLimitedTimeOfferGuard) {
|
|
363
380
|
const partOfLimitedTimeOffer = await this.limitedTimeOfferParticipantModel.exists({
|
|
364
381
|
marketing: _id,
|
|
365
382
|
});
|
|
@@ -425,7 +442,7 @@ let MarketingService = class MarketingService {
|
|
|
425
442
|
async handleNewProductForEntireMenuMarketing(data) {
|
|
426
443
|
const existingMarketing = await this.model.findOne({
|
|
427
444
|
shop: data.shop,
|
|
428
|
-
marketingType: { $in: [
|
|
445
|
+
marketingType: { $in: [enum_1.MarketingType.BUY1GET1, enum_1.MarketingType.DISCOUNT] },
|
|
429
446
|
'duration.end': { $gt: new Date() },
|
|
430
447
|
status: enum_1.MarketingStatus.ACTIVE,
|
|
431
448
|
isEntireMenu: true,
|
|
@@ -435,10 +452,10 @@ let MarketingService = class MarketingService {
|
|
|
435
452
|
product: data.product,
|
|
436
453
|
marketing: existingMarketing._id,
|
|
437
454
|
};
|
|
438
|
-
if (existingMarketing.marketingType ==
|
|
455
|
+
if (existingMarketing.marketingType == enum_1.MarketingType.BUY1GET1) {
|
|
439
456
|
productMarketingData.isBuy1Get1 = true;
|
|
440
457
|
}
|
|
441
|
-
if (existingMarketing.marketingType ==
|
|
458
|
+
if (existingMarketing.marketingType == enum_1.MarketingType.DISCOUNT) {
|
|
442
459
|
productMarketingData.value = existingMarketing.value;
|
|
443
460
|
productMarketingData.valueType = existingMarketing.valueType;
|
|
444
461
|
}
|
|
@@ -517,7 +534,7 @@ let MarketingService = class MarketingService {
|
|
|
517
534
|
}
|
|
518
535
|
async recomputeAndSyncAllMarketingSpent() {
|
|
519
536
|
const cursor = this.model
|
|
520
|
-
.find({ marketingType: { $ne:
|
|
537
|
+
.find({ marketingType: { $ne: enum_1.MarketingType.FEATURED } }, { _id: 1 })
|
|
521
538
|
.lean()
|
|
522
539
|
.cursor();
|
|
523
540
|
const bulkOps = [];
|
|
@@ -544,34 +561,31 @@ let MarketingService = class MarketingService {
|
|
|
544
561
|
await this.expireMarketingsExceedingSpendLimits(marketingIds);
|
|
545
562
|
await this.unExpireMarketingsBelowSpendLimits(marketingIds);
|
|
546
563
|
}
|
|
547
|
-
async publishEntireMenuSeedEvents(marketing) {
|
|
548
|
-
const PAGE_SIZE = 500;
|
|
549
|
-
const marketingId = marketing._id.toString();
|
|
550
|
-
const shopId = (marketing.shop?._id ?? marketing.shop).toString();
|
|
551
|
-
const products = await models_1.ProductModel.find({ shop: marketing.shop }).select('_id').lean();
|
|
552
|
-
const productIds = products.map((p) => p._id.toString());
|
|
553
|
-
for (let i = 0; i < productIds.length; i += PAGE_SIZE) {
|
|
554
|
-
await (0, event_1.publishEvent)(new marketing_product_seed_event_1.MarketingEntireMenuSeedEvent({
|
|
555
|
-
marketingId,
|
|
556
|
-
shopId,
|
|
557
|
-
isAppliedByCompany: marketing.isAppliedByCompany ?? false,
|
|
558
|
-
isBuy1Get1: marketing.marketingType === enum_2.MarketingType.BUY1GET1,
|
|
559
|
-
value: marketing.value,
|
|
560
|
-
valueType: marketing.valueType,
|
|
561
|
-
productIds: productIds.slice(i, i + PAGE_SIZE),
|
|
562
|
-
}));
|
|
563
|
-
}
|
|
564
|
-
return productIds.length;
|
|
565
|
-
}
|
|
566
564
|
async reseedEntireMenuMarketing(marketingId) {
|
|
567
565
|
const logger = (0, core_1.getLibraries)().getLoggerKit();
|
|
568
566
|
const marketing = await this.model.findOne({ _id: marketingId, deletedAt: null });
|
|
569
567
|
if (!marketing)
|
|
570
568
|
(0, error_common_1.internalServerError)('Marketing not found');
|
|
571
|
-
const
|
|
572
|
-
|
|
569
|
+
const PAGE_SIZE = 500;
|
|
570
|
+
const mid = marketingId.toString();
|
|
571
|
+
const shopId = (marketing.shop?._id ?? marketing.shop).toString();
|
|
572
|
+
const count = await models_1.ProductModel.countDocuments({ shop: marketing.shop });
|
|
573
|
+
const pages = Math.ceil(count / PAGE_SIZE);
|
|
574
|
+
if (!pages)
|
|
575
|
+
return;
|
|
576
|
+
await Promise.all(Array.from({ length: pages }, (_, page) => (0, event_1.publishEvent)(new marketing_product_seed_event_1.MarketingEntireMenuSeedEvent({
|
|
577
|
+
marketingId: mid,
|
|
578
|
+
shopId,
|
|
579
|
+
isAppliedByCompany: marketing.isAppliedByCompany ?? false,
|
|
580
|
+
isBuy1Get1: marketing.marketingType === enum_1.MarketingType.BUY1GET1,
|
|
581
|
+
value: marketing.value,
|
|
582
|
+
valueType: marketing.valueType,
|
|
583
|
+
page,
|
|
584
|
+
pageSize: PAGE_SIZE,
|
|
585
|
+
}))));
|
|
586
|
+
logger.debug(`entire-menu reseed dispatched — ${pages} pages for ${count} products`, {
|
|
573
587
|
tag: 'marketing.seed.entire-menu',
|
|
574
|
-
data: { marketingId:
|
|
588
|
+
data: { marketingId: mid, shopId, pages, productCount: count },
|
|
575
589
|
});
|
|
576
590
|
}
|
|
577
591
|
async assignMarketingToProducts(marketing) {
|
|
@@ -581,27 +595,31 @@ let MarketingService = class MarketingService {
|
|
|
581
595
|
}
|
|
582
596
|
if (marketing.isEntireMenu) {
|
|
583
597
|
const logger = (0, core_1.getLibraries)().getLoggerKit();
|
|
584
|
-
const productCount = await this.publishEntireMenuSeedEvents(marketing);
|
|
585
|
-
logger.debug(`entire-menu marketing seed dispatched — ${productCount} products`, {
|
|
586
|
-
tag: 'marketing.seed.entire-menu',
|
|
587
|
-
data: { marketingId: marketing._id.toString(), productCount },
|
|
588
|
-
});
|
|
589
|
-
}
|
|
590
|
-
else {
|
|
591
|
-
const shopId = (marketing.shop?._id ?? marketing.shop).toString();
|
|
592
|
-
const pms = await models_1.ProductMarketingModel.find({ marketing: marketing._id, deletedAt: null })
|
|
593
|
-
.select('product')
|
|
594
|
-
.lean();
|
|
595
|
-
const productIds = pms.map((p) => p.product.toString());
|
|
596
598
|
const PAGE_SIZE = 500;
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
599
|
+
const marketingId = marketing._id.toString();
|
|
600
|
+
const shopId = (marketing.shop?._id ?? marketing.shop).toString();
|
|
601
|
+
const count = await models_1.ProductModel.countDocuments({ shop: marketing.shop });
|
|
602
|
+
const pages = Math.ceil(count / PAGE_SIZE);
|
|
603
|
+
if (pages > 0) {
|
|
604
|
+
await Promise.all(Array.from({ length: pages }, (_, page) => (0, event_1.publishEvent)(new marketing_product_seed_event_1.MarketingEntireMenuSeedEvent({
|
|
605
|
+
marketingId,
|
|
600
606
|
shopId,
|
|
601
|
-
|
|
602
|
-
|
|
607
|
+
isAppliedByCompany: marketing.isAppliedByCompany ?? false,
|
|
608
|
+
isBuy1Get1: marketing.marketingType === enum_1.MarketingType.BUY1GET1,
|
|
609
|
+
value: marketing.value,
|
|
610
|
+
valueType: marketing.valueType,
|
|
611
|
+
page,
|
|
612
|
+
pageSize: PAGE_SIZE,
|
|
613
|
+
}))));
|
|
614
|
+
logger.debug(`entire-menu marketing seed dispatched — ${pages} pages for ${count} products`, {
|
|
615
|
+
tag: 'marketing.seed.entire-menu',
|
|
616
|
+
data: { marketingId, shopId, pages, productCount: count },
|
|
617
|
+
});
|
|
603
618
|
}
|
|
604
619
|
}
|
|
620
|
+
else {
|
|
621
|
+
await _1.productMarketingService.syncProductMarketingInfo(marketing._id);
|
|
622
|
+
}
|
|
605
623
|
}
|
|
606
624
|
};
|
|
607
625
|
exports.MarketingService = MarketingService;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"marketing.service.js","sourceRoot":"/","sources":["modules/marketing/services/marketing.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, { Service } from 'typedi';\nimport { TRPCError } from '@trpc/server';\nimport { dayjs } from '@lyxa.ai/core/dist/utilities/dayjs';\nimport { getLibraries } from '@lyxa.ai/core';\nimport { DocumentType, mongoose, ReturnModelType } from '@typegoose/typegoose';\nimport {\n\tBuy1Get1Marketing,\n\tDiscountMarketing,\n\tLimitedTimeOfferParticipant,\n\tLimitedTimeOfferParticipantModel,\n\tLineItem,\n\tMarketing,\n\tMarketingModel,\n\tMarketing as Model,\n\tProductModel,\n\tProductMarketingModel,\n\tRegularOrder,\n\tRegularOrderModel,\n\tShop,\n\tShopModel,\n} from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport {\n\tAllMarketingsDTO,\n\tAllMarketingsValidationDTO,\n\tCreateProductMarketingDTO,\n\tProductEntireMenuMarketingHandlerDTO,\n\tUpdateMarketingDTO as UpdateDTO,\n} from '@modules/marketing/validations';\nimport {\n\tFilterDTO,\n\tPaginatedResponse,\n\tDeleteDTO,\n\tGetByIdInputDTO,\n} from '@lyxa.ai/core/dist/utilities/validation';\nimport { SoftDeleteModel } from '@lyxa.ai/core/dist/libraries/mongo/plugins/soft-delete-plugin';\nimport { createRawDocumentPaginatorObject, PaginatorOptions } from '@lyxa.ai/core/dist/utilities/pagination';\nimport { ModelType } from '@typegoose/typegoose/lib/types';\nimport {\n\tfilterRelevantChanges,\n\tgetChangedFields,\n\tpublishSyncSingleShopSectionsInCacheProcessEvent,\n} from '@lyxa.ai/core/dist/utilities/events-common-methods';\nimport { AdminActivityLogsEvent } from '@lyxa.ai/core/dist/libraries/event/events/admin-logs-event';\nimport {\n\tAdminLogsUpdatedFieldsType, MarketingCampaignType,\n\tMarketingStatus,\n\tRegularOrderStatus,\n} from '@lyxa.ai/core/dist/utilities/enum';\nimport { publishEvent } from '@lyxa.ai/core/dist/libraries/event';\nimport { BaseEvent } from '@lyxa.ai/core/dist/libraries/event/BaseEvent';\nimport {\n\tMarketingEntireMenuSeedEvent,\n\tMarketingProductSeedPayload,\n} from '@events/events/marketing-product-seed.event';\nimport { MarketingProductSyncEvent } from '@events/events/marketing-product-sync.event';\nimport {\n\tbuy1Get1MarketingService,\n\tdiscountMarketingService,\n\tfeaturedMarketingService,\n\tfreeDeliveryMarketingService,\n\tproductMarketingService,\n\tpunchMarketingService,\n\tspendToGetMarketingService,\n\tsynchronizeProductMarketingService,\n\tmarketingConflictService,\n\tCONFLICT_CHECK_MARKETING_TYPES,\n} from '.';\nimport { MarketingType } from '@lyxa.ai/core/dist/utilities/enum';\nimport {\n\tconflictError,\n\tforbiddenError,\n\tinternalServerError,\n\tnotFoundError,\n\tunauthorizedError,\n} from '@lyxa.ai/core/dist/utilities/error-common';\nimport { ChangeStreamOperationTypes } from '@lyxa.ai/core/dist/libraries/event/events/mongo-stream-changes-batch-process-shops-event';\nimport {\n\tMarketingMetricsRepository,\n\tmarketingMetricsRepository,\n} from '../patterns/repository/MarketingMetricsRepository';\nimport { scheduleMarketingProductSync } from '../queues/marketing-product-sync.queue';\nimport { ltoParticipantService } from '@modules/limited-time-offer/participant/services/limited-time-offer-participant.service';\n\n@Service()\nexport class MarketingService {\n\tprivate model: typeof MarketingModel & SoftDeleteModel<Model>;\n\tprivate shopModel: typeof ShopModel & SoftDeleteModel<Shop>;\n\tprivate orderModel: typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\tprivate marketingMetricsRepository: MarketingMetricsRepository;\n\tprivate limitedTimeOfferParticipantModel: typeof LimitedTimeOfferParticipantModel &\n\t\tSoftDeleteModel<LimitedTimeOfferParticipant>;\n\n\tconstructor() {\n\t\tthis.model = MarketingModel as typeof MarketingModel & SoftDeleteModel<Model>;\n\t\tthis.shopModel = ShopModel as typeof ShopModel & SoftDeleteModel<Shop>;\n\t\tthis.orderModel = RegularOrderModel as typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\t\tthis.marketingMetricsRepository = marketingMetricsRepository;\n\t\tthis.limitedTimeOfferParticipantModel =\n\t\t\tLimitedTimeOfferParticipantModel as typeof LimitedTimeOfferParticipantModel &\n\t\t\t\tSoftDeleteModel<LimitedTimeOfferParticipant>;\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(\n\t\tdata: AllMarketingsValidationDTO,\n\t\tadmin?: mongoose.Types.ObjectId,\n\t\toptions?: { skipLimitedTimeOfferGuard?: boolean }\n\t): Promise<DocumentType<Model>> {\n\t\tconst now = dayjs().toDate();\n\n\t\tif (\n\t\t\t!options?.skipLimitedTimeOfferGuard &&\n\t\t\tdata.marketingType === MarketingType.DISCOUNT &&\n\t\t\t(await ltoParticipantService.isActiveParticipant(data.shop))\n\t\t) {\n\t\t\tforbiddenError(\n\t\t\t\t'You are currently participating in a Limited Time Offer. Please manage your discount from the Limited Time Offer section or withdraw first.'\n\t\t\t);\n\t\t}\n\n\t\tconst existingRecord = await this.model.findOne({\n\t\t\tshop: data.shop,\n\t\t\tmarketingType: data.marketingType,\n\t\t\t'duration.end': { $gt: now },\n\t\t\tstatus: MarketingStatus.ACTIVE,\n\t\t\tisAppliedByCompany: data.isAppliedByCompany,\n\t\t\tcampaignType: data.campaignType,\n\t\t\tadmin: admin ? { $ne: null } : null,\n\t\t});\n\n\t\tif (existingRecord) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'CONFLICT',\n\t\t\t\tmessage: `This shop already has a ${data.marketingType} marketing`,\n\t\t\t});\n\t\t}\n\n\t\tif (CONFLICT_CHECK_MARKETING_TYPES.includes(data.marketingType)) {\n\t\t\tawait marketingConflictService.assertNoConflict({\n\t\t\t\tshop: data.shop,\n\t\t\t\tmarketingType: data.marketingType,\n\t\t\t\tduration: data.duration,\n\t\t\t\trewardTypeGroups: marketingConflictService.getRewardTypeGroups(data.marketingType, data.tiers),\n\t\t\t});\n\t\t}\n\n\t\tif (data.isEntireMenu) {\n\t\t\tconst existingMarketing = await this.model.findOne({\n\t\t\t\tshop: data.shop,\n\t\t\t\t'duration.start': { $lt: now },\n\t\t\t\t'duration.end': { $gt: now },\n\t\t\t\tstatus: MarketingStatus.ACTIVE,\n\t\t\t\tmarketingType: { $in: [MarketingType.BUY1GET1, MarketingType.DISCOUNT], $ne: data.marketingType },\n\t\t\t});\n\n\t\t\tif (existingMarketing) {\n\t\t\t\tthrow new TRPCError({\n\t\t\t\t\tcode: 'CONFLICT',\n\t\t\t\t\tmessage: `Cannot create marketing for entire menu while another product based marketing exists for the shop`,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (data.products && data.products.length > 0) {\n\t\t\tconst productIds = data.products.map((product: CreateProductMarketingDTO) => product.product);\n\n\t\t\tconst hasDuplicates = new Set(productIds.map(String)).size !== productIds.length;\n\n\t\t\tif (hasDuplicates) {\n\t\t\t\tthrow new TRPCError({\n\t\t\t\t\tcode: 'BAD_REQUEST',\n\t\t\t\t\tmessage: `Product list contains duplicate products`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (data.campaignType === MarketingCampaignType.LIMITED_TIME_OFFER) {\n\t\t\t\tawait productMarketingService.pauseConflictingMarketings(productIds);\n\t\t\t} else {\n\t\t\t\tconst isAvailable = await productMarketingService.checkProductMarketingAvailability(\n\t\t\t\t\tproductIds,\n\t\t\t\t\tdata.isAppliedByCompany\n\t\t\t\t);\n\n\t\t\t\tif (!isAvailable) {\n\t\t\t\t\tthrow new TRPCError({\n\t\t\t\t\t\tcode: 'CONFLICT',\n\t\t\t\t\t\tmessage: `Product list contains products which already have marketing applied`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (admin) {\n\t\t\tdata.admin = admin;\n\t\t}\n\n\t\tlet marketing: AllMarketingsDTO;\n\n\t\tswitch (data.marketingType) {\n\t\t\tcase MarketingType.DISCOUNT: {\n\t\t\t\tmarketing = await discountMarketingService.create(data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MarketingType.BUY1GET1: {\n\t\t\t\tmarketing = await buy1Get1MarketingService.create(data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MarketingType.FEATURED: {\n\t\t\t\tif (!admin) {\n\t\t\t\t\tthrow new TRPCError({\n\t\t\t\t\t\tcode: 'UNAUTHORIZED',\n\t\t\t\t\t\tmessage: `Only admin is allowed to create ${data.marketingType} marketing`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tmarketing = await featuredMarketingService.create(data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MarketingType.FREE_DELIVERY: {\n\t\t\t\tmarketing = await freeDeliveryMarketingService.create(data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MarketingType.PUNCH_MARKETING: {\n\t\t\t\tmarketing = await punchMarketingService.create(data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MarketingType.SPEND_TO_GET: {\n\t\t\t\tmarketing = await spendToGetMarketingService.create(data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tmarketing = await this.model.create(data, admin);\n\t\t\t}\n\t\t}\n\n\t\tawait this.assignMarketingToProducts(marketing);\n\n\t\tawait this.model.populate(marketing, {\n\t\t\tpath: 'shop',\n\t\t\tmodel: this.shopModel,\n\t\t\tselect: '_id name shopId',\n\t\t});\n\n\t\tif (admin) {\n\t\t\tthis.logMarketingAdminAction(\n\t\t\t\tadmin,\n\t\t\t\tAdminLogsUpdatedFieldsType.ACTIVATED_MARKETING_PROMOTIONS,\n\t\t\t\t'',\n\t\t\t\tmarketing\n\t\t\t);\n\t\t}\n\t\tif (marketing && !data.isEntireMenu)\n\t\t\tpublishSyncSingleShopSectionsInCacheProcessEvent({\n\t\t\t\tshopId: data.shop,\n\t\t\t\toperation: ChangeStreamOperationTypes.UPDATE,\n\t\t\t});\n\t\treturn marketing;\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(data: GetByIdInputDTO): Promise<DocumentType<Model>> {\n\t\tconst select = data.select || '';\n\t\tconst populate = data.populate || [];\n\t\tconst result = await this.model\n\t\t\t.findOne({\n\t\t\t\t_id: data._id,\n\t\t\t})\n\t\t\t.select(select)\n\t\t\t.populate(populate);\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 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,\n\t\t\t\tselect: data?.select,\n\t\t\t\tpopulate: data?.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 record\n\t * @param data Data to update\n\t */\n\tpublic async update(\n\t\t_id: mongoose.Types.ObjectId,\n\t\tdata: UpdateDTO,\n\t\tadmin?: mongoose.Types.ObjectId\n\t): Promise<DocumentType<Model>> {\n\t\tlet marketing: AllMarketingsDTO;\n\n\t\tconst partOfLimitedTimeOffer = await this.limitedTimeOfferParticipantModel.exists({\n\t\t\tmarketing: _id,\n\t\t});\n\n\t\tif (partOfLimitedTimeOffer) {\n\t\t\tforbiddenError(\n\t\t\t\t'You are currently participating in a Limited Time Offer. Please make your edits from the Limited Time Offer section.'\n\t\t\t);\n\t\t}\n\n\t\tconst oldMarketing = await this.model.findById(_id).populate({\n\t\t\tpath: 'shop',\n\t\t\tselect: '_id name shopId',\n\t\t});\n\n\t\tif (!oldMarketing) {\n\t\t\tnotFoundError('Could not find marketing');\n\t\t}\n\n\t\tif (data.status && data.status === MarketingStatus.ACTIVE && oldMarketing.status !== MarketingStatus.ACTIVE) {\n\t\t\tif (\n\t\t\t\toldMarketing.status === MarketingStatus.PAUSED &&\n\t\t\t\toldMarketing.marketingType === MarketingType.DISCOUNT &&\n\t\t\t\t(await ltoParticipantService.isActiveParticipant(oldMarketing.shop._id))\n\t\t\t) {\n\t\t\t\tforbiddenError(\n\t\t\t\t\t'You are currently participating in a Limited Time Offer. Please manage your discount from the Limited Time Offer section or withdraw first.'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tawait this.verifyUnpauseConditions(_id);\n\t\t}\n\n\t\tswitch (oldMarketing.marketingType) {\n\t\t\tcase MarketingType.DISCOUNT: {\n\t\t\t\tmarketing = await discountMarketingService.update(_id, data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MarketingType.BUY1GET1: {\n\t\t\t\tmarketing = await buy1Get1MarketingService.update(_id, data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MarketingType.FEATURED: {\n\t\t\t\tif (!admin) {\n\t\t\t\t\tunauthorizedError(`Only admin is allowed to update ${data.marketingType} marketing`);\n\t\t\t\t}\n\t\t\t\tmarketing = await featuredMarketingService.update(_id, data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MarketingType.FREE_DELIVERY: {\n\t\t\t\tmarketing = await freeDeliveryMarketingService.update(_id, data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MarketingType.PUNCH_MARKETING: {\n\t\t\t\tmarketing = await punchMarketingService.update(_id, data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MarketingType.SPEND_TO_GET: {\n\t\t\t\tmarketing = await spendToGetMarketingService.update(_id, data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tmarketing = await this.model\n\t\t\t\t\t.findOneAndUpdate(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t_id: _id,\n\t\t\t\t\t\t\tdeletedAt: null,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdata,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnew: true,\n\t\t\t\t\t\t\trunValidators: true,\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\t.populate({\n\t\t\t\t\t\tpath: 'shop',\n\t\t\t\t\t\tselect: '_id name shopId',\n\t\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (!marketing) {\n\t\t\tinternalServerError('Could not update marketing');\n\t\t}\n\n\t\tif (admin) {\n\t\t\tconst allChanges = getChangedFields(oldMarketing, marketing);\n\t\t\tconst relevantChanges = filterRelevantChanges(allChanges, data);\n\n\t\t\tif (Object.keys(relevantChanges).includes('status')) {\n\t\t\t\tif (data.status == MarketingStatus.ACTIVE) {\n\t\t\t\t\tthis.logMarketingAdminAction(\n\t\t\t\t\t\tadmin,\n\t\t\t\t\t\tAdminLogsUpdatedFieldsType.CONTINUED_MARKETING_PROMOTIONS,\n\t\t\t\t\t\toldMarketing,\n\t\t\t\t\t\tmarketing\n\t\t\t\t\t);\n\t\t\t\t} else if (data.status == MarketingStatus.PAUSED) {\n\t\t\t\t\tthis.logMarketingAdminAction(\n\t\t\t\t\t\tadmin,\n\t\t\t\t\t\tAdminLogsUpdatedFieldsType.PAUSED_MARKETING_PROMOTIONS,\n\t\t\t\t\t\toldMarketing,\n\t\t\t\t\t\tmarketing\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.logMarketingAdminAction(\n\t\t\t\tadmin,\n\t\t\t\tAdminLogsUpdatedFieldsType.EDITED_MARKETING_PROMOTIONS,\n\t\t\t\toldMarketing,\n\t\t\t\tmarketing\n\t\t\t);\n\t\t}\n\n\t\tawait this.assignMarketingToProducts(marketing);\n\n\t\tpublishSyncSingleShopSectionsInCacheProcessEvent({\n\t\t\tshopId: marketing.shop,\n\t\t\toperation: ChangeStreamOperationTypes.UPDATE,\n\t\t});\n\n\t\treturn marketing;\n\t}\n\n\tprivate async verifyUnpauseConditions(marketingId: mongoose.Types.ObjectId): Promise<void> {\n\t\tconst marketing = await this.model.findOne({ _id: marketingId, deletedAt: null }).populate('products');\n\t\tif (!marketing) return;\n\n\t\tif ([MarketingType.BUY1GET1, MarketingType.DISCOUNT].includes(marketing.marketingType)) {\n\t\t\tconst typedMarketing = marketing as DocumentType<DiscountMarketing | Buy1Get1Marketing>;\n\t\t\tconst productIds = typedMarketing.products.map((product: any) => product.product);\n\t\t\tconst isAvailable = await productMarketingService.checkProductMarketingAvailability(\n\t\t\t\tproductIds,\n\t\t\t\tmarketing.isAppliedByCompany\n\t\t\t);\n\n\t\t\tif (!isAvailable) {\n\t\t\t\tconflictError(\"You can't activate discount and B1G1 on the same items at the same time\");\n\t\t\t}\n\t\t}\n\n\t\tif (CONFLICT_CHECK_MARKETING_TYPES.includes(marketing.marketingType)) {\n\t\t\tawait marketingConflictService.assertNoConflict({\n\t\t\t\tshop: marketing.shop as mongoose.Types.ObjectId,\n\t\t\t\tmarketingType: marketing.marketingType,\n\t\t\t\tduration: marketing.duration,\n\t\t\t\trewardTypeGroups: marketingConflictService.getRewardTypeGroups(\n\t\t\t\t\tmarketing.marketingType,\n\t\t\t\t\t(marketing as any).tiers\n\t\t\t\t),\n\t\t\t\texcludeMarketingId: marketingId,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async logMarketingAdminAction(\n\t\tadmin: mongoose.Types.ObjectId,\n\t\tactionType: AdminLogsUpdatedFieldsType,\n\t\toldDocument?: any,\n\t\tnewDocument?: any\n\t) {\n\t\tconst adminActivityLogsEvent: BaseEvent<Record<string, unknown>> = new AdminActivityLogsEvent({\n\t\t\tadmin,\n\t\t\tupdatedField: actionType,\n\t\t\toldDocument: oldDocument ?? '',\n\t\t\tnewDocument: newDocument ?? '',\n\t\t});\n\t\tawait publishEvent(adminActivityLogsEvent);\n\t}\n\n\t/**\n\t * Delete record\n\t * @param data Data for delete\n\t */\n\tpublic async deleteById(\n\t\tdata: DeleteDTO,\n\t\tadmin?: mongoose.Types.ObjectId,\n\t\toptions?: { skipLimitedTimeOfferGuard?: boolean }\n\t): Promise<string> {\n\t\tconst { _id, softDelete } = data;\n\n\t\tif (!options?.skipLimitedTimeOfferGuard) {\n\t\t\tconst partOfLimitedTimeOffer = await this.limitedTimeOfferParticipantModel.exists({\n\t\t\t\tmarketing: _id,\n\t\t\t});\n\n\t\t\tif (partOfLimitedTimeOffer) {\n\t\t\t\tforbiddenError(\n\t\t\t\t\t'You are currently participating in a Limited Time Offer. Please make your edits from the Limited Time Offer section.'\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst record = await this.model.findById(_id).populate({\n\t\t\tpath: 'shop',\n\t\t\tselect: '_id name shopId',\n\t\t});\n\n\t\tif (!record) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'NOT_FOUND',\n\t\t\t\tmessage: 'Record not found',\n\t\t\t});\n\t\t}\n\n\t\trecord.status = MarketingStatus.DELETED;\n\t\tawait record.save();\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: 'INTERNAL_SERVER_ERROR',\n\t\t\t\tmessage: 'Unable to delete marketing',\n\t\t\t});\n\t\t}\n\n\t\tif (admin) {\n\t\t\tthis.logMarketingAdminAction(admin, AdminLogsUpdatedFieldsType.DELETED_MARKETING_PROMOTIONS, record);\n\t\t}\n\n\t\tproductMarketingService.deleteMany({ marketing: data._id }, data.softDelete);\n\t\tpublishSyncSingleShopSectionsInCacheProcessEvent({\n\t\t\tshopId: record.shop._id,\n\t\t\toperation: ChangeStreamOperationTypes.DELETE,\n\t\t});\n\t\treturn 'Record deleted successfully';\n\t}\n\n\tpublic async deleteManyByIds(marketingIds: mongoose.Types.ObjectId[], softDelete = true): Promise<void> {\n\t\tif (marketingIds.length === 0) return;\n\n\t\tconst marketings = await this.model\n\t\t\t.find({ _id: { $in: marketingIds } })\n\t\t\t.select('shop')\n\t\t\t.lean();\n\n\t\tawait this.model.updateMany(\n\t\t\t{ _id: { $in: marketingIds } },\n\t\t\t{ $set: { status: MarketingStatus.DELETED } }\n\t\t);\n\t\tawait this.model.deleteRecords({ _id: { $in: marketingIds } }, softDelete);\n\n\t\tawait productMarketingService.deleteManyByMarketingIds(marketingIds, softDelete);\n\n\t\tconst uniqueShopIds = [\n\t\t\t...new Map(\n\t\t\t\tmarketings\n\t\t\t\t\t.map((m: any) => m.shop)\n\t\t\t\t\t.filter(Boolean)\n\t\t\t\t\t.map((s: any) => {\n\t\t\t\t\t\tconst id = s instanceof mongoose.Types.ObjectId ? s : new mongoose.Types.ObjectId(s);\n\t\t\t\t\t\treturn [id.toString(), id] as [string, mongoose.Types.ObjectId];\n\t\t\t\t\t})\n\t\t\t).values(),\n\t\t];\n\n\t\tfor (const shopId of uniqueShopIds) {\n\t\t\tpublishSyncSingleShopSectionsInCacheProcessEvent({\n\t\t\t\tshopId,\n\t\t\t\toperation: ChangeStreamOperationTypes.DELETE,\n\t\t\t});\n\t\t}\n\t}\n\n\tpublic async handleNewProductForEntireMenuMarketing(data: ProductEntireMenuMarketingHandlerDTO) {\n\t\tconst existingMarketing = await this.model.findOne({\n\t\t\tshop: data.shop,\n\t\t\tmarketingType: { $in: [MarketingType.BUY1GET1, MarketingType.DISCOUNT] },\n\t\t\t'duration.end': { $gt: new Date() },\n\t\t\tstatus: MarketingStatus.ACTIVE,\n\t\t\tisEntireMenu: true,\n\t\t});\n\n\t\t// check if existing marketing\n\t\tif (existingMarketing) {\n\t\t\tconst productMarketingData: CreateProductMarketingDTO = {\n\t\t\t\tproduct: data.product,\n\t\t\t\tmarketing: existingMarketing._id,\n\t\t\t};\n\t\t\tif (existingMarketing.marketingType == MarketingType.BUY1GET1) {\n\t\t\t\tproductMarketingData.isBuy1Get1 = true;\n\t\t\t}\n\t\t\tif (existingMarketing.marketingType == MarketingType.DISCOUNT) {\n\t\t\t\tproductMarketingData.value = (existingMarketing as DocumentType<DiscountMarketing>).value;\n\t\t\t\tproductMarketingData.valueType = (existingMarketing as DocumentType<DiscountMarketing>).valueType;\n\t\t\t}\n\n\t\t\tawait productMarketingService.create(productMarketingData);\n\t\t\tawait synchronizeProductMarketingService.syncProductMarketingInfoByProductId(data.product);\n\t\t}\n\n\t\treturn 'Product handled successfully';\n\t}\n\n\tpublic async incrementMarketingSpentFromOrder(orderId: mongoose.Types.ObjectId): Promise<any> {\n\t\tconst order = (await this.orderModel\n\t\t\t.findById(orderId)\n\t\t\t.populate([\n\t\t\t\t{ path: 'lineItems' },\n\t\t\t\t{ path: 'marketings', select: 'isAppliedByCompany' },\n\t\t\t])) as DocumentType<RegularOrder> & {\n\t\t\tlineItems: DocumentType<LineItem>[];\n\t\t\tmarketings: DocumentType<Marketing>[];\n\t\t};\n\n\t\tif (!order || !order.marketings?.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst marketingSpendMap = this.marketingMetricsRepository.calculateMarketingSpendPerOrder(order);\n\n\t\tconst bulkOps = [...marketingSpendMap.entries()].map(([marketingId, amountSpent]) => ({\n\t\t\tupdateOne: {\n\t\t\t\tfilter: { _id: marketingId },\n\t\t\t\tupdate: { $inc: { amountSpent } },\n\t\t\t},\n\t\t}));\n\n\t\tif (bulkOps.length) {\n\t\t\tawait this.model.bulkWrite(bulkOps);\n\t\t}\n\n\t\tawait this.expireMarketingsExceedingSpendLimits(Array.from(marketingSpendMap.keys()));\n\n\t\treturn 'Marketing amount spent incremented successfully';\n\t}\n\n\tpublic async decrementMarketingSpentFromOrder(orderId: mongoose.Types.ObjectId): Promise<any> {\n\t\tconst order = (await this.orderModel\n\t\t\t.findById(orderId)\n\t\t\t.populate([\n\t\t\t\t{ path: 'lineItems' },\n\t\t\t\t{ path: 'marketings', select: 'isAppliedByCompany' },\n\t\t\t])) as DocumentType<RegularOrder> & {\n\t\t\tlineItems: DocumentType<LineItem>[];\n\t\t\tmarketings: DocumentType<Marketing>[];\n\t\t};\n\n\t\tif (!order || !order.marketings?.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst marketingSpendMap = this.marketingMetricsRepository.calculateMarketingSpendPerOrder(order);\n\n\t\tconst bulkOps = [...marketingSpendMap.entries()].map(([marketingId, amountSpent]) => ({\n\t\t\tupdateOne: {\n\t\t\t\tfilter: { _id: marketingId },\n\t\t\t\tupdate: { $inc: { amountSpent: -amountSpent } },\n\t\t\t},\n\t\t}));\n\n\t\tif (bulkOps.length) {\n\t\t\tawait this.model.bulkWrite(bulkOps);\n\t\t}\n\n\t\tawait this.unExpireMarketingsBelowSpendLimits(Array.from(marketingSpendMap.keys()));\n\n\t\treturn 'Marketing amount spent decremented successfully';\n\t}\n\n\tprivate async expireMarketingsExceedingSpendLimits(marketingIds: mongoose.Types.ObjectId[]) {\n\t\tconst update = await this.model.updateMany(\n\t\t\t{\n\t\t\t\t_id: { $in: marketingIds },\n\t\t\t\tisSpendLimitEnabled: true,\n\t\t\t\tstatus: { $ne: MarketingStatus.EXPIRED },\n\t\t\t\t$expr: { $gte: ['$amountSpent', '$spendLimit'] },\n\t\t\t},\n\t\t\t{ $set: { status: MarketingStatus.EXPIRED, expiredAt: dayjs().toDate() } }\n\t\t);\n\n\t\tif (update.modifiedCount > 0) {\n\t\t\tawait synchronizeProductMarketingService.syncProductMarketingInfoByMarketingIds(marketingIds);\n\t\t}\n\t}\n\n\tprivate async unExpireMarketingsBelowSpendLimits(marketingIds: mongoose.Types.ObjectId[]) {\n\t\tconst update = await this.model.updateMany(\n\t\t\t{\n\t\t\t\t_id: { $in: marketingIds },\n\t\t\t\tisSpendLimitEnabled: true,\n\t\t\t\tstatus: MarketingStatus.EXPIRED,\n\t\t\t\t$expr: { $lt: ['$amountSpent', '$spendLimit'] },\n\t\t\t},\n\t\t\t{ $set: { status: MarketingStatus.ACTIVE }, $unset: { expiredAt: 1 } }\n\t\t);\n\n\t\tif (update.modifiedCount > 0) {\n\t\t\tawait synchronizeProductMarketingService.syncProductMarketingInfoByMarketingIds(marketingIds);\n\t\t}\n\t}\n\n\tpublic async recomputeAndSyncAllMarketingSpent(): Promise<void> {\n\t\tconst cursor = this.model\n\t\t\t.find({ marketingType: { $ne: MarketingType.FEATURED } }, { _id: 1 })\n\t\t\t.lean()\n\t\t\t.cursor();\n\n\t\tconst bulkOps: mongoose.AnyBulkWriteOperation[] = [];\n\t\tconst marketingIds: mongoose.Types.ObjectId[] = [];\n\n\t\tfor await (const marketing of cursor) {\n\t\t\tconst { amount } = await this.marketingMetricsRepository.calculateMarketingSpent(marketing._id);\n\n\t\t\tbulkOps.push({\n\t\t\t\tupdateOne: {\n\t\t\t\t\tfilter: { _id: marketing._id },\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\t$set: { amountSpent: amount },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tmarketingIds.push(marketing._id);\n\n\t\t\tif (bulkOps.length >= 500) {\n\t\t\t\tawait this.model.bulkWrite(bulkOps);\n\t\t\t\tbulkOps.length = 0;\n\t\t\t}\n\t\t}\n\n\t\tif (bulkOps.length) {\n\t\t\tawait this.model.bulkWrite(bulkOps);\n\t\t}\n\n\t\tawait this.expireMarketingsExceedingSpendLimits(marketingIds);\n\t\tawait this.unExpireMarketingsBelowSpendLimits(marketingIds);\n\t}\n\n\tprivate async publishEntireMenuSeedEvents(\n\t\tmarketing: DocumentType<Buy1Get1Marketing | DiscountMarketing>\n\t): Promise<number> {\n\t\tconst PAGE_SIZE = 500;\n\t\tconst marketingId = marketing._id.toString();\n\t\tconst shopId = ((marketing.shop as any)?._id ?? marketing.shop).toString();\n\n\t\tconst products = await ProductModel.find({ shop: marketing.shop }).select('_id').lean();\n\t\tconst productIds = products.map((p: any) => p._id.toString());\n\n\t\tfor (let i = 0; i < productIds.length; i += PAGE_SIZE) {\n\t\t\tawait publishEvent(\n\t\t\t\tnew MarketingEntireMenuSeedEvent({\n\t\t\t\t\tmarketingId,\n\t\t\t\t\tshopId,\n\t\t\t\t\tisAppliedByCompany: marketing.isAppliedByCompany ?? false,\n\t\t\t\t\tisBuy1Get1: marketing.marketingType === MarketingType.BUY1GET1,\n\t\t\t\t\tvalue: (marketing as any).value,\n\t\t\t\t\tvalueType: (marketing as any).valueType,\n\t\t\t\t\tproductIds: productIds.slice(i, i + PAGE_SIZE),\n\t\t\t\t})\n\t\t\t);\n\t\t}\n\n\t\treturn productIds.length;\n\t}\n\n\tpublic async reseedEntireMenuMarketing(marketingId: mongoose.Types.ObjectId): Promise<void> {\n\t\tconst logger = getLibraries().getLoggerKit();\n\n\t\tconst marketing = await this.model.findOne({ _id: marketingId, deletedAt: null });\n\t\tif (!marketing) internalServerError('Marketing not found');\n\n\t\tconst productCount = await this.publishEntireMenuSeedEvents(\n\t\t\tmarketing as DocumentType<Buy1Get1Marketing | DiscountMarketing>\n\t\t);\n\n\t\tlogger.debug(`entire-menu reseed dispatched — ${productCount} products`, {\n\t\t\ttag: 'marketing.seed.entire-menu',\n\t\t\tdata: { marketingId: marketingId.toString(), productCount },\n\t\t});\n\t}\n\n\tpublic async assignMarketingToProducts(marketing: DocumentType<Buy1Get1Marketing | DiscountMarketing>) {\n\t\tconst diffStartTime = dayjs(marketing.duration.start).diff(dayjs(), 'milliseconds');\n\t\tif (diffStartTime > 0) {\n\t\t\treturn await scheduleMarketingProductSync(marketing._id.toString(), diffStartTime);\n\t\t}\n\n\t\tif (marketing.isEntireMenu) {\n\t\t\tconst logger = getLibraries().getLoggerKit();\n\n\t\t\tconst productCount = await this.publishEntireMenuSeedEvents(marketing);\n\n\t\t\tlogger.debug(`entire-menu marketing seed dispatched — ${productCount} products`, {\n\t\t\t\ttag: 'marketing.seed.entire-menu',\n\t\t\t\tdata: { marketingId: marketing._id.toString(), productCount },\n\t\t\t});\n\t\t} else {\n\t\t\t// Non-entire-menu: the productMarketings were already created synchronously. The product-doc\n\t\t\t// sync is linear in product count (thousands → seconds), so page it into background events\n\t\t\t// instead of blocking the request — same pattern as the entire-menu branch above.\n\t\t\tconst shopId = ((marketing.shop as any)?._id ?? marketing.shop).toString();\n\t\t\tconst pms = await ProductMarketingModel.find({ marketing: marketing._id, deletedAt: null })\n\t\t\t\t.select('product')\n\t\t\t\t.lean();\n\t\t\tconst productIds = pms.map((p: any) => p.product.toString());\n\n\t\t\tconst PAGE_SIZE = 500;\n\t\t\tfor (let i = 0; i < productIds.length; i += PAGE_SIZE) {\n\t\t\t\tawait publishEvent(\n\t\t\t\t\tnew MarketingProductSyncEvent({\n\t\t\t\t\t\tmarketingId: marketing._id.toString(),\n\t\t\t\t\t\tshopId,\n\t\t\t\t\t\tproductIds: productIds.slice(i, i + PAGE_SIZE),\n\t\t\t\t\t})\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\t}\n}\n\nexport const marketingService = Container.get(MarketingService);\n"]}
|
|
1
|
+
{"version":3,"file":"marketing.service.js","sourceRoot":"/","sources":["modules/marketing/services/marketing.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, { Service } from 'typedi';\nimport { TRPCError } from '@trpc/server';\nimport { dayjs } from '@lyxa.ai/core/dist/utilities/dayjs';\nimport { getLibraries } from '@lyxa.ai/core';\nimport { DocumentType, mongoose, ReturnModelType } from '@typegoose/typegoose';\nimport {\n\tBuy1Get1Marketing,\n\tDiscountMarketing,\n\tLimitedTimeOfferParticipant,\n\tLimitedTimeOfferParticipantModel,\n\tLineItem,\n\tMarketing,\n\tMarketing as Model,\n\tMarketingModel,\n\tProductModel,\n\tRegularOrder,\n\tRegularOrderModel,\n\tShop,\n\tShopModel,\n} from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport {\n\tAllMarketingsDTO,\n\tAllMarketingsValidationDTO,\n\tCreateProductMarketingDTO,\n\tProductEntireMenuMarketingHandlerDTO,\n\tUpdateMarketingDTO as UpdateDTO,\n} from '@modules/marketing/validations';\nimport {\n\tDeleteDTO,\n\tFilterDTO,\n\tGetByIdInputDTO,\n\tPaginatedResponse,\n} from '@lyxa.ai/core/dist/utilities/validation';\nimport { SoftDeleteModel } from '@lyxa.ai/core/dist/libraries/mongo/plugins/soft-delete-plugin';\nimport { createRawDocumentPaginatorObject, PaginatorOptions } from '@lyxa.ai/core/dist/utilities/pagination';\nimport { ModelType } from '@typegoose/typegoose/lib/types';\nimport {\n\tfilterRelevantChanges,\n\tgetChangedFields,\n\tpublishSyncSingleShopSectionsInCacheProcessEvent,\n} from '@lyxa.ai/core/dist/utilities/events-common-methods';\nimport { AdminActivityLogsEvent } from '@lyxa.ai/core/dist/libraries/event/events/admin-logs-event';\nimport {\n\tAdminLogsUpdatedFieldsType,\n\tMarketingCampaignType,\n\tMarketingStatus,\n\tMarketingType,\n} from '@lyxa.ai/core/dist/utilities/enum';\nimport { publishEvent } from '@lyxa.ai/core/dist/libraries/event';\nimport { BaseEvent } from '@lyxa.ai/core/dist/libraries/event/BaseEvent';\nimport { MarketingEntireMenuSeedEvent } from '@events/events/marketing-product-seed.event';\nimport {\n\tbuy1Get1MarketingService,\n\tCONFLICT_CHECK_MARKETING_TYPES,\n\tdiscountMarketingService,\n\tfeaturedMarketingService,\n\tfreeDeliveryMarketingService,\n\tmarketingConflictService,\n\tproductMarketingService,\n\tpunchMarketingService,\n\tspendToGetMarketingService,\n\tsynchronizeProductMarketingService,\n} from '.';\nimport {\n\tconflictError,\n\tforbiddenError,\n\tinternalServerError,\n\tnotFoundError,\n\tunauthorizedError,\n} from '@lyxa.ai/core/dist/utilities/error-common';\nimport { ChangeStreamOperationTypes } from '@lyxa.ai/core/dist/libraries/event/events/mongo-stream-changes-batch-process-shops-event';\nimport {\n\tMarketingMetricsRepository,\n\tmarketingMetricsRepository,\n} from '../patterns/repository/MarketingMetricsRepository';\nimport { scheduleMarketingProductSync } from '../queues/marketing-product-sync.queue';\nimport { ltoParticipantService } from '@modules/limited-time-offer/participant/services/limited-time-offer-participant.service';\nimport { isLtoScheduleEnabled } from '@utility/feature-flags';\n\n@Service()\nexport class MarketingService {\n\tprivate model: typeof MarketingModel & SoftDeleteModel<Model>;\n\tprivate shopModel: typeof ShopModel & SoftDeleteModel<Shop>;\n\tprivate orderModel: typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\tprivate marketingMetricsRepository: MarketingMetricsRepository;\n\tprivate limitedTimeOfferParticipantModel: typeof LimitedTimeOfferParticipantModel &\n\t\tSoftDeleteModel<LimitedTimeOfferParticipant>;\n\n\tconstructor() {\n\t\tthis.model = MarketingModel as typeof MarketingModel & SoftDeleteModel<Model>;\n\t\tthis.shopModel = ShopModel as typeof ShopModel & SoftDeleteModel<Shop>;\n\t\tthis.orderModel = RegularOrderModel as typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\t\tthis.marketingMetricsRepository = marketingMetricsRepository;\n\t\tthis.limitedTimeOfferParticipantModel =\n\t\t\tLimitedTimeOfferParticipantModel as typeof LimitedTimeOfferParticipantModel &\n\t\t\t\tSoftDeleteModel<LimitedTimeOfferParticipant>;\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(\n\t\tdata: AllMarketingsValidationDTO,\n\t\tadmin?: mongoose.Types.ObjectId,\n\t\toptions?: { skipLimitedTimeOfferGuard?: boolean }\n\t): Promise<DocumentType<Model>> {\n\t\tconst now = dayjs().toDate();\n\n\t\tconst ltoScheduleEnabled = await isLtoScheduleEnabled();\n\n\t\tif (\n\t\t\tltoScheduleEnabled &&\n\t\t\t!options?.skipLimitedTimeOfferGuard &&\n\t\t\tdata.marketingType === MarketingType.DISCOUNT &&\n\t\t\t(await ltoParticipantService.isActiveParticipant(data.shop))\n\t\t) {\n\t\t\tforbiddenError(\n\t\t\t\t'You are currently participating in a Limited Time Offer. Please manage your discount from the Limited Time Offer section or withdraw first.'\n\t\t\t);\n\t\t}\n\n\t\tconst existingRecordQuery: mongoose.FilterQuery<Model> = {\n\t\t\tshop: data.shop,\n\t\t\tmarketingType: data.marketingType,\n\t\t\t'duration.end': { $gt: now },\n\t\t\tstatus: MarketingStatus.ACTIVE,\n\t\t\tisAppliedByCompany: data.isAppliedByCompany,\n\t\t};\n\n\t\tif (ltoScheduleEnabled) {\n\t\t\texistingRecordQuery.campaignType = data.campaignType;\n\t\t\texistingRecordQuery.admin = admin ? { $ne: null } : null;\n\t\t}\n\n\t\tconst existingRecord = await this.model.findOne(existingRecordQuery);\n\n\t\tif (existingRecord) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'CONFLICT',\n\t\t\t\tmessage: `This shop already has a ${data.marketingType} marketing`,\n\t\t\t});\n\t\t}\n\n\t\tif (CONFLICT_CHECK_MARKETING_TYPES.includes(data.marketingType)) {\n\t\t\tawait marketingConflictService.assertNoConflict({\n\t\t\t\tshop: data.shop,\n\t\t\t\tmarketingType: data.marketingType,\n\t\t\t\tduration: data.duration,\n\t\t\t\trewardTypeGroups: marketingConflictService.getRewardTypeGroups(data.marketingType, data.tiers),\n\t\t\t});\n\t\t}\n\n\t\tif (data.isEntireMenu) {\n\t\t\tconst existingMarketing = await this.model.findOne({\n\t\t\t\tshop: data.shop,\n\t\t\t\t'duration.start': { $lt: now },\n\t\t\t\t'duration.end': { $gt: now },\n\t\t\t\tstatus: MarketingStatus.ACTIVE,\n\t\t\t\tmarketingType: { $in: [MarketingType.BUY1GET1, MarketingType.DISCOUNT], $ne: data.marketingType },\n\t\t\t});\n\n\t\t\tif (existingMarketing) {\n\t\t\t\tthrow new TRPCError({\n\t\t\t\t\tcode: 'CONFLICT',\n\t\t\t\t\tmessage: `Cannot create marketing for entire menu while another product based marketing exists for the shop`,\n\t\t\t\t});\n\t\t\t}\n\t\t} else if (data.products && data.products.length > 0) {\n\t\t\tconst productIds = data.products.map((product: CreateProductMarketingDTO) => product.product);\n\n\t\t\tconst hasDuplicates = new Set(productIds.map(String)).size !== productIds.length;\n\n\t\t\tif (hasDuplicates) {\n\t\t\t\tthrow new TRPCError({\n\t\t\t\t\tcode: 'BAD_REQUEST',\n\t\t\t\t\tmessage: `Product list contains duplicate products`,\n\t\t\t\t});\n\t\t\t}\n\n\t\t\tif (ltoScheduleEnabled && data.campaignType === MarketingCampaignType.LIMITED_TIME_OFFER) {\n\t\t\t\tawait productMarketingService.pauseConflictingMarketings(productIds);\n\t\t\t} else {\n\t\t\t\tconst isAvailable = await productMarketingService.checkProductMarketingAvailability(\n\t\t\t\t\tproductIds,\n\t\t\t\t\tdata.isAppliedByCompany\n\t\t\t\t);\n\n\t\t\t\tif (!isAvailable) {\n\t\t\t\t\tthrow new TRPCError({\n\t\t\t\t\t\tcode: 'CONFLICT',\n\t\t\t\t\t\tmessage: `Product list contains products which already have marketing applied`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tif (admin) {\n\t\t\tdata.admin = admin;\n\t\t}\n\n\t\tlet marketing: AllMarketingsDTO;\n\n\t\tswitch (data.marketingType) {\n\t\t\tcase MarketingType.DISCOUNT: {\n\t\t\t\tmarketing = await discountMarketingService.create(data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MarketingType.BUY1GET1: {\n\t\t\t\tmarketing = await buy1Get1MarketingService.create(data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MarketingType.FEATURED: {\n\t\t\t\tif (!admin) {\n\t\t\t\t\tthrow new TRPCError({\n\t\t\t\t\t\tcode: 'UNAUTHORIZED',\n\t\t\t\t\t\tmessage: `Only admin is allowed to create ${data.marketingType} marketing`,\n\t\t\t\t\t});\n\t\t\t\t}\n\t\t\t\tmarketing = await featuredMarketingService.create(data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MarketingType.FREE_DELIVERY: {\n\t\t\t\tmarketing = await freeDeliveryMarketingService.create(data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MarketingType.PUNCH_MARKETING: {\n\t\t\t\tmarketing = await punchMarketingService.create(data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MarketingType.SPEND_TO_GET: {\n\t\t\t\tmarketing = await spendToGetMarketingService.create(data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tmarketing = await this.model.create(data, admin);\n\t\t\t}\n\t\t}\n\n\t\tawait this.assignMarketingToProducts(marketing);\n\n\t\tawait this.model.populate(marketing, {\n\t\t\tpath: 'shop',\n\t\t\tmodel: this.shopModel,\n\t\t\tselect: '_id name shopId',\n\t\t});\n\n\t\tif (admin) {\n\t\t\tthis.logMarketingAdminAction(\n\t\t\t\tadmin,\n\t\t\t\tAdminLogsUpdatedFieldsType.ACTIVATED_MARKETING_PROMOTIONS,\n\t\t\t\t'',\n\t\t\t\tmarketing\n\t\t\t);\n\t\t}\n\t\tif (marketing && !data.isEntireMenu)\n\t\t\tpublishSyncSingleShopSectionsInCacheProcessEvent({\n\t\t\t\tshopId: data.shop,\n\t\t\t\toperation: ChangeStreamOperationTypes.UPDATE,\n\t\t\t});\n\t\treturn marketing;\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(data: GetByIdInputDTO): Promise<DocumentType<Model>> {\n\t\tconst select = data.select || '';\n\t\tconst populate = data.populate || [];\n\t\tconst result = await this.model\n\t\t\t.findOne({\n\t\t\t\t_id: data._id,\n\t\t\t})\n\t\t\t.select(select)\n\t\t\t.populate(populate);\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 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,\n\t\t\t\tselect: data?.select,\n\t\t\t\tpopulate: data?.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 record\n\t * @param data Data to update\n\t */\n\tpublic async update(\n\t\t_id: mongoose.Types.ObjectId,\n\t\tdata: UpdateDTO,\n\t\tadmin?: mongoose.Types.ObjectId\n\t): Promise<DocumentType<Model>> {\n\t\tlet marketing: AllMarketingsDTO;\n\n\t\tconst partOfLimitedTimeOffer = await this.limitedTimeOfferParticipantModel.exists({\n\t\t\tmarketing: _id,\n\t\t});\n\n\t\tif (partOfLimitedTimeOffer) {\n\t\t\tforbiddenError(\n\t\t\t\t'You are currently participating in a Limited Time Offer. Please make your edits from the Limited Time Offer section.'\n\t\t\t);\n\t\t}\n\n\t\tconst oldMarketing = await this.model.findById(_id).populate({\n\t\t\tpath: 'shop',\n\t\t\tselect: '_id name shopId',\n\t\t});\n\n\t\tif (!oldMarketing) {\n\t\t\tnotFoundError('Could not find marketing');\n\t\t}\n\n\t\tif (\n\t\t\tdata.status &&\n\t\t\tdata.status === MarketingStatus.ACTIVE &&\n\t\t\toldMarketing.status !== MarketingStatus.ACTIVE\n\t\t) {\n\t\t\tif (\n\t\t\t\t(await isLtoScheduleEnabled()) &&\n\t\t\t\toldMarketing.marketingType === MarketingType.DISCOUNT &&\n\t\t\t\t(await ltoParticipantService.isActiveParticipant(oldMarketing.shop._id))\n\t\t\t) {\n\t\t\t\tforbiddenError(\n\t\t\t\t\t'You are currently participating in a Limited Time Offer. Please manage your discount from the Limited Time Offer section or withdraw first.'\n\t\t\t\t);\n\t\t\t}\n\n\t\t\tawait this.verifyUnpauseConditions(_id);\n\t\t}\n\n\t\tswitch (oldMarketing.marketingType) {\n\t\t\tcase MarketingType.DISCOUNT: {\n\t\t\t\tmarketing = await discountMarketingService.update(_id, data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MarketingType.BUY1GET1: {\n\t\t\t\tmarketing = await buy1Get1MarketingService.update(_id, data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MarketingType.FEATURED: {\n\t\t\t\tif (!admin) {\n\t\t\t\t\tunauthorizedError(`Only admin is allowed to update ${data.marketingType} marketing`);\n\t\t\t\t}\n\t\t\t\tmarketing = await featuredMarketingService.update(_id, data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MarketingType.FREE_DELIVERY: {\n\t\t\t\tmarketing = await freeDeliveryMarketingService.update(_id, data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MarketingType.PUNCH_MARKETING: {\n\t\t\t\tmarketing = await punchMarketingService.update(_id, data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tcase MarketingType.SPEND_TO_GET: {\n\t\t\t\tmarketing = await spendToGetMarketingService.update(_id, data);\n\t\t\t\tbreak;\n\t\t\t}\n\n\t\t\tdefault: {\n\t\t\t\tmarketing = await this.model\n\t\t\t\t\t.findOneAndUpdate(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t_id: _id,\n\t\t\t\t\t\t\tdeletedAt: null,\n\t\t\t\t\t\t},\n\t\t\t\t\t\tdata,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tnew: true,\n\t\t\t\t\t\t\trunValidators: true,\n\t\t\t\t\t\t}\n\t\t\t\t\t)\n\t\t\t\t\t.populate({\n\t\t\t\t\t\tpath: 'shop',\n\t\t\t\t\t\tselect: '_id name shopId',\n\t\t\t\t\t});\n\t\t\t}\n\t\t}\n\n\t\tif (!marketing) {\n\t\t\tinternalServerError('Could not update marketing');\n\t\t}\n\n\t\tif (admin) {\n\t\t\tconst allChanges = getChangedFields(oldMarketing, marketing);\n\t\t\tconst relevantChanges = filterRelevantChanges(allChanges, data);\n\n\t\t\tif (Object.keys(relevantChanges).includes('status')) {\n\t\t\t\tif (data.status == MarketingStatus.ACTIVE) {\n\t\t\t\t\tthis.logMarketingAdminAction(\n\t\t\t\t\t\tadmin,\n\t\t\t\t\t\tAdminLogsUpdatedFieldsType.CONTINUED_MARKETING_PROMOTIONS,\n\t\t\t\t\t\toldMarketing,\n\t\t\t\t\t\tmarketing\n\t\t\t\t\t);\n\t\t\t\t} else if (data.status == MarketingStatus.PAUSED) {\n\t\t\t\t\tthis.logMarketingAdminAction(\n\t\t\t\t\t\tadmin,\n\t\t\t\t\t\tAdminLogsUpdatedFieldsType.PAUSED_MARKETING_PROMOTIONS,\n\t\t\t\t\t\toldMarketing,\n\t\t\t\t\t\tmarketing\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tthis.logMarketingAdminAction(\n\t\t\t\tadmin,\n\t\t\t\tAdminLogsUpdatedFieldsType.EDITED_MARKETING_PROMOTIONS,\n\t\t\t\toldMarketing,\n\t\t\t\tmarketing\n\t\t\t);\n\t\t}\n\n\t\tawait this.assignMarketingToProducts(marketing);\n\n\t\tpublishSyncSingleShopSectionsInCacheProcessEvent({\n\t\t\tshopId: marketing.shop,\n\t\t\toperation: ChangeStreamOperationTypes.UPDATE,\n\t\t});\n\n\t\treturn marketing;\n\t}\n\n\tprivate async verifyUnpauseConditions(marketingId: mongoose.Types.ObjectId): Promise<void> {\n\t\tconst marketing = await this.model.findOne({ _id: marketingId, deletedAt: null }).populate('products');\n\t\tif (!marketing) return;\n\n\t\tif (await isLtoScheduleEnabled()) {\n\t\t\tconst hasActiveLto = await this.model.exists({\n\t\t\t\tshop: marketing.shop,\n\t\t\t\tcampaignType: MarketingCampaignType.LIMITED_TIME_OFFER,\n\t\t\t\tstatus: MarketingStatus.ACTIVE,\n\t\t\t\tdeletedAt: null,\n\t\t\t});\n\t\t\tif (hasActiveLto) {\n\t\t\t\tconflictError(\"Can't resume this discount while a limited time offer is active\");\n\t\t\t}\n\t\t}\n\n\t\tif ([MarketingType.BUY1GET1, MarketingType.DISCOUNT].includes(marketing.marketingType)) {\n\t\t\tconst typedMarketing = marketing as DocumentType<DiscountMarketing | Buy1Get1Marketing>;\n\t\t\tconst productIds = typedMarketing.products.map((product: any) => product.product);\n\t\t\tconst isAvailable = await productMarketingService.checkProductMarketingAvailability(\n\t\t\t\tproductIds,\n\t\t\t\tmarketing.isAppliedByCompany\n\t\t\t);\n\n\t\t\tif (!isAvailable) {\n\t\t\t\tconflictError(\"You can't activate discount and B1G1 on the same items at the same time\");\n\t\t\t}\n\t\t}\n\n\t\tif (CONFLICT_CHECK_MARKETING_TYPES.includes(marketing.marketingType)) {\n\t\t\tawait marketingConflictService.assertNoConflict({\n\t\t\t\tshop: marketing.shop as mongoose.Types.ObjectId,\n\t\t\t\tmarketingType: marketing.marketingType,\n\t\t\t\tduration: marketing.duration,\n\t\t\t\trewardTypeGroups: marketingConflictService.getRewardTypeGroups(\n\t\t\t\t\tmarketing.marketingType,\n\t\t\t\t\t(marketing as any).tiers\n\t\t\t\t),\n\t\t\t\texcludeMarketingId: marketingId,\n\t\t\t});\n\t\t}\n\t}\n\n\tprivate async logMarketingAdminAction(\n\t\tadmin: mongoose.Types.ObjectId,\n\t\tactionType: AdminLogsUpdatedFieldsType,\n\t\toldDocument?: any,\n\t\tnewDocument?: any\n\t) {\n\t\tconst adminActivityLogsEvent: BaseEvent<Record<string, unknown>> = new AdminActivityLogsEvent({\n\t\t\tadmin,\n\t\t\tupdatedField: actionType,\n\t\t\toldDocument: oldDocument ?? '',\n\t\t\tnewDocument: newDocument ?? '',\n\t\t});\n\t\tawait publishEvent(adminActivityLogsEvent);\n\t}\n\n\t/**\n\t * Delete record\n\t * @param data Data for delete\n\t */\n\tpublic async deleteById(\n\t\tdata: DeleteDTO,\n\t\tadmin?: mongoose.Types.ObjectId,\n\t\toptions?: { skipLimitedTimeOfferGuard?: boolean }\n\t): Promise<string> {\n\t\tconst { _id, softDelete } = data;\n\n\t\tif ((await isLtoScheduleEnabled()) && !options?.skipLimitedTimeOfferGuard) {\n\t\t\tconst partOfLimitedTimeOffer = await this.limitedTimeOfferParticipantModel.exists({\n\t\t\t\tmarketing: _id,\n\t\t\t});\n\n\t\t\tif (partOfLimitedTimeOffer) {\n\t\t\t\tforbiddenError(\n\t\t\t\t\t'You are currently participating in a Limited Time Offer. Please make your edits from the Limited Time Offer section.'\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\tconst record = await this.model.findById(_id).populate({\n\t\t\tpath: 'shop',\n\t\t\tselect: '_id name shopId',\n\t\t});\n\n\t\tif (!record) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'NOT_FOUND',\n\t\t\t\tmessage: 'Record not found',\n\t\t\t});\n\t\t}\n\n\t\trecord.status = MarketingStatus.DELETED;\n\t\tawait record.save();\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: 'INTERNAL_SERVER_ERROR',\n\t\t\t\tmessage: 'Unable to delete marketing',\n\t\t\t});\n\t\t}\n\n\t\tif (admin) {\n\t\t\tthis.logMarketingAdminAction(admin, AdminLogsUpdatedFieldsType.DELETED_MARKETING_PROMOTIONS, record);\n\t\t}\n\n\t\tproductMarketingService.deleteMany({ marketing: data._id }, data.softDelete);\n\t\tpublishSyncSingleShopSectionsInCacheProcessEvent({\n\t\t\tshopId: record.shop._id,\n\t\t\toperation: ChangeStreamOperationTypes.DELETE,\n\t\t});\n\t\treturn 'Record deleted successfully';\n\t}\n\n\tpublic async deleteManyByIds(marketingIds: mongoose.Types.ObjectId[], softDelete = true): Promise<void> {\n\t\tif (marketingIds.length === 0) return;\n\n\t\tconst marketings = await this.model\n\t\t\t.find({ _id: { $in: marketingIds } })\n\t\t\t.select('shop')\n\t\t\t.lean();\n\n\t\tawait this.model.updateMany(\n\t\t\t{ _id: { $in: marketingIds } },\n\t\t\t{ $set: { status: MarketingStatus.DELETED } }\n\t\t);\n\t\tawait this.model.deleteRecords({ _id: { $in: marketingIds } }, softDelete);\n\n\t\tawait productMarketingService.deleteManyByMarketingIds(marketingIds, softDelete);\n\n\t\tconst uniqueShopIds = [\n\t\t\t...new Map(\n\t\t\t\tmarketings\n\t\t\t\t\t.map((m: any) => m.shop)\n\t\t\t\t\t.filter(Boolean)\n\t\t\t\t\t.map((s: any) => {\n\t\t\t\t\t\tconst id = s instanceof mongoose.Types.ObjectId ? s : new mongoose.Types.ObjectId(s);\n\t\t\t\t\t\treturn [id.toString(), id] as [string, mongoose.Types.ObjectId];\n\t\t\t\t\t})\n\t\t\t).values(),\n\t\t];\n\n\t\tfor (const shopId of uniqueShopIds) {\n\t\t\tpublishSyncSingleShopSectionsInCacheProcessEvent({\n\t\t\t\tshopId,\n\t\t\t\toperation: ChangeStreamOperationTypes.DELETE,\n\t\t\t});\n\t\t}\n\t}\n\n\tpublic async handleNewProductForEntireMenuMarketing(data: ProductEntireMenuMarketingHandlerDTO) {\n\t\tconst existingMarketing = await this.model.findOne({\n\t\t\tshop: data.shop,\n\t\t\tmarketingType: { $in: [MarketingType.BUY1GET1, MarketingType.DISCOUNT] },\n\t\t\t'duration.end': { $gt: new Date() },\n\t\t\tstatus: MarketingStatus.ACTIVE,\n\t\t\tisEntireMenu: true,\n\t\t});\n\n\t\t// check if existing marketing\n\t\tif (existingMarketing) {\n\t\t\tconst productMarketingData: CreateProductMarketingDTO = {\n\t\t\t\tproduct: data.product,\n\t\t\t\tmarketing: existingMarketing._id,\n\t\t\t};\n\t\t\tif (existingMarketing.marketingType == MarketingType.BUY1GET1) {\n\t\t\t\tproductMarketingData.isBuy1Get1 = true;\n\t\t\t}\n\t\t\tif (existingMarketing.marketingType == MarketingType.DISCOUNT) {\n\t\t\t\tproductMarketingData.value = (existingMarketing as DocumentType<DiscountMarketing>).value;\n\t\t\t\tproductMarketingData.valueType = (existingMarketing as DocumentType<DiscountMarketing>).valueType;\n\t\t\t}\n\n\t\t\tawait productMarketingService.create(productMarketingData);\n\t\t\tawait synchronizeProductMarketingService.syncProductMarketingInfoByProductId(data.product);\n\t\t}\n\n\t\treturn 'Product handled successfully';\n\t}\n\n\tpublic async incrementMarketingSpentFromOrder(orderId: mongoose.Types.ObjectId): Promise<any> {\n\t\tconst order = (await this.orderModel\n\t\t\t.findById(orderId)\n\t\t\t.populate([\n\t\t\t\t{ path: 'lineItems' },\n\t\t\t\t{ path: 'marketings', select: 'isAppliedByCompany' },\n\t\t\t])) as DocumentType<RegularOrder> & {\n\t\t\tlineItems: DocumentType<LineItem>[];\n\t\t\tmarketings: DocumentType<Marketing>[];\n\t\t};\n\n\t\tif (!order || !order.marketings?.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst marketingSpendMap = this.marketingMetricsRepository.calculateMarketingSpendPerOrder(order);\n\n\t\tconst bulkOps = [...marketingSpendMap.entries()].map(([marketingId, amountSpent]) => ({\n\t\t\tupdateOne: {\n\t\t\t\tfilter: { _id: marketingId },\n\t\t\t\tupdate: { $inc: { amountSpent } },\n\t\t\t},\n\t\t}));\n\n\t\tif (bulkOps.length) {\n\t\t\tawait this.model.bulkWrite(bulkOps);\n\t\t}\n\n\t\tawait this.expireMarketingsExceedingSpendLimits(Array.from(marketingSpendMap.keys()));\n\n\t\treturn 'Marketing amount spent incremented successfully';\n\t}\n\n\tpublic async decrementMarketingSpentFromOrder(orderId: mongoose.Types.ObjectId): Promise<any> {\n\t\tconst order = (await this.orderModel\n\t\t\t.findById(orderId)\n\t\t\t.populate([\n\t\t\t\t{ path: 'lineItems' },\n\t\t\t\t{ path: 'marketings', select: 'isAppliedByCompany' },\n\t\t\t])) as DocumentType<RegularOrder> & {\n\t\t\tlineItems: DocumentType<LineItem>[];\n\t\t\tmarketings: DocumentType<Marketing>[];\n\t\t};\n\n\t\tif (!order || !order.marketings?.length) {\n\t\t\treturn;\n\t\t}\n\n\t\tconst marketingSpendMap = this.marketingMetricsRepository.calculateMarketingSpendPerOrder(order);\n\n\t\tconst bulkOps = [...marketingSpendMap.entries()].map(([marketingId, amountSpent]) => ({\n\t\t\tupdateOne: {\n\t\t\t\tfilter: { _id: marketingId },\n\t\t\t\tupdate: { $inc: { amountSpent: -amountSpent } },\n\t\t\t},\n\t\t}));\n\n\t\tif (bulkOps.length) {\n\t\t\tawait this.model.bulkWrite(bulkOps);\n\t\t}\n\n\t\tawait this.unExpireMarketingsBelowSpendLimits(Array.from(marketingSpendMap.keys()));\n\n\t\treturn 'Marketing amount spent decremented successfully';\n\t}\n\n\tprivate async expireMarketingsExceedingSpendLimits(marketingIds: mongoose.Types.ObjectId[]) {\n\t\tconst update = await this.model.updateMany(\n\t\t\t{\n\t\t\t\t_id: { $in: marketingIds },\n\t\t\t\tisSpendLimitEnabled: true,\n\t\t\t\tstatus: { $ne: MarketingStatus.EXPIRED },\n\t\t\t\t$expr: { $gte: ['$amountSpent', '$spendLimit'] },\n\t\t\t},\n\t\t\t{ $set: { status: MarketingStatus.EXPIRED, expiredAt: dayjs().toDate() } }\n\t\t);\n\n\t\tif (update.modifiedCount > 0) {\n\t\t\tawait synchronizeProductMarketingService.syncProductMarketingInfoByMarketingIds(marketingIds);\n\t\t}\n\t}\n\n\tprivate async unExpireMarketingsBelowSpendLimits(marketingIds: mongoose.Types.ObjectId[]) {\n\t\tconst update = await this.model.updateMany(\n\t\t\t{\n\t\t\t\t_id: { $in: marketingIds },\n\t\t\t\tisSpendLimitEnabled: true,\n\t\t\t\tstatus: MarketingStatus.EXPIRED,\n\t\t\t\t$expr: { $lt: ['$amountSpent', '$spendLimit'] },\n\t\t\t},\n\t\t\t{ $set: { status: MarketingStatus.ACTIVE }, $unset: { expiredAt: 1 } }\n\t\t);\n\n\t\tif (update.modifiedCount > 0) {\n\t\t\tawait synchronizeProductMarketingService.syncProductMarketingInfoByMarketingIds(marketingIds);\n\t\t}\n\t}\n\n\tpublic async recomputeAndSyncAllMarketingSpent(): Promise<void> {\n\t\tconst cursor = this.model\n\t\t\t.find({ marketingType: { $ne: MarketingType.FEATURED } }, { _id: 1 })\n\t\t\t.lean()\n\t\t\t.cursor();\n\n\t\tconst bulkOps: mongoose.AnyBulkWriteOperation[] = [];\n\t\tconst marketingIds: mongoose.Types.ObjectId[] = [];\n\n\t\tfor await (const marketing of cursor) {\n\t\t\tconst { amount } = await this.marketingMetricsRepository.calculateMarketingSpent(marketing._id);\n\n\t\t\tbulkOps.push({\n\t\t\t\tupdateOne: {\n\t\t\t\t\tfilter: { _id: marketing._id },\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\t$set: { amountSpent: amount },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t});\n\n\t\t\tmarketingIds.push(marketing._id);\n\n\t\t\tif (bulkOps.length >= 500) {\n\t\t\t\tawait this.model.bulkWrite(bulkOps);\n\t\t\t\tbulkOps.length = 0;\n\t\t\t}\n\t\t}\n\n\t\tif (bulkOps.length) {\n\t\t\tawait this.model.bulkWrite(bulkOps);\n\t\t}\n\n\t\tawait this.expireMarketingsExceedingSpendLimits(marketingIds);\n\t\tawait this.unExpireMarketingsBelowSpendLimits(marketingIds);\n\t}\n\n\tpublic async reseedEntireMenuMarketing(marketingId: mongoose.Types.ObjectId): Promise<void> {\n\t\tconst logger = getLibraries().getLoggerKit();\n\n\t\tconst marketing = await this.model.findOne({ _id: marketingId, deletedAt: null });\n\t\tif (!marketing) internalServerError('Marketing not found');\n\n\t\tconst PAGE_SIZE = 500;\n\t\tconst mid = marketingId.toString();\n\t\tconst shopId = ((marketing.shop as any)?._id ?? marketing.shop).toString();\n\t\tconst count = await ProductModel.countDocuments({ shop: marketing.shop });\n\t\tconst pages = Math.ceil(count / PAGE_SIZE);\n\n\t\tif (!pages) return;\n\n\t\tawait Promise.all(\n\t\t\tArray.from({ length: pages }, (_, page) =>\n\t\t\t\tpublishEvent(\n\t\t\t\t\tnew MarketingEntireMenuSeedEvent({\n\t\t\t\t\t\tmarketingId: mid,\n\t\t\t\t\t\tshopId,\n\t\t\t\t\t\tisAppliedByCompany: marketing.isAppliedByCompany ?? false,\n\t\t\t\t\t\tisBuy1Get1: marketing.marketingType === MarketingType.BUY1GET1,\n\t\t\t\t\t\tvalue: (marketing as any).value,\n\t\t\t\t\t\tvalueType: (marketing as any).valueType,\n\t\t\t\t\t\tpage,\n\t\t\t\t\t\tpageSize: PAGE_SIZE,\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t)\n\t\t);\n\n\t\tlogger.debug(`entire-menu reseed dispatched — ${pages} pages for ${count} products`, {\n\t\t\ttag: 'marketing.seed.entire-menu',\n\t\t\tdata: { marketingId: mid, shopId, pages, productCount: count },\n\t\t});\n\t}\n\n\tpublic async assignMarketingToProducts(marketing: DocumentType<Buy1Get1Marketing | DiscountMarketing>) {\n\t\tconst diffStartTime = dayjs(marketing.duration.start).diff(dayjs(), 'milliseconds');\n\t\tif (diffStartTime > 0) {\n\t\t\treturn await scheduleMarketingProductSync(marketing._id.toString(), diffStartTime);\n\t\t}\n\n\t\tif (marketing.isEntireMenu) {\n\t\t\tconst logger = getLibraries().getLoggerKit();\n\t\t\tconst PAGE_SIZE = 500;\n\t\t\tconst marketingId = marketing._id.toString();\n\t\t\tconst shopId = ((marketing.shop as any)?._id ?? marketing.shop).toString();\n\n\t\t\tconst count = await ProductModel.countDocuments({ shop: marketing.shop });\n\t\t\tconst pages = Math.ceil(count / PAGE_SIZE);\n\n\t\t\tif (pages > 0) {\n\t\t\t\tawait Promise.all(\n\t\t\t\t\tArray.from({ length: pages }, (_, page) =>\n\t\t\t\t\t\tpublishEvent(\n\t\t\t\t\t\t\tnew MarketingEntireMenuSeedEvent({\n\t\t\t\t\t\t\t\tmarketingId,\n\t\t\t\t\t\t\t\tshopId,\n\t\t\t\t\t\t\t\tisAppliedByCompany: marketing.isAppliedByCompany ?? false,\n\t\t\t\t\t\t\t\tisBuy1Get1: marketing.marketingType === MarketingType.BUY1GET1,\n\t\t\t\t\t\t\t\tvalue: (marketing as any).value,\n\t\t\t\t\t\t\t\tvalueType: (marketing as any).valueType,\n\t\t\t\t\t\t\t\tpage,\n\t\t\t\t\t\t\t\tpageSize: PAGE_SIZE,\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\n\t\t\t\tlogger.debug(`entire-menu marketing seed dispatched — ${pages} pages for ${count} products`, {\n\t\t\t\t\ttag: 'marketing.seed.entire-menu',\n\t\t\t\t\tdata: { marketingId, shopId, pages, productCount: count },\n\t\t\t\t});\n\t\t\t}\n\t\t} else {\n\t\t\tawait productMarketingService.syncProductMarketingInfo(marketing._id);\n\t\t}\n\t}\n}\n\nexport const marketingService = Container.get(MarketingService);\n"]}
|
|
@@ -25,8 +25,10 @@ export declare class ProductMarketingService {
|
|
|
25
25
|
checkProductMarketingAvailability(products: mongoose.Types.ObjectId[], isAppliedByCompany?: boolean): Promise<boolean>;
|
|
26
26
|
pauseConflictingMarketings(products: mongoose.Types.ObjectId[]): Promise<mongoose.Types.ObjectId[]>;
|
|
27
27
|
upsertProductMarketingsForPage(data: {
|
|
28
|
+
shop: mongoose.Types.ObjectId;
|
|
28
29
|
marketingId: mongoose.Types.ObjectId;
|
|
29
|
-
|
|
30
|
+
page: number;
|
|
31
|
+
pageSize: number;
|
|
30
32
|
isAppliedByCompany: boolean;
|
|
31
33
|
isBuy1Get1: boolean;
|
|
32
34
|
value?: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"product-marketing.service.d.ts","sourceRoot":"/","sources":["modules/marketing/services/product-marketing.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAmB,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAGN,gBAAgB,IAAI,KAAK,EAEzB,MAAM,4CAA4C,CAAC;AACpD,OAAO,EACN,oCAAoC,EACpC,yBAAyB,IAAI,SAAS,EACtC,wBAAwB,IAAI,QAAQ,EACpC,gCAAgC,EAChC,yBAAyB,IAAI,SAAS,EACtC,MAAM,gCAAgC,CAAC;AAExC,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,MAAM,yCAAyC,CAAC;AAEvF,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAC3D,OAAO,EAA0C,SAAS,EAAE,MAAM,mCAAmC,CAAC;AAOtG,qBACa,uBAAuB;IACnC,OAAO,CAAC,KAAK,CAAwD;IACrE,OAAO,CAAC,YAAY,CAAsB;IAE1C,OAAO,CAAC,gCAAgC,CAAqC;;IAahE,MAAM,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAUrD,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAI5C,oBAAoB,CAAC,CAAC,EAAE,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,GAAG;IAkB1E,mBAAmB,CAAC,CAAC,EAAE,KAAK,EAAE,QAAQ,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,CAAC,KAAK,GAAG;YAkBlE,gBAAgB;IAsDjB,uBAAuB,CAAC,IAAI,EAAE,oCAAoC,GAAG,OAAO,CAAC,IAAI,CAAC;IAoDlF,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IAkB5E,IAAI,CAAC,IAAI,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,GAAG,OAAO,CAAC,iBAAiB,CAAC,YAAY,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IA0B3F,SAAS,CAAC,KAAK,EAAE,QAAQ,EAAE,IAAI,EAAE,SAAS,GAAG,OAAO,CAAC,MAAM,CAAC;IAoB5D,UAAU,CAAC,MAAM,EAAE,QAAQ,EAAE,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC;IAgBlE,wBAAwB,CAAC,YAAY,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,OAAO,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BrG,wBAAwB,CAAC,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ;
|
|
1
|
+
{"version":3,"file":"product-marketing.service.d.ts","sourceRoot":"/","sources":["modules/marketing/services/product-marketing.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -245,10 +245,7 @@ let ProductMarketingService = class ProductMarketingService {
|
|
|
245
245
|
}
|
|
246
246
|
}
|
|
247
247
|
async syncProductMarketingInfo(marketingId) {
|
|
248
|
-
const productMarketings = await this.model
|
|
249
|
-
.find({ marketing: marketingId, deletedAt: null })
|
|
250
|
-
.select('product')
|
|
251
|
-
.lean();
|
|
248
|
+
const productMarketings = await this.model.find({ marketing: marketingId });
|
|
252
249
|
const productIds = productMarketings
|
|
253
250
|
.map((r) => r.product)
|
|
254
251
|
.filter((p) => !!p)
|
|
@@ -326,21 +323,27 @@ let ProductMarketingService = class ProductMarketingService {
|
|
|
326
323
|
return marketingIds;
|
|
327
324
|
}
|
|
328
325
|
async upsertProductMarketingsForPage(data) {
|
|
329
|
-
const { marketingId,
|
|
330
|
-
|
|
326
|
+
const { shop, marketingId, page, pageSize, isAppliedByCompany, isBuy1Get1, value, valueType } = data;
|
|
327
|
+
const products = await this.productModel
|
|
328
|
+
.find({ shop })
|
|
329
|
+
.select('_id')
|
|
330
|
+
.skip(page * pageSize)
|
|
331
|
+
.limit(pageSize)
|
|
332
|
+
.lean();
|
|
333
|
+
if (!products.length)
|
|
331
334
|
return [];
|
|
332
|
-
const ops =
|
|
335
|
+
const ops = products.map(product => ({
|
|
333
336
|
updateOne: {
|
|
334
|
-
filter: { marketing: marketingId, product:
|
|
337
|
+
filter: { marketing: marketingId, product: product._id, deletedAt: null },
|
|
335
338
|
update: {
|
|
336
339
|
$set: { value, valueType, isAppliedByCompany, isBuy1Get1 },
|
|
337
|
-
$setOnInsert: { marketing: marketingId, product:
|
|
340
|
+
$setOnInsert: { marketing: marketingId, product: product._id },
|
|
338
341
|
},
|
|
339
342
|
upsert: true,
|
|
340
343
|
},
|
|
341
344
|
}));
|
|
342
345
|
await this.model.bulkWrite(ops);
|
|
343
|
-
return
|
|
346
|
+
return products.map(p => p._id);
|
|
344
347
|
}
|
|
345
348
|
async countDocuments(filter) {
|
|
346
349
|
const count = await this.model.countDocuments({ ...filter, deletedAt: null });
|