@lyxa.ai/marketing 1.0.53 → 1.0.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (97) hide show
  1. package/dist/lib/index.d.ts +675 -28
  2. package/dist/lib/index.d.ts.map +1 -1
  3. package/dist/lib/modules/coupon/routers/coupon.router.d.ts +647 -0
  4. package/dist/lib/modules/coupon/routers/coupon.router.d.ts.map +1 -1
  5. package/dist/lib/modules/coupon/routers/coupon.router.js +8 -1
  6. package/dist/lib/modules/coupon/routers/coupon.router.js.map +1 -1
  7. package/dist/lib/modules/coupon/services/coupon.service.d.ts +8 -1
  8. package/dist/lib/modules/coupon/services/coupon.service.d.ts.map +1 -1
  9. package/dist/lib/modules/coupon/services/coupon.service.js +231 -27
  10. package/dist/lib/modules/coupon/services/coupon.service.js.map +1 -1
  11. package/dist/lib/modules/coupon/services/patterns/repository/CouponMetricsRepository.js +2 -2
  12. package/dist/lib/modules/coupon/services/patterns/repository/CouponMetricsRepository.js.map +1 -1
  13. package/dist/lib/modules/coupon/validations/all-coupons.validation.d.ts +293 -1125
  14. package/dist/lib/modules/coupon/validations/all-coupons.validation.d.ts.map +1 -1
  15. package/dist/lib/modules/coupon/validations/all-coupons.validation.js +2 -16
  16. package/dist/lib/modules/coupon/validations/all-coupons.validation.js.map +1 -1
  17. package/dist/lib/modules/coupon/validations/coupon.validation.d.ts +26 -0
  18. package/dist/lib/modules/coupon/validations/coupon.validation.d.ts.map +1 -1
  19. package/dist/lib/modules/coupon/validations/coupon.validation.js +10 -1
  20. package/dist/lib/modules/coupon/validations/coupon.validation.js.map +1 -1
  21. package/dist/lib/modules/coupon/validations/index.d.ts +1 -0
  22. package/dist/lib/modules/coupon/validations/index.d.ts.map +1 -1
  23. package/dist/lib/modules/coupon/validations/index.js +1 -0
  24. package/dist/lib/modules/coupon/validations/index.js.map +1 -1
  25. package/dist/lib/modules/limited-time-offer/campaign/campaign.router.d.ts +8 -8
  26. package/dist/lib/modules/limited-time-offer/campaign/limited-time-offer-campaign.validation.d.ts +34 -34
  27. package/dist/lib/modules/limited-time-offer/limited-time-offer.router.d.ts +28 -28
  28. package/dist/lib/modules/limited-time-offer/limited-time-offer.service.d.ts +1 -0
  29. package/dist/lib/modules/limited-time-offer/limited-time-offer.service.d.ts.map +1 -1
  30. package/dist/lib/modules/limited-time-offer/limited-time-offer.service.js +6 -0
  31. package/dist/lib/modules/limited-time-offer/limited-time-offer.service.js.map +1 -1
  32. package/dist/lib/modules/limited-time-offer/notification/limited-time-offer-notification.builder.d.ts +13 -0
  33. package/dist/lib/modules/limited-time-offer/notification/limited-time-offer-notification.builder.d.ts.map +1 -0
  34. package/dist/lib/modules/limited-time-offer/notification/limited-time-offer-notification.builder.js +22 -0
  35. package/dist/lib/modules/limited-time-offer/notification/limited-time-offer-notification.builder.js.map +1 -0
  36. package/dist/lib/modules/limited-time-offer/notification/limited-time-offer-notification.constants.d.ts +20 -0
  37. package/dist/lib/modules/limited-time-offer/notification/limited-time-offer-notification.constants.d.ts.map +1 -0
  38. package/dist/lib/modules/limited-time-offer/notification/limited-time-offer-notification.constants.js +26 -0
  39. package/dist/lib/modules/limited-time-offer/notification/limited-time-offer-notification.constants.js.map +1 -0
  40. package/dist/lib/modules/limited-time-offer/notification/limited-time-offer-notification.service.d.ts +8 -0
  41. package/dist/lib/modules/limited-time-offer/notification/limited-time-offer-notification.service.d.ts.map +1 -0
  42. package/dist/lib/modules/limited-time-offer/notification/limited-time-offer-notification.service.js +60 -0
  43. package/dist/lib/modules/limited-time-offer/notification/limited-time-offer-notification.service.js.map +1 -0
  44. package/dist/lib/modules/limited-time-offer/notification/limited-time-offer-notification.type.d.ts +5 -0
  45. package/dist/lib/modules/limited-time-offer/notification/limited-time-offer-notification.type.d.ts.map +1 -0
  46. package/dist/lib/modules/limited-time-offer/notification/limited-time-offer-notification.type.js +3 -0
  47. package/dist/lib/modules/limited-time-offer/notification/limited-time-offer-notification.type.js.map +1 -0
  48. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.builder.js +1 -1
  49. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.builder.js.map +1 -1
  50. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.repository.d.ts +1 -0
  51. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.repository.d.ts.map +1 -1
  52. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.repository.js +8 -1
  53. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.repository.js.map +1 -1
  54. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.router.d.ts +20 -20
  55. package/dist/lib/modules/limited-time-offer/participant/limited-time-offer-participant.validation.d.ts +82 -82
  56. package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.d.ts +2 -1
  57. package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.d.ts.map +1 -1
  58. package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.js +12 -5
  59. package/dist/lib/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.js.map +1 -1
  60. package/dist/lib/modules/marketing/services/marketing.service.d.ts +1 -0
  61. package/dist/lib/modules/marketing/services/marketing.service.d.ts.map +1 -1
  62. package/dist/lib/modules/marketing/services/marketing.service.js +9 -0
  63. package/dist/lib/modules/marketing/services/marketing.service.js.map +1 -1
  64. package/dist/types/index.d.ts +675 -28
  65. package/dist/types/index.d.ts.map +1 -1
  66. package/dist/types/modules/coupon/routers/coupon.router.d.ts +647 -0
  67. package/dist/types/modules/coupon/routers/coupon.router.d.ts.map +1 -1
  68. package/dist/types/modules/coupon/services/coupon.service.d.ts +8 -1
  69. package/dist/types/modules/coupon/services/coupon.service.d.ts.map +1 -1
  70. package/dist/types/modules/coupon/validations/all-coupons.validation.d.ts +293 -1125
  71. package/dist/types/modules/coupon/validations/all-coupons.validation.d.ts.map +1 -1
  72. package/dist/types/modules/coupon/validations/coupon.validation.d.ts +26 -0
  73. package/dist/types/modules/coupon/validations/coupon.validation.d.ts.map +1 -1
  74. package/dist/types/modules/coupon/validations/index.d.ts +1 -0
  75. package/dist/types/modules/coupon/validations/index.d.ts.map +1 -1
  76. package/dist/types/modules/limited-time-offer/campaign/campaign.router.d.ts +8 -8
  77. package/dist/types/modules/limited-time-offer/campaign/limited-time-offer-campaign.validation.d.ts +34 -34
  78. package/dist/types/modules/limited-time-offer/limited-time-offer.router.d.ts +28 -28
  79. package/dist/types/modules/limited-time-offer/limited-time-offer.service.d.ts +1 -0
  80. package/dist/types/modules/limited-time-offer/limited-time-offer.service.d.ts.map +1 -1
  81. package/dist/types/modules/limited-time-offer/notification/limited-time-offer-notification.builder.d.ts +13 -0
  82. package/dist/types/modules/limited-time-offer/notification/limited-time-offer-notification.builder.d.ts.map +1 -0
  83. package/dist/types/modules/limited-time-offer/notification/limited-time-offer-notification.constants.d.ts +20 -0
  84. package/dist/types/modules/limited-time-offer/notification/limited-time-offer-notification.constants.d.ts.map +1 -0
  85. package/dist/types/modules/limited-time-offer/notification/limited-time-offer-notification.service.d.ts +8 -0
  86. package/dist/types/modules/limited-time-offer/notification/limited-time-offer-notification.service.d.ts.map +1 -0
  87. package/dist/types/modules/limited-time-offer/notification/limited-time-offer-notification.type.d.ts +5 -0
  88. package/dist/types/modules/limited-time-offer/notification/limited-time-offer-notification.type.d.ts.map +1 -0
  89. package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.repository.d.ts +1 -0
  90. package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.repository.d.ts.map +1 -1
  91. package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.router.d.ts +20 -20
  92. package/dist/types/modules/limited-time-offer/participant/limited-time-offer-participant.validation.d.ts +82 -82
  93. package/dist/types/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.d.ts +2 -1
  94. package/dist/types/modules/limited-time-offer/participant/services/limited-time-offer-participant.service.d.ts.map +1 -1
  95. package/dist/types/modules/marketing/services/marketing.service.d.ts +1 -0
  96. package/dist/types/modules/marketing/services/marketing.service.d.ts.map +1 -1
  97. package/package.json +2 -2
@@ -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\tLineItem,\n\tMarketing,\n\tMarketingModel,\n\tMarketing as Model,\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\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,\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 {\n\tbuy1Get1MarketingService,\n\tdiscountMarketingService,\n\tfeaturedMarketingService,\n\tfreeDeliveryMarketingService,\n\tproductMarketingService,\n\tpunchMarketingService,\n\tsynchronizeProductMarketingService,\n} from '.';\nimport { MarketingType } from '@lyxa.ai/core/dist/utilities/enum';\nimport {\n\tconflictError,\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';\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\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}\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): Promise<DocumentType<Model>> {\n\t\tconst now = dayjs().toDate();\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});\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 (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\tconst isAvailable = await productMarketingService.checkProductMarketingAvailability(\n\t\t\t\tproductIds,\n\t\t\t\tdata.isAppliedByCompany\n\t\t\t);\n\n\t\t\tif (!isAvailable) {\n\t\t\t\tthrow new TRPCError({\n\t\t\t\t\tcode: 'CONFLICT',\n\t\t\t\t\tmessage: `Product list contains products which already have marketing applied`,\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\tdefault: {\n\t\t\t\tmarketing = await this.model.create(data, admin);\n\t\t\t}\n\t\t}\n\n\t\tif (data.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 = data.shop.toString();\n\n\t\t\tconst count = await ProductModel.countDocuments({ shop: data.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: data.isAppliedByCompany ?? false,\n\t\t\t\t\t\t\t\tisBuy1Get1: data.marketingType === MarketingType.BUY1GET1,\n\t\t\t\t\t\t\t\tvalue: (data as any).value,\n\t\t\t\t\t\t\t\tvalueType: (data 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\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 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.PAUSED\n\t\t) {\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\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 productMarketingService.syncProductMarketingInfo(_id);\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\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(data: DeleteDTO, admin?: mongoose.Types.ObjectId): Promise<string> {\n\t\tconst { _id, softDelete } = data;\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.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\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\tMarketingModel,\n\tMarketing as Model,\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\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,\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 {\n\tbuy1Get1MarketingService,\n\tdiscountMarketingService,\n\tfeaturedMarketingService,\n\tfreeDeliveryMarketingService,\n\tproductMarketingService,\n\tpunchMarketingService,\n\tsynchronizeProductMarketingService,\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';\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): Promise<DocumentType<Model>> {\n\t\tconst now = dayjs().toDate();\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});\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 (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\tconst isAvailable = await productMarketingService.checkProductMarketingAvailability(\n\t\t\t\tproductIds,\n\t\t\t\tdata.isAppliedByCompany\n\t\t\t);\n\n\t\t\tif (!isAvailable) {\n\t\t\t\tthrow new TRPCError({\n\t\t\t\t\tcode: 'CONFLICT',\n\t\t\t\t\tmessage: `Product list contains products which already have marketing applied`,\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\tdefault: {\n\t\t\t\tmarketing = await this.model.create(data, admin);\n\t\t\t}\n\t\t}\n\n\t\tif (data.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 = data.shop.toString();\n\n\t\t\tconst count = await ProductModel.countDocuments({ shop: data.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: data.isAppliedByCompany ?? false,\n\t\t\t\t\t\t\t\tisBuy1Get1: data.marketingType === MarketingType.BUY1GET1,\n\t\t\t\t\t\t\t\tvalue: (data as any).value,\n\t\t\t\t\t\t\t\tvalueType: (data 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\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.PAUSED\n\t\t) {\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\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 productMarketingService.syncProductMarketingInfo(_id);\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\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(data: DeleteDTO, admin?: mongoose.Types.ObjectId): Promise<string> {\n\t\tconst { _id, softDelete } = data;\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.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\nexport const marketingService = Container.get(MarketingService);\n"]}