@lyxa.ai/marketing 1.0.40 → 1.0.41

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 (74) hide show
  1. package/dist/lib/index.d.ts +9 -0
  2. package/dist/lib/index.d.ts.map +1 -1
  3. package/dist/lib/modules/coupon/routers/coupon.router.d.ts +4 -0
  4. package/dist/lib/modules/coupon/routers/coupon.router.d.ts.map +1 -1
  5. package/dist/lib/modules/coupon/services/coupon.service.d.ts.map +1 -1
  6. package/dist/lib/modules/coupon/services/coupon.service.js +13 -25
  7. package/dist/lib/modules/coupon/services/coupon.service.js.map +1 -1
  8. package/dist/lib/modules/coupon/services/custom-coupon.service.d.ts +28 -2
  9. package/dist/lib/modules/coupon/services/custom-coupon.service.d.ts.map +1 -1
  10. package/dist/lib/modules/coupon/services/custom-coupon.service.js +13 -33
  11. package/dist/lib/modules/coupon/services/custom-coupon.service.js.map +1 -1
  12. package/dist/lib/modules/coupon/services/helper.service.d.ts +30 -2
  13. package/dist/lib/modules/coupon/services/helper.service.d.ts.map +1 -1
  14. package/dist/lib/modules/coupon/services/helper.service.js +112 -4
  15. package/dist/lib/modules/coupon/services/helper.service.js.map +1 -1
  16. package/dist/lib/modules/coupon/services/individual-store-coupon.service.d.ts +29 -3
  17. package/dist/lib/modules/coupon/services/individual-store-coupon.service.d.ts.map +1 -1
  18. package/dist/lib/modules/coupon/services/individual-store-coupon.service.js +10 -62
  19. package/dist/lib/modules/coupon/services/individual-store-coupon.service.js.map +1 -1
  20. package/dist/lib/modules/coupon/services/patterns/repository/CouponRepository.d.ts.map +1 -1
  21. package/dist/lib/modules/coupon/services/patterns/repository/CouponRepository.js +9 -6
  22. package/dist/lib/modules/coupon/services/patterns/repository/CouponRepository.js.map +1 -1
  23. package/dist/lib/modules/coupon/services/referral-code-coupon.service.d.ts +9 -0
  24. package/dist/lib/modules/coupon/services/referral-code-coupon.service.d.ts.map +1 -1
  25. package/dist/lib/modules/coupon/services/referral-code-coupon.service.js +96 -29
  26. package/dist/lib/modules/coupon/services/referral-code-coupon.service.js.map +1 -1
  27. package/dist/lib/modules/coupon/services/shops-categories-coupon.service.d.ts +29 -3
  28. package/dist/lib/modules/coupon/services/shops-categories-coupon.service.d.ts.map +1 -1
  29. package/dist/lib/modules/coupon/services/shops-categories-coupon.service.js +10 -63
  30. package/dist/lib/modules/coupon/services/shops-categories-coupon.service.js.map +1 -1
  31. package/dist/lib/modules/coupon/validations/coupon.validation.d.ts +13 -0
  32. package/dist/lib/modules/coupon/validations/coupon.validation.d.ts.map +1 -1
  33. package/dist/lib/modules/coupon/validations/coupon.validation.js +3 -2
  34. package/dist/lib/modules/coupon/validations/coupon.validation.js.map +1 -1
  35. package/dist/lib/modules/deal-setting/services/deal-setting.service.d.ts.map +1 -1
  36. package/dist/lib/modules/deal-setting/services/deal-setting.service.js +4 -4
  37. package/dist/lib/modules/deal-setting/services/deal-setting.service.js.map +1 -1
  38. package/dist/lib/modules/marketing/patterns/repository/MarketingMetricsRepository.d.ts.map +1 -1
  39. package/dist/lib/modules/marketing/patterns/repository/MarketingMetricsRepository.js.map +1 -1
  40. package/dist/lib/modules/marketing/routers/marketing.router.d.ts +5 -0
  41. package/dist/lib/modules/marketing/routers/marketing.router.d.ts.map +1 -1
  42. package/dist/lib/modules/marketing/routers/marketing.router.js +3 -0
  43. package/dist/lib/modules/marketing/routers/marketing.router.js.map +1 -1
  44. package/dist/lib/modules/marketing/services/synchronize-product-marketing.service.d.ts.map +1 -1
  45. package/dist/lib/modules/marketing/services/synchronize-product-marketing.service.js +28 -7
  46. package/dist/lib/modules/marketing/services/synchronize-product-marketing.service.js.map +1 -1
  47. package/dist/lib/modules/marketing/validations/buy1-get1-marketing.validation.d.ts +12 -12
  48. package/dist/lib/modules/marketing/validations/discount-marketing.validation.d.ts +12 -12
  49. package/dist/types/index.d.ts +9 -0
  50. package/dist/types/index.d.ts.map +1 -1
  51. package/dist/types/modules/coupon/routers/coupon.router.d.ts +4 -0
  52. package/dist/types/modules/coupon/routers/coupon.router.d.ts.map +1 -1
  53. package/dist/types/modules/coupon/services/coupon.service.d.ts.map +1 -1
  54. package/dist/types/modules/coupon/services/custom-coupon.service.d.ts +28 -2
  55. package/dist/types/modules/coupon/services/custom-coupon.service.d.ts.map +1 -1
  56. package/dist/types/modules/coupon/services/helper.service.d.ts +30 -2
  57. package/dist/types/modules/coupon/services/helper.service.d.ts.map +1 -1
  58. package/dist/types/modules/coupon/services/individual-store-coupon.service.d.ts +29 -3
  59. package/dist/types/modules/coupon/services/individual-store-coupon.service.d.ts.map +1 -1
  60. package/dist/types/modules/coupon/services/patterns/repository/CouponRepository.d.ts.map +1 -1
  61. package/dist/types/modules/coupon/services/referral-code-coupon.service.d.ts +57 -0
  62. package/dist/types/modules/coupon/services/referral-code-coupon.service.d.ts.map +1 -1
  63. package/dist/types/modules/coupon/services/shops-categories-coupon.service.d.ts +29 -3
  64. package/dist/types/modules/coupon/services/shops-categories-coupon.service.d.ts.map +1 -1
  65. package/dist/types/modules/coupon/validations/coupon.validation.d.ts +13 -0
  66. package/dist/types/modules/coupon/validations/coupon.validation.d.ts.map +1 -1
  67. package/dist/types/modules/deal-setting/services/deal-setting.service.d.ts.map +1 -1
  68. package/dist/types/modules/marketing/patterns/repository/MarketingMetricsRepository.d.ts.map +1 -1
  69. package/dist/types/modules/marketing/routers/marketing.router.d.ts +5 -0
  70. package/dist/types/modules/marketing/routers/marketing.router.d.ts.map +1 -1
  71. package/dist/types/modules/marketing/services/synchronize-product-marketing.service.d.ts.map +1 -1
  72. package/dist/types/modules/marketing/validations/buy1-get1-marketing.validation.d.ts +12 -12
  73. package/dist/types/modules/marketing/validations/discount-marketing.validation.d.ts +12 -12
  74. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"coupon.validation.js","sourceRoot":"/","sources":["modules/coupon/validations/coupon.validation.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AACxB,iGAImE;AACnE,4DAA0G;AAC1G,iGAGmE;AACnE,8DAA2D;AAK9C,QAAA,YAAY,GAAG;IAC3B,IAAI,EAAE,iCAAa,CAAC,MAAM,CAAC,MAAM,EAAE;QAClC,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,MAAM,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,+BAA+B,EAAE;QACvF,SAAS,EAAE,EAAE;QACb,SAAS,EAAE,EAAE;QACb,UAAU,EAAE,8BAA8B;QAC1C,UAAU,EAAE,8BAA8B;KAC1C,CAAC;IACF,iBAAiB,EAAE,iCAAa,CAAC,MAAM,CAAC,mBAAmB,CAAC;SAC1D,WAAW,EAAE;SACb,QAAQ,EAAE;SACV,QAAQ,EAAE;SACV,OAAO,CAAC,IAAI,CAAC;IACf,0BAA0B,EAAE,iCAAa,CAAC,OAAO,CAAC,iCAAiC,CAAC;SAClF,QAAQ,EAAE;SACV,OAAO,CAAC,KAAK,CAAC;IAChB,SAAS,EAAE,iCAAa,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE;IAC1D,SAAS,EAAE,iCAAa,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE;CACzD,CAAC;AAEW,QAAA,UAAU,GAAG;IACzB,GAAG,oBAAY;IACf,SAAS,EAAE,iCAAa,CAAC,QAAQ,CAAC,gBAAS,EAAE,YAAY,CAAC;IAC1D,KAAK,EAAE,iCAAa,CAAC,MAAM,CAAC,OAAO,CAAC;IACpC,sBAAsB,EAAE,iCAAa,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC,QAAQ,EAAE;IACnF,gBAAgB,EAAE,iCAAa,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAChG,iCAAiC,EAAE,iCAAa,CAAC,MAAM,CAAC,uCAAuC,CAAC,CAAC,QAAQ,EAAE;IAC3G,yBAAyB,EAAE,iCAAa,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAC3G,QAAQ,EAAE,kCAAc;SAItB,SAAS,CAAC,QAAQ,CAAC,EAAE;QACrB,QAAQ,CAAC,KAAK,GAAG,IAAA,aAAK,EAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QAChD,QAAQ,CAAC,GAAG,GAAG,IAAA,aAAK,EAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;QAC5C,OAAO,QAAQ,CAAC;IACjB,CAAC,CAAC;IACH,UAAU,EAAE,iCAAa,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IACnF,mBAAmB,EAAE,iCAAa,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAC9F,eAAe,EAAE,iCAAa,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAC9F,wBAAwB,EAAE,iCAAa,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACzG,aAAa,EAAE,iCAAa,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAC/E,8BAA8B,EAAE,iCAAa,CAAC,MAAM,CAAC,oCAAoC,CAAC,CAAC,QAAQ,EAAE;IACrG,sBAAsB,EAAE,iCAAa,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACrG,cAAc,EAAE,iCAAa,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACjF,MAAM,EAAE,iCAAa,CAAC,QAAQ,CAAC,aAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,aAAM,CAAC,MAAM,CAAC;IAClF,gBAAgB,EAAE,iCAAa,CAAC,QAAQ,CAAC,6BAAsB,EAAE,mBAAmB,CAAC;SACnF,QAAQ,EAAE;SACV,QAAQ,EAAE;SACV,OAAO,CAAC,IAAI,CAAC;IACf,aAAa,EAAE,OAAC;SACd,MAAM,CAAC;QACP,IAAI,EAAE,iCAAa,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,QAAQ,EAAE;KAC5D,CAAC;SACD,QAAQ,EAAE;CACZ,CAAC;AAOF,MAAM,aAAa,GAAG,IAAA,uCAAmB,EAAC,kBAAU,CAAC,CAAC;AAKtD,MAAM,EACL,UAAU,EAAE,sBAAsB,EAClC,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,cAAc,EACxB,YAAY,EAAE,kBAAkB,GAChC,GAAG,aAAa,CAAC,aAAa,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAYpD,wDAAsB;AACtB,oCAAY;AACM,kDAAwB;AAC1C,gDAAkB;AAVN,QAAA,4BAA4B,GAAG,OAAC,CAAC,MAAM,CAAC;IACpD,SAAS,EAAE,OAAC,CAAC,KAAK,CAAC,YAAY,CAAC;IAChC,IAAI,EAAE,OAAC,CAAC,KAAK,CAAC,YAAY,CAAC;IAC3B,OAAO,EAAE,OAAC,CAAC,KAAK,CAAC,YAAY,CAAC;CAC9B,CAAC,CAAC;AAYU,QAAA,mBAAmB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC3C,IAAI,EAAE,iCAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE;IAC/C,IAAI,EAAE,iCAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE;IAC/C,IAAI,EAAE,iCAAa,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACxD,IAAI,EAAE,iCAAa,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;CAC/D,CAAC,CAAC;AAKU,QAAA,oBAAoB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC5C,IAAI,EAAE,iCAAa,CAAC,sBAAsB;IAC1C,IAAI,EAAE,iCAAa,CAAC,sBAAsB;IAC1C,MAAM,EAAE,iCAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE;IACjD,kBAAkB,EAAE,iCAAa,CAAC,MAAM,CAAC,sBAAsB,CAAC;IAChE,2BAA2B,EAAE,iCAAa,CAAC,MAAM,CAAC,gCAAgC,CAAC;IACnF,WAAW,EAAE,iCAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,QAAQ,EAAE;CAC1D,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,OAAC,CAAC,MAAM,CAAC;IAClC,UAAU,EAAE,iCAAa,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE;IACzD,mBAAmB,EAAE,iCAAa,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,QAAQ,EAAE;IAC3E,OAAO,EAAE,iCAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE;IACnD,gBAAgB,EAAE,iCAAa,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,QAAQ,EAAE;CACrE,CAAC,CAAC;AAKU,QAAA,4BAA4B,GAAG,OAAC,CAAC,MAAM,CAAC;IACpD,OAAO,EAAE,iCAAa,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IACxD,OAAO,EAAE,iCAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE;IACnD,iBAAiB,EAAE,iCAAa,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,QAAQ,EAAE;IACzE,0BAA0B,EAAE,iCAAa,CAAC,MAAM,CAAC,+BAA+B,CAAC,CAAC,QAAQ,EAAE;IAC5F,cAAc,EAAE,iCAAa,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE;IAClE,uBAAuB,EAAE,iCAAa,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,QAAQ,EAAE;IACrF,WAAW,EAAE,iBAAiB,CAAC,QAAQ,EAAE;CACzC,CAAC,CAAC;AAEU,QAAA,gBAAgB,GAAG,OAAC,CAAC,MAAM,CAAC;IACxC,UAAU,EAAE,iCAAa,CAAC,MAAM,CAAC,aAAa,CAAC;CAC/C,CAAC,CAAC;AAEU,QAAA,wBAAwB,GAAG,OAAC,CAAC,MAAM,CAAC;IAChD,GAAG,EAAE,iCAAa,CAAC,sBAAsB;IACzC,MAAM,EAAE,iCAAa,CAAC,QAAQ,CAAC,aAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,aAAM,CAAC,MAAM,CAAC;CAClF,CAAC,CAAC;AAEU,QAAA,sCAAsC,GAAG,OAAC,CAAC,MAAM,CAAC;IAC9D,MAAM,EAAE,iCAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;CACtD,CAAC,CAAC;AAEU,QAAA,8BAA8B,GAAG,IAAA,wCAAoB,EAAC,oCAA4B,CAAC,CAAC;AAEpF,QAAA,cAAc,GAAG,OAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACpD,QAAA,2BAA2B,GAAG,OAAC,CAAC,MAAM,CAAC,EAAE,qBAAqB,EAAE,OAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC","sourcesContent":["import { z } from 'zod';\nimport {\n\tZodValidation,\n\tcreateSchemaBuilder,\n\tDTO,\n} from '@lyxa.ai/core/dist/utilities/validation/global-validation';\nimport { CouponExpirationReason, CouponType, Status, ValueType } from '@lyxa.ai/core/dist/utilities/enum';\nimport {\n\tcreateResponseSchema,\n\tDurationSchema,\n} from '@lyxa.ai/core/dist/utilities/validation/common-validation';\nimport { dayjs } from '@lyxa.ai/core/dist/utilities/dayjs';\n\n/**\n * Define the base parent schema fields\n */\nexport const couponFields = {\n\tcode: ZodValidation.string('Code', {\n\t\tregex: { pattern: new RegExp('^[A-Z0-9]+$'), message: 'Coupon name must be uppercase' },\n\t\tmaxLength: 10,\n\t\tminLength: 10,\n\t\tminMessage: 'Coupon must be 10 characters',\n\t\tmaxMessage: 'Coupon must be 10 characters',\n\t}),\n\torderLimitPerUser: ZodValidation.number('OrderLimitPerUser')\n\t\t.nonnegative()\n\t\t.optional()\n\t\t.nullable()\n\t\t.default(null),\n\tisOrderLimitPerUserEnabled: ZodValidation.boolean('Is order limit per user enabled')\n\t\t.optional()\n\t\t.default(false),\n\tcreatedBy: ZodValidation.objectId('Created by').optional(),\n\tisExpired: ZodValidation.boolean('Is expired').optional(),\n};\n\nexport const baseFields = {\n\t...couponFields,\n\tvalueType: ZodValidation.enumType(ValueType, 'Value type'),\n\tvalue: ZodValidation.number('Value'),\n\tsecondaryCurrencyValue: ZodValidation.number('Secondary currency value').optional(),\n\tmaxDiscountLimit: ZodValidation.number('Max discount limit').optional().nullable().default(null),\n\tsecondaryCurrencyMaxDiscountLimit: ZodValidation.number('Secondary currency max discount limit').optional(),\n\tisMaxDiscountLimitEnabled: ZodValidation.boolean('Is max discount limit enabled').optional().default(false),\n\tduration: DurationSchema\n\t\t// .refine((d: any) => d.start >= new Date() && d.end >= new Date(), {\n\t\t// \tmessage: 'Start and end dates must not be in the past',\n\t\t// })\n\t\t.transform(duration => {\n\t\t\tduration.start = dayjs(duration.start).toDate();\n\t\t\tduration.end = dayjs(duration.end).toDate();\n\t\t\treturn duration;\n\t\t}),\n\tspendLimit: ZodValidation.number('Spend limit').optional().nullable().default(null),\n\tisSpendLimitEnabled: ZodValidation.boolean('Is spend limit enabled').optional().default(false),\n\ttotalOrderLimit: ZodValidation.number('Total order limit').optional().nullable().default(null),\n\tisTotalOrderLimitEnabled: ZodValidation.boolean('Is total order limit enabled').optional().default(false),\n\tminOrderValue: ZodValidation.number('Min order value').nullable().default(null),\n\tsecondaryCurrencyMinOrderValue: ZodValidation.number('Secondary currency min order value').optional(),\n\tisMinOrderValueEnabled: ZodValidation.boolean('Is min order value enabled').optional().default(false),\n\tforNewUserOnly: ZodValidation.boolean('ForNewUserOnly').optional().default(false),\n\tstatus: ZodValidation.enumType(Status, 'Status').optional().default(Status.ACTIVE),\n\texpirationReason: ZodValidation.enumType(CouponExpirationReason, 'Expiration reason')\n\t\t.optional()\n\t\t.nullable()\n\t\t.default(null),\n\treferringUser: z\n\t\t.object({\n\t\t\tname: ZodValidation.string('Referring user name').optional(),\n\t\t})\n\t\t.optional(),\n};\n\n/**\n * Create schema builder for Parent entity\n * - Includes timestamps\n * - Excludes 'createdAt' from update operations\n */\nconst schemaBuilder = createSchemaBuilder(baseFields);\n\n/**\n * Get all schemas for the Parent entity\n */\nconst {\n\tBaseSchema: CouponValidationSchema,\n\tEntitySchema: CouponSchema,\n\tIdSchema: CouponIdSchema,\n\tUpdateSchema: UpdateCouponSchema,\n} = schemaBuilder.getAllSchemas({ createdAt: true });\n\n/**\n * Export schemas\n */\nexport const GetUserCouponsResponseSchema = z.object({\n\tavailable: z.array(CouponSchema),\n\tused: z.array(CouponSchema),\n\texpired: z.array(CouponSchema),\n});\n\nexport {\n\tCouponValidationSchema,\n\tCouponSchema,\n\tCouponIdSchema as CouponIdValidationSchema,\n\tUpdateCouponSchema,\n};\n\n/**\n * Schema for getting user coupons\n */\nexport const GetUserCouponSchema = z.object({\n\tuser: ZodValidation.objectId('User').optional(),\n\tshop: ZodValidation.objectId('Shop').optional(),\n\tpage: ZodValidation.number('Page').optional().default(0),\n\tsize: ZodValidation.number('Page size').optional().default(100),\n});\n\n/**\n * Schema for validating coupons\n */\nexport const ValidateCouponSchema = z.object({\n\tuser: ZodValidation.objectIdOrStringSchema,\n\tshop: ZodValidation.objectIdOrStringSchema,\n\tcoupon: ZodValidation.string('Coupon').optional(),\n\tamountBeforeCoupon: ZodValidation.number('Amount before coupon'),\n\tsecondaryAmountBeforeCoupon: ZodValidation.number('Secondary amount before coupon'),\n\tscheduledAt: ZodValidation.date('Scheduled at').optional(),\n});\n\nconst discountCutSchema = z.object({\n\tcompanyCut: ZodValidation.number('companyCut').optional(),\n\tsecondaryCompanyCut: ZodValidation.number('secondaryCompanyCut').optional(),\n\tshopCut: ZodValidation.number('shopCut').optional(),\n\tsecondaryShopCut: ZodValidation.number('secondaryShopCut').optional(),\n});\n\n/**\n * Schema for coupon validation output\n */\nexport const CouponValidationOutputSchema = z.object({\n\tisValid: ZodValidation.boolean('IsValid').default(false),\n\tmessage: ZodValidation.string('Message').optional(),\n\tamountAfterCoupon: ZodValidation.number('Amount after coupon').optional(),\n\tsecondaryAmountAfterCoupon: ZodValidation.number('Secondary amount after coupon').optional(),\n\tdiscountAmount: ZodValidation.number('Coupon Discount').optional(),\n\tsecondaryDiscountAmount: ZodValidation.number('Secondary coupon discount').optional(),\n\tdiscountCut: discountCutSchema.optional(),\n});\n\nexport const CouponCodeSchema = z.object({\n\tcouponCode: ZodValidation.string('Coupon code'),\n});\n\nexport const UpdateCouponStatusSchema = z.object({\n\t_id: ZodValidation.objectIdOrStringSchema,\n\tstatus: ZodValidation.enumType(Status, 'Status').optional().default(Status.ACTIVE),\n});\n\nexport const CheckExistingNewUserCouponOutputSchema = z.object({\n\texists: ZodValidation.boolean('Exists').default(false),\n});\n\nexport const CouponValidationResponseSchema = createResponseSchema(CouponValidationOutputSchema);\n\nexport const DeviceIdSchema = z.object({ deviceId: z.string() });\nexport const IsNewUserGiftBoxShownSchema = z.object({ isNewUserGiftBoxShown: z.boolean() });\n\n/**\n * Export DTO types\n */\nexport type CreateCouponDTO = DTO<typeof CouponValidationSchema>;\nexport type CouponDTO = DTO<typeof CouponSchema>;\nexport type UpdateCouponDTO = DTO<typeof UpdateCouponSchema>;\nexport type GetUserCouponDTO = DTO<typeof GetUserCouponSchema>;\nexport type ValidateCouponDTO = DTO<typeof ValidateCouponSchema>;\nexport type CouponValidationOutputDTO = DTO<typeof CouponValidationOutputSchema>;\nexport type GetUserCouponsResponseDTO = DTO<typeof GetUserCouponsResponseSchema>;\nexport type UpdateCouponStatusDTO = DTO<typeof UpdateCouponStatusSchema>;\nexport type CheckExistingNewUserCouponOutputDTO = DTO<typeof CheckExistingNewUserCouponOutputSchema>;\nexport type DeviceIdDTO = DTO<typeof DeviceIdSchema>;\nexport type IsNewUserGiftBoxShownDTO = DTO<typeof IsNewUserGiftBoxShownSchema>;\n"]}
1
+ {"version":3,"file":"coupon.validation.js","sourceRoot":"/","sources":["modules/coupon/validations/coupon.validation.ts"],"names":[],"mappings":";;;AAAA,6BAAwB;AACxB,iGAImE;AACnE,4DAA0G;AAC1G,iGAGmE;AACnE,8DAA2D;AAK9C,QAAA,YAAY,GAAG;IAC3B,IAAI,EAAE,iCAAa,CAAC,MAAM,CAAC,MAAM,EAAE;QAClC,KAAK,EAAE,EAAE,OAAO,EAAE,IAAI,MAAM,CAAC,aAAa,CAAC,EAAE,OAAO,EAAE,+BAA+B,EAAE;QACvF,SAAS,EAAE,EAAE;QACb,SAAS,EAAE,CAAC;QACZ,UAAU,EAAE,6BAA6B;QACzC,UAAU,EAAE,8BAA8B;KAC1C,CAAC;IACF,iBAAiB,EAAE,iCAAa,CAAC,MAAM,CAAC,mBAAmB,CAAC;SAC1D,WAAW,EAAE;SACb,QAAQ,EAAE;SACV,QAAQ,EAAE;SACV,OAAO,CAAC,IAAI,CAAC;IACf,0BAA0B,EAAE,iCAAa,CAAC,OAAO,CAAC,iCAAiC,CAAC;SAClF,QAAQ,EAAE;SACV,OAAO,CAAC,KAAK,CAAC;IAChB,SAAS,EAAE,iCAAa,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE;IAC1D,SAAS,EAAE,iCAAa,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE;CACzD,CAAC;AAEW,QAAA,UAAU,GAAG;IACzB,GAAG,oBAAY;IACf,SAAS,EAAE,iCAAa,CAAC,QAAQ,CAAC,gBAAS,EAAE,YAAY,CAAC;IAC1D,KAAK,EAAE,iCAAa,CAAC,MAAM,CAAC,OAAO,CAAC;IACpC,sBAAsB,EAAE,iCAAa,CAAC,MAAM,CAAC,0BAA0B,CAAC,CAAC,QAAQ,EAAE;IACnF,gBAAgB,EAAE,iCAAa,CAAC,MAAM,CAAC,oBAAoB,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAChG,iCAAiC,EAAE,iCAAa,CAAC,MAAM,CAAC,uCAAuC,CAAC,CAAC,QAAQ,EAAE;IAC3G,yBAAyB,EAAE,iCAAa,CAAC,OAAO,CAAC,+BAA+B,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAC3G,QAAQ,EAAE,kCAAc;SAItB,SAAS,CAAC,QAAQ,CAAC,EAAE;QACrB,QAAQ,CAAC,KAAK,GAAG,IAAA,aAAK,EAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,MAAM,EAAE,CAAC;QAChD,QAAQ,CAAC,GAAG,GAAG,IAAA,aAAK,EAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;QAC5C,OAAO,QAAQ,CAAC;IACjB,CAAC,CAAC;IACH,UAAU,EAAE,iCAAa,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IACnF,mBAAmB,EAAE,iCAAa,CAAC,OAAO,CAAC,wBAAwB,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IAC9F,eAAe,EAAE,iCAAa,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAC9F,wBAAwB,EAAE,iCAAa,CAAC,OAAO,CAAC,8BAA8B,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACzG,aAAa,EAAE,iCAAa,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC;IAC/E,8BAA8B,EAAE,iCAAa,CAAC,MAAM,CAAC,oCAAoC,CAAC,CAAC,QAAQ,EAAE;IACrG,sBAAsB,EAAE,iCAAa,CAAC,OAAO,CAAC,4BAA4B,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACrG,cAAc,EAAE,iCAAa,CAAC,OAAO,CAAC,gBAAgB,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,KAAK,CAAC;IACjF,MAAM,EAAE,iCAAa,CAAC,QAAQ,CAAC,aAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,aAAM,CAAC,MAAM,CAAC;IAClF,gBAAgB,EAAE,iCAAa,CAAC,QAAQ,CAAC,6BAAsB,EAAE,mBAAmB,CAAC;SACnF,QAAQ,EAAE;SACV,QAAQ,EAAE;SACV,OAAO,CAAC,IAAI,CAAC;IACf,aAAa,EAAE,OAAC;SACd,MAAM,CAAC;QACP,IAAI,EAAE,iCAAa,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,QAAQ,EAAE;KAC5D,CAAC;SACD,QAAQ,EAAE;CACZ,CAAC;AAOF,MAAM,aAAa,GAAG,IAAA,uCAAmB,EAAC,kBAAU,CAAC,CAAC;AAKtD,MAAM,EACL,UAAU,EAAE,sBAAsB,EAClC,YAAY,EAAE,YAAY,EAC1B,QAAQ,EAAE,cAAc,EACxB,YAAY,EAAE,kBAAkB,GAChC,GAAG,aAAa,CAAC,aAAa,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AAYpD,wDAAsB;AACtB,oCAAY;AACM,kDAAwB;AAC1C,gDAAkB;AAVN,QAAA,4BAA4B,GAAG,OAAC,CAAC,MAAM,CAAC;IACpD,SAAS,EAAE,OAAC,CAAC,KAAK,CAAC,YAAY,CAAC;IAChC,IAAI,EAAE,OAAC,CAAC,KAAK,CAAC,YAAY,CAAC;IAC3B,OAAO,EAAE,OAAC,CAAC,KAAK,CAAC,YAAY,CAAC;CAC9B,CAAC,CAAC;AAYU,QAAA,mBAAmB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC3C,IAAI,EAAE,iCAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE;IAC/C,IAAI,EAAE,iCAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE;IAC/C,IAAI,EAAE,iCAAa,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,CAAC,CAAC;IACxD,IAAI,EAAE,iCAAa,CAAC,MAAM,CAAC,WAAW,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC;CAC/D,CAAC,CAAC;AAKU,QAAA,oBAAoB,GAAG,OAAC,CAAC,MAAM,CAAC;IAC5C,IAAI,EAAE,iCAAa,CAAC,sBAAsB;IAC1C,IAAI,EAAE,iCAAa,CAAC,sBAAsB;IAC1C,MAAM,EAAE,iCAAa,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,QAAQ,EAAE;IACjD,kBAAkB,EAAE,iCAAa,CAAC,MAAM,CAAC,sBAAsB,CAAC;IAChE,2BAA2B,EAAE,iCAAa,CAAC,MAAM,CAAC,gCAAgC,CAAC;IACnF,WAAW,EAAE,iCAAa,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,QAAQ,EAAE;CAC1D,CAAC,CAAC;AAEH,MAAM,iBAAiB,GAAG,OAAC,CAAC,MAAM,CAAC;IAClC,UAAU,EAAE,iCAAa,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC,QAAQ,EAAE;IACzD,mBAAmB,EAAE,iCAAa,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,QAAQ,EAAE;IAC3E,OAAO,EAAE,iCAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE;IACnD,gBAAgB,EAAE,iCAAa,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC,QAAQ,EAAE;CACrE,CAAC,CAAC;AAKU,QAAA,4BAA4B,GAAG,OAAC,CAAC,MAAM,CAAC;IACpD,OAAO,EAAE,iCAAa,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IACxD,OAAO,EAAE,iCAAa,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC,QAAQ,EAAE;IACnD,iBAAiB,EAAE,iCAAa,CAAC,MAAM,CAAC,qBAAqB,CAAC,CAAC,QAAQ,EAAE;IACzE,0BAA0B,EAAE,iCAAa,CAAC,MAAM,CAAC,+BAA+B,CAAC,CAAC,QAAQ,EAAE;IAC5F,cAAc,EAAE,iCAAa,CAAC,MAAM,CAAC,iBAAiB,CAAC,CAAC,QAAQ,EAAE;IAClE,uBAAuB,EAAE,iCAAa,CAAC,MAAM,CAAC,2BAA2B,CAAC,CAAC,QAAQ,EAAE;IACrF,WAAW,EAAE,iBAAiB,CAAC,QAAQ,EAAE;IACzC,aAAa,EAAE,OAAC,CAAC,MAAM,CAAC,OAAC,CAAC,OAAO,EAAE,CAAC,CAAC,QAAQ,EAAE;CAC/C,CAAC,CAAC;AAEU,QAAA,gBAAgB,GAAG,OAAC,CAAC,MAAM,CAAC;IACxC,UAAU,EAAE,iCAAa,CAAC,MAAM,CAAC,aAAa,CAAC;CAC/C,CAAC,CAAC;AAEU,QAAA,wBAAwB,GAAG,OAAC,CAAC,MAAM,CAAC;IAChD,GAAG,EAAE,iCAAa,CAAC,sBAAsB;IACzC,MAAM,EAAE,iCAAa,CAAC,QAAQ,CAAC,aAAM,EAAE,QAAQ,CAAC,CAAC,QAAQ,EAAE,CAAC,OAAO,CAAC,aAAM,CAAC,MAAM,CAAC;CAClF,CAAC,CAAC;AAEU,QAAA,sCAAsC,GAAG,OAAC,CAAC,MAAM,CAAC;IAC9D,MAAM,EAAE,iCAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;CACtD,CAAC,CAAC;AAEU,QAAA,8BAA8B,GAAG,IAAA,wCAAoB,EAAC,oCAA4B,CAAC,CAAC;AAEpF,QAAA,cAAc,GAAG,OAAC,CAAC,MAAM,CAAC,EAAE,QAAQ,EAAE,OAAC,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACpD,QAAA,2BAA2B,GAAG,OAAC,CAAC,MAAM,CAAC,EAAE,qBAAqB,EAAE,OAAC,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC","sourcesContent":["import { z } from 'zod';\nimport {\n\tZodValidation,\n\tcreateSchemaBuilder,\n\tDTO,\n} from '@lyxa.ai/core/dist/utilities/validation/global-validation';\nimport { CouponExpirationReason, CouponType, Status, ValueType } from '@lyxa.ai/core/dist/utilities/enum';\nimport {\n\tcreateResponseSchema,\n\tDurationSchema,\n} from '@lyxa.ai/core/dist/utilities/validation/common-validation';\nimport { dayjs } from '@lyxa.ai/core/dist/utilities/dayjs';\n\n/**\n * Define the base parent schema fields\n */\nexport const couponFields = {\n\tcode: ZodValidation.string('Code', {\n\t\tregex: { pattern: new RegExp('^[A-Z0-9]+$'), message: 'Coupon name must be uppercase' },\n\t\tmaxLength: 10,\n\t\tminLength: 4,\n\t\tminMessage: 'Coupon must be 4 characters',\n\t\tmaxMessage: 'Coupon must be 10 characters',\n\t}),\n\torderLimitPerUser: ZodValidation.number('OrderLimitPerUser')\n\t\t.nonnegative()\n\t\t.optional()\n\t\t.nullable()\n\t\t.default(null),\n\tisOrderLimitPerUserEnabled: ZodValidation.boolean('Is order limit per user enabled')\n\t\t.optional()\n\t\t.default(false),\n\tcreatedBy: ZodValidation.objectId('Created by').optional(),\n\tisExpired: ZodValidation.boolean('Is expired').optional(),\n};\n\nexport const baseFields = {\n\t...couponFields,\n\tvalueType: ZodValidation.enumType(ValueType, 'Value type'),\n\tvalue: ZodValidation.number('Value'),\n\tsecondaryCurrencyValue: ZodValidation.number('Secondary currency value').optional(),\n\tmaxDiscountLimit: ZodValidation.number('Max discount limit').optional().nullable().default(null),\n\tsecondaryCurrencyMaxDiscountLimit: ZodValidation.number('Secondary currency max discount limit').optional(),\n\tisMaxDiscountLimitEnabled: ZodValidation.boolean('Is max discount limit enabled').optional().default(false),\n\tduration: DurationSchema\n\t\t// .refine((d: any) => d.start >= new Date() && d.end >= new Date(), {\n\t\t// \tmessage: 'Start and end dates must not be in the past',\n\t\t// })\n\t\t.transform(duration => {\n\t\t\tduration.start = dayjs(duration.start).toDate();\n\t\t\tduration.end = dayjs(duration.end).toDate();\n\t\t\treturn duration;\n\t\t}),\n\tspendLimit: ZodValidation.number('Spend limit').optional().nullable().default(null),\n\tisSpendLimitEnabled: ZodValidation.boolean('Is spend limit enabled').optional().default(false),\n\ttotalOrderLimit: ZodValidation.number('Total order limit').optional().nullable().default(null),\n\tisTotalOrderLimitEnabled: ZodValidation.boolean('Is total order limit enabled').optional().default(false),\n\tminOrderValue: ZodValidation.number('Min order value').nullable().default(null),\n\tsecondaryCurrencyMinOrderValue: ZodValidation.number('Secondary currency min order value').optional(),\n\tisMinOrderValueEnabled: ZodValidation.boolean('Is min order value enabled').optional().default(false),\n\tforNewUserOnly: ZodValidation.boolean('ForNewUserOnly').optional().default(false),\n\tstatus: ZodValidation.enumType(Status, 'Status').optional().default(Status.ACTIVE),\n\texpirationReason: ZodValidation.enumType(CouponExpirationReason, 'Expiration reason')\n\t\t.optional()\n\t\t.nullable()\n\t\t.default(null),\n\treferringUser: z\n\t\t.object({\n\t\t\tname: ZodValidation.string('Referring user name').optional(),\n\t\t})\n\t\t.optional(),\n};\n\n/**\n * Create schema builder for Parent entity\n * - Includes timestamps\n * - Excludes 'createdAt' from update operations\n */\nconst schemaBuilder = createSchemaBuilder(baseFields);\n\n/**\n * Get all schemas for the Parent entity\n */\nconst {\n\tBaseSchema: CouponValidationSchema,\n\tEntitySchema: CouponSchema,\n\tIdSchema: CouponIdSchema,\n\tUpdateSchema: UpdateCouponSchema,\n} = schemaBuilder.getAllSchemas({ createdAt: true });\n\n/**\n * Export schemas\n */\nexport const GetUserCouponsResponseSchema = z.object({\n\tavailable: z.array(CouponSchema),\n\tused: z.array(CouponSchema),\n\texpired: z.array(CouponSchema),\n});\n\nexport {\n\tCouponValidationSchema,\n\tCouponSchema,\n\tCouponIdSchema as CouponIdValidationSchema,\n\tUpdateCouponSchema,\n};\n\n/**\n * Schema for getting user coupons\n */\nexport const GetUserCouponSchema = z.object({\n\tuser: ZodValidation.objectId('User').optional(),\n\tshop: ZodValidation.objectId('Shop').optional(),\n\tpage: ZodValidation.number('Page').optional().default(0),\n\tsize: ZodValidation.number('Page size').optional().default(100),\n});\n\n/**\n * Schema for validating coupons\n */\nexport const ValidateCouponSchema = z.object({\n\tuser: ZodValidation.objectIdOrStringSchema,\n\tshop: ZodValidation.objectIdOrStringSchema,\n\tcoupon: ZodValidation.string('Coupon').optional(),\n\tamountBeforeCoupon: ZodValidation.number('Amount before coupon'),\n\tsecondaryAmountBeforeCoupon: ZodValidation.number('Secondary amount before coupon'),\n\tscheduledAt: ZodValidation.date('Scheduled at').optional(),\n});\n\nconst discountCutSchema = z.object({\n\tcompanyCut: ZodValidation.number('companyCut').optional(),\n\tsecondaryCompanyCut: ZodValidation.number('secondaryCompanyCut').optional(),\n\tshopCut: ZodValidation.number('shopCut').optional(),\n\tsecondaryShopCut: ZodValidation.number('secondaryShopCut').optional(),\n});\n\n/**\n * Schema for coupon validation output\n */\nexport const CouponValidationOutputSchema = z.object({\n\tisValid: ZodValidation.boolean('IsValid').default(false),\n\tmessage: ZodValidation.string('Message').optional(),\n\tamountAfterCoupon: ZodValidation.number('Amount after coupon').optional(),\n\tsecondaryAmountAfterCoupon: ZodValidation.number('Secondary amount after coupon').optional(),\n\tdiscountAmount: ZodValidation.number('Coupon Discount').optional(),\n\tsecondaryDiscountAmount: ZodValidation.number('Secondary coupon discount').optional(),\n\tdiscountCut: discountCutSchema.optional(),\n\tcouponDetails: z.record(z.unknown()).optional(), // Flexible field for any additional coupon details\n});\n\nexport const CouponCodeSchema = z.object({\n\tcouponCode: ZodValidation.string('Coupon code'),\n});\n\nexport const UpdateCouponStatusSchema = z.object({\n\t_id: ZodValidation.objectIdOrStringSchema,\n\tstatus: ZodValidation.enumType(Status, 'Status').optional().default(Status.ACTIVE),\n});\n\nexport const CheckExistingNewUserCouponOutputSchema = z.object({\n\texists: ZodValidation.boolean('Exists').default(false),\n});\n\nexport const CouponValidationResponseSchema = createResponseSchema(CouponValidationOutputSchema);\n\nexport const DeviceIdSchema = z.object({ deviceId: z.string() });\nexport const IsNewUserGiftBoxShownSchema = z.object({ isNewUserGiftBoxShown: z.boolean() });\n\n/**\n * Export DTO types\n */\nexport type CreateCouponDTO = DTO<typeof CouponValidationSchema>;\nexport type CouponDTO = DTO<typeof CouponSchema>;\nexport type UpdateCouponDTO = DTO<typeof UpdateCouponSchema>;\nexport type GetUserCouponDTO = DTO<typeof GetUserCouponSchema>;\nexport type ValidateCouponDTO = DTO<typeof ValidateCouponSchema>;\nexport type CouponValidationOutputDTO = DTO<typeof CouponValidationOutputSchema>;\nexport type GetUserCouponsResponseDTO = DTO<typeof GetUserCouponsResponseSchema>;\nexport type UpdateCouponStatusDTO = DTO<typeof UpdateCouponStatusSchema>;\nexport type CheckExistingNewUserCouponOutputDTO = DTO<typeof CheckExistingNewUserCouponOutputSchema>;\nexport type DeviceIdDTO = DTO<typeof DeviceIdSchema>;\nexport type IsNewUserGiftBoxShownDTO = DTO<typeof IsNewUserGiftBoxShownSchema>;\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"deal-setting.service.d.ts","sourceRoot":"/","sources":["modules/deal-setting/services/deal-setting.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAmB,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAElG,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAC3D,OAAO,EAAoB,WAAW,IAAI,KAAK,EAAE,MAAM,2CAA2C,CAAC;AACnG,OAAO,EACN,oBAAoB,IAAI,SAAS,EACjC,oBAAoB,IAAI,SAAS,EACjC,mBAAmB,IAAI,YAAY,EACnC,MAAM,mCAAmC,CAAC;AAQ3C,qBACa,kBAAkB;IAC9B,OAAO,CAAC,KAAK,CAAmD;IAChE,OAAO,CAAC,kBAAkB,CAQxB;;IAUW,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IA4BrE,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;YA+B1F,yBAAyB;IAyB1B,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IA4BjF,SAAS,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YAkB9E,8BAA8B;IAmB/B,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAoCzE;AAED,eAAO,MAAM,kBAAkB,oBAAoC,CAAC"}
1
+ {"version":3,"file":"deal-setting.service.d.ts","sourceRoot":"/","sources":["modules/deal-setting/services/deal-setting.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAmB,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAAE,SAAS,EAAE,iBAAiB,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AAElG,OAAO,EAAE,SAAS,EAAE,MAAM,gCAAgC,CAAC;AAC3D,OAAO,EAAoB,WAAW,IAAI,KAAK,EAAE,MAAM,2CAA2C,CAAC;AACnG,OAAO,EACN,oBAAoB,IAAI,SAAS,EACjC,oBAAoB,IAAI,SAAS,EACjC,mBAAmB,IAAI,YAAY,EACnC,MAAM,mCAAmC,CAAC;AAQ3C,qBACa,kBAAkB;IAC9B,OAAO,CAAC,KAAK,CAAmD;IAChE,OAAO,CAAC,kBAAkB,CAWxB;;IAUW,MAAM,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IA4BrE,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;YA2B1F,yBAAyB;IAyB1B,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC;IA4BjF,SAAS,CAAC,IAAI,EAAE,YAAY,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,KAAK,CAAC,EAAE,CAAC;YAkB9E,8BAA8B;IAmB/B,UAAU,CAAC,IAAI,EAAE,SAAS,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAoCzE;AAED,eAAO,MAAM,kBAAkB,oBAAoC,CAAC"}
@@ -59,6 +59,9 @@ let DealSettingService = class DealSettingService {
59
59
  enum_1.ItemType.GROCERY,
60
60
  enum_1.ItemType.FLOWER,
61
61
  enum_1.ItemType.PET,
62
+ enum_1.ItemType.CLEANING,
63
+ enum_1.ItemType.LAUNDRY,
64
+ enum_1.ItemType.SALOON
62
65
  ];
63
66
  constructor() {
64
67
  this.model = models_1.DealSettingModel;
@@ -113,10 +116,7 @@ let DealSettingService = class DealSettingService {
113
116
  return paginatedResult;
114
117
  }
115
118
  catch (err) {
116
- throw new server_1.TRPCError({
117
- code: 'INTERNAL_SERVER_ERROR',
118
- message: `err: ${err}`,
119
- });
119
+ (0, error_common_1.internalServerError)(`err: ${err}`);
120
120
  }
121
121
  }
122
122
  async createDefaultDealSettings(documents) {
@@ -1 +1 @@
1
- {"version":3,"file":"deal-setting.service.js","sourceRoot":"/","sources":["modules/deal-setting/services/deal-setting.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, { Service } from 'typedi';\nimport { TRPCError } from '@trpc/server';\nimport { DocumentType, mongoose, ReturnModelType } from '@typegoose/typegoose';\nimport { FilterDTO, PaginatedResponse, DeleteDTO } from '@lyxa.ai/core/dist/utilities/validation';\nimport { createRawDocumentPaginatorObject, PaginatorOptions } from '@lyxa.ai/core/dist/utilities/pagination';\nimport { ModelType } from '@typegoose/typegoose/lib/types';\nimport { DealSettingModel, DealSetting as Model } from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport {\n\tCreateDealSettingDTO as CreateDTO,\n\tUpdateDealSettingDTO as UpdateDTO,\n\tDealSettingArrayDTO as UpdateAllDTO,\n} from '@modules/deal-setting/validations';\nimport { SoftDeleteModel } from '@lyxa.ai/core/dist/libraries/mongo/plugins/soft-delete-plugin';\nimport { publishEvent } from '@lyxa.ai/core/dist/libraries/event';\nimport { BaseEvent } from '@lyxa.ai/core/dist/libraries/event/BaseEvent';\nimport { AdminActivityLogsEvent } from '@lyxa.ai/core/dist/libraries/event/events/admin-logs-event';\nimport { AdminLogsUpdatedFieldsType, ItemType } from '@lyxa.ai/core/dist/utilities/enum';\nimport { badRequestError, notFoundError } from '@lyxa.ai/core/dist/utilities/error-common';\n\n@Service()\nexport class DealSettingService {\n\tprivate model: typeof DealSettingModel & SoftDeleteModel<Model>;\n\tprivate ALLOWED_ITEM_TYPES = [\n\t\tItemType.FOOD,\n\t\tItemType.GROCERY,\n\t\t// ItemType.COFFEE, // removed because https://trello.com/c/x19zLU0A/2935-marketing-remove-coffee\n\t\tItemType.FLOWER,\n\t\tItemType.PET,\n\t\t// ItemType.PHARMACY,\n\t\t// ItemType.HEALTHY_CORNER,\n\t];\n\n\tconstructor() {\n\t\tthis.model = DealSettingModel as typeof DealSettingModel & SoftDeleteModel<Model>;\n\t}\n\n\t/**\n\t * Create a new record\n\t * @param data Data for the new record\n\t */\n\tpublic async create(data: CreateDTO, admin?: string): Promise<DocumentType<Model>> {\n\t\tconst exists = await this.model.exists({\n\t\t\titemType: data.itemType,\n\t\t});\n\t\tif (exists) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'CONFLICT',\n\t\t\t\tmessage: `Deal settings for itemType ${data.itemType} already exists. Please update the existing settings.`,\n\t\t\t});\n\t\t}\n\t\tconst result = await this.model.create(data);\n\n\t\tif (admin) {\n\t\t\tthis.logMarketingSettingAdminAction(\n\t\t\t\tnew mongoose.Types.ObjectId(admin),\n\t\t\t\tAdminLogsUpdatedFieldsType.CREATED_MARKETING_SETTINGS,\n\t\t\t\t'',\n\t\t\t\tresult\n\t\t\t);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Get record by ID\n\t * @param id ID of the record\n\t */\n\tpublic async findById(id: string | mongoose.Types.ObjectId): Promise<DocumentType<Model>> {\n\t\tconst result = await this.model.findOne({\n\t\t\t_id: id,\n\t\t\tdeletedAt: null,\n\t\t});\n\t\tif (!result) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'NOT_FOUND',\n\t\t\t\tmessage: 'Record not found',\n\t\t\t});\n\t\t}\n\t\treturn result;\n\t}\n\n\t/**\n\t * Get records\n\t * @param query Query to find records\n\t */\n\tpublic async find(data?: Partial<FilterDTO>): Promise<PaginatedResponse<DocumentType<ModelType<Model>>>> {\n\t\ttry {\n\n\t\t\tconst query = data?.query ?? {}\n\t\t\tquery.itemType = { $in: this.ALLOWED_ITEM_TYPES }\n\n\t\t\tconst paginate = createRawDocumentPaginatorObject(this.model as ReturnModelType<typeof this.model>);\n\t\t\tconst options: PaginatorOptions<typeof Model> = {\n\t\t\t\tpage: data?.page,\n\t\t\t\tsize: data?.size,\n\t\t\t\tsort: data?.sort,\n\t\t\t\tquery,\n\t\t\t\tselect: data?.select,\n\t\t\t\tpopulate: data?.populate,\n\t\t\t};\n\t\t\tlet paginatedResult = await paginate(options);\n\n\t\t\tif (!data?.query && paginatedResult.metadata.totalElements < this.ALLOWED_ITEM_TYPES.length) {\n\t\t\t\tawait this.createDefaultDealSettings(paginatedResult.documents as unknown as DocumentType<Model>[]);\n\t\t\t\tpaginatedResult = await paginate(options);\n\t\t\t}\n\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\tprivate async createDefaultDealSettings(documents: DocumentType<Model>[]): Promise<void> {\n\t\tconst existingItemTypes = documents.map(deal => deal.itemType);\n\t\tconst newItemTypes = this.ALLOWED_ITEM_TYPES.filter(item => !existingItemTypes.includes(item));\n\t\tconst defaultSetting = {\n\t\t\tpercentageBundles: [],\n\t\t\tisDiscount: false,\n\t\t\tisBuy1Get1: false,\n\t\t\tisFreeDelivery: false,\n\t\t\tisPunchMarketing: false,\n\t\t};\n\n\t\tfor (const item of newItemTypes) {\n\t\t\tawait this.create({\n\t\t\t\t...defaultSetting,\n\t\t\t\titemType: item as ItemType,\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 * @param admin Admin id\n\t */\n\tpublic async update(id: string, data: UpdateDTO, admin?: string): Promise<DocumentType<Model>> {\n\t\tif (!admin) notFoundError('Admin not found');\n\n\t\tconst record = await this.model.findById(id);\n\t\tif (!record) notFoundError('Record not found');\n\n\t\tconst result = await this.model.findByIdAndUpdate(id, data, {\n\t\t\tnew: true,\n\t\t\trunValidators: true,\n\t\t});\n\n\t\tif (!result) notFoundError('Record not found');\n\n\t\tthis.logMarketingSettingAdminAction(\n\t\t\tnew mongoose.Types.ObjectId(admin),\n\t\t\tAdminLogsUpdatedFieldsType.CHANGE_IN_MARKETING_SETTINGS,\n\t\t\trecord,\n\t\t\tresult\n\t\t);\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Update all records\n\t * @param data Data to update\n\t * @param admin Admin id\n\t */\n\tpublic async updateAll(data: UpdateAllDTO[], admin?: string): Promise<DocumentType<Model>[]> {\n\t\t// Check admin existence\n\t\tif (!admin) notFoundError('Admin not found');\n\n\t\tconst results: DocumentType<Model>[] = [];\n\n\t\tfor (const dealSetting of data) {\n\t\t\tconst { _id, ...rest } = dealSetting as UpdateAllDTO & { _id: string | mongoose.Types.ObjectId };\n\n\t\t\tif (!_id) continue;\n\n\t\t\tconst updated = await this.update(String(_id), rest as UpdateAllDTO, admin);\n\t\t\tresults.push(updated);\n\t\t}\n\n\t\treturn results;\n\t}\n\n\tprivate async logMarketingSettingAdminAction(\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?: string): Promise<string> {\n\t\tconst { _id, softDelete } = data;\n\n\t\tif (!admin) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'NOT_FOUND',\n\t\t\t\tmessage: 'Admin not found',\n\t\t\t});\n\t\t}\n\n\t\tconst record = await this.model.findById(_id);\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\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 record',\n\t\t\t});\n\t\t}\n\n\t\tthis.logMarketingSettingAdminAction(\n\t\t\tnew mongoose.Types.ObjectId(admin),\n\t\t\tAdminLogsUpdatedFieldsType.DELETED_MARKETING_SETTINGS,\n\t\t\trecord,\n\t\t\tresult\n\t\t);\n\n\t\treturn 'Record deleted successfully';\n\t}\n}\n\nexport const dealSettingService = Container.get(DealSettingService);\n"]}
1
+ {"version":3,"file":"deal-setting.service.js","sourceRoot":"/","sources":["modules/deal-setting/services/deal-setting.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, { Service } from 'typedi';\nimport { TRPCError } from '@trpc/server';\nimport { DocumentType, mongoose, ReturnModelType } from '@typegoose/typegoose';\nimport { FilterDTO, PaginatedResponse, DeleteDTO } from '@lyxa.ai/core/dist/utilities/validation';\nimport { createRawDocumentPaginatorObject, PaginatorOptions } from '@lyxa.ai/core/dist/utilities/pagination';\nimport { ModelType } from '@typegoose/typegoose/lib/types';\nimport { DealSettingModel, DealSetting as Model } from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport {\n\tCreateDealSettingDTO as CreateDTO,\n\tUpdateDealSettingDTO as UpdateDTO,\n\tDealSettingArrayDTO as UpdateAllDTO,\n} from '@modules/deal-setting/validations';\nimport { SoftDeleteModel } from '@lyxa.ai/core/dist/libraries/mongo/plugins/soft-delete-plugin';\nimport { publishEvent } from '@lyxa.ai/core/dist/libraries/event';\nimport { BaseEvent } from '@lyxa.ai/core/dist/libraries/event/BaseEvent';\nimport { AdminActivityLogsEvent } from '@lyxa.ai/core/dist/libraries/event/events/admin-logs-event';\nimport { AdminLogsUpdatedFieldsType, ItemType } from '@lyxa.ai/core/dist/utilities/enum';\nimport { badRequestError, internalServerError, notFoundError } from '@lyxa.ai/core/dist/utilities/error-common';\n\n@Service()\nexport class DealSettingService {\n\tprivate model: typeof DealSettingModel & SoftDeleteModel<Model>;\n\tprivate ALLOWED_ITEM_TYPES = [\n\t\tItemType.FOOD,\n\t\tItemType.GROCERY,\n\t\t// ItemType.COFFEE, // removed because https://trello.com/c/x19zLU0A/2935-marketing-remove-coffee\n\t\tItemType.FLOWER,\n\t\tItemType.PET,\n\t\t// ItemType.PHARMACY,\n\t\t// ItemType.HEALTHY_CORNER,\n\t\tItemType.CLEANING,\n\t\tItemType.LAUNDRY,\n\t\tItemType.SALOON\n\t];\n\n\tconstructor() {\n\t\tthis.model = DealSettingModel as typeof DealSettingModel & SoftDeleteModel<Model>;\n\t}\n\n\t/**\n\t * Create a new record\n\t * @param data Data for the new record\n\t */\n\tpublic async create(data: CreateDTO, admin?: string): Promise<DocumentType<Model>> {\n\t\tconst exists = await this.model.exists({\n\t\t\titemType: data.itemType,\n\t\t});\n\t\tif (exists) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'CONFLICT',\n\t\t\t\tmessage: `Deal settings for itemType ${data.itemType} already exists. Please update the existing settings.`,\n\t\t\t});\n\t\t}\n\t\tconst result = await this.model.create(data);\n\n\t\tif (admin) {\n\t\t\tthis.logMarketingSettingAdminAction(\n\t\t\t\tnew mongoose.Types.ObjectId(admin),\n\t\t\t\tAdminLogsUpdatedFieldsType.CREATED_MARKETING_SETTINGS,\n\t\t\t\t'',\n\t\t\t\tresult\n\t\t\t);\n\t\t}\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Get record by ID\n\t * @param id ID of the record\n\t */\n\tpublic async findById(id: string | mongoose.Types.ObjectId): Promise<DocumentType<Model>> {\n\t\tconst result = await this.model.findOne({\n\t\t\t_id: id,\n\t\t\tdeletedAt: null,\n\t\t});\n\t\tif (!result) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'NOT_FOUND',\n\t\t\t\tmessage: 'Record not found',\n\t\t\t});\n\t\t}\n\t\treturn result;\n\t}\n\n\t/**\n\t * Get records\n\t * @param query Query to find records\n\t */\n\tpublic async find(data?: Partial<FilterDTO>): Promise<PaginatedResponse<DocumentType<ModelType<Model>>>> {\n\t\ttry {\n\t\t\tconst query = data?.query ?? {}\n\t\t\tquery.itemType = { $in: this.ALLOWED_ITEM_TYPES }\n\n\t\t\tconst paginate = createRawDocumentPaginatorObject(this.model as ReturnModelType<typeof this.model>);\n\t\t\tconst options: PaginatorOptions<typeof Model> = {\n\t\t\t\tpage: data?.page,\n\t\t\t\tsize: data?.size,\n\t\t\t\tsort: data?.sort,\n\t\t\t\tquery,\n\t\t\t\tselect: data?.select,\n\t\t\t\tpopulate: data?.populate,\n\t\t\t};\n\t\t\tlet paginatedResult = await paginate(options);\n\n\t\t\tif (!data?.query && paginatedResult.metadata.totalElements < this.ALLOWED_ITEM_TYPES.length) {\n\t\t\t\tawait this.createDefaultDealSettings(paginatedResult.documents as unknown as DocumentType<Model>[]);\n\t\t\t\tpaginatedResult = await paginate(options);\n\t\t\t}\n\n\t\t\treturn paginatedResult;\n\t\t} catch (err) {\n\t\t\tinternalServerError(`err: ${err}`);\n\t\t}\n\t}\n\n\tprivate async createDefaultDealSettings(documents: DocumentType<Model>[]): Promise<void> {\n\t\tconst existingItemTypes = documents.map(deal => deal.itemType);\n\t\tconst newItemTypes = this.ALLOWED_ITEM_TYPES.filter(item => !existingItemTypes.includes(item));\n\t\tconst defaultSetting = {\n\t\t\tpercentageBundles: [],\n\t\t\tisDiscount: false,\n\t\t\tisBuy1Get1: false,\n\t\t\tisFreeDelivery: false,\n\t\t\tisPunchMarketing: false,\n\t\t};\n\n\t\tfor (const item of newItemTypes) {\n\t\t\tawait this.create({\n\t\t\t\t...defaultSetting,\n\t\t\t\titemType: item as ItemType,\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 * @param admin Admin id\n\t */\n\tpublic async update(id: string, data: UpdateDTO, admin?: string): Promise<DocumentType<Model>> {\n\t\tif (!admin) notFoundError('Admin not found');\n\n\t\tconst record = await this.model.findById(id);\n\t\tif (!record) notFoundError('Record not found');\n\n\t\tconst result = await this.model.findByIdAndUpdate(id, data, {\n\t\t\tnew: true,\n\t\t\trunValidators: true,\n\t\t});\n\n\t\tif (!result) notFoundError('Record not found');\n\n\t\tthis.logMarketingSettingAdminAction(\n\t\t\tnew mongoose.Types.ObjectId(admin),\n\t\t\tAdminLogsUpdatedFieldsType.CHANGE_IN_MARKETING_SETTINGS,\n\t\t\trecord,\n\t\t\tresult\n\t\t);\n\n\t\treturn result;\n\t}\n\n\t/**\n\t * Update all records\n\t * @param data Data to update\n\t * @param admin Admin id\n\t */\n\tpublic async updateAll(data: UpdateAllDTO[], admin?: string): Promise<DocumentType<Model>[]> {\n\t\t// Check admin existence\n\t\tif (!admin) notFoundError('Admin not found');\n\n\t\tconst results: DocumentType<Model>[] = [];\n\n\t\tfor (const dealSetting of data) {\n\t\t\tconst { _id, ...rest } = dealSetting as UpdateAllDTO & { _id: string | mongoose.Types.ObjectId };\n\n\t\t\tif (!_id) continue;\n\n\t\t\tconst updated = await this.update(String(_id), rest as UpdateAllDTO, admin);\n\t\t\tresults.push(updated);\n\t\t}\n\n\t\treturn results;\n\t}\n\n\tprivate async logMarketingSettingAdminAction(\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?: string): Promise<string> {\n\t\tconst { _id, softDelete } = data;\n\n\t\tif (!admin) {\n\t\t\tthrow new TRPCError({\n\t\t\t\tcode: 'NOT_FOUND',\n\t\t\t\tmessage: 'Admin not found',\n\t\t\t});\n\t\t}\n\n\t\tconst record = await this.model.findById(_id);\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\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 record',\n\t\t\t});\n\t\t}\n\n\t\tthis.logMarketingSettingAdminAction(\n\t\t\tnew mongoose.Types.ObjectId(admin),\n\t\t\tAdminLogsUpdatedFieldsType.DELETED_MARKETING_SETTINGS,\n\t\t\trecord,\n\t\t\tresult\n\t\t);\n\n\t\treturn 'Record deleted successfully';\n\t}\n}\n\nexport const dealSettingService = Container.get(DealSettingService);\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"MarketingMetricsRepository.d.ts","sourceRoot":"/","sources":["modules/marketing/patterns/repository/MarketingMetricsRepository.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAmB,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAEN,QAAQ,EAGR,YAAY,EAEZ,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAEN,sBAAsB,EACtB,mBAAmB,EACnB,6BAA6B,EAC7B,MAAM,gCAAgC,CAAC;AAIxC,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAElE,OAAO,EAAE,QAAQ,EAAE,MAAM,iEAAiE,CAAC;AAI3F,qBACa,0BAA0B;IACtC,OAAO,CAAC,KAAK,CAAiD;IAC9D,OAAO,CAAC,UAAU,CAA2D;;IAOtE,+BAA+B,CACrC,KAAK,EAAE,YAAY,CAAC,YAAY,CAAC,GAAG;QAAE,SAAS,EAAE,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAA;KAAE,GACzE,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC;IAiD1B,uBAAuB,CACnC,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EACpC,QAAQ,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,aAAa,CAAA;KAAE,CAAC;YA4B9C,uBAAuB;YAqCvB,0BAA0B;YAyB1B,4BAA4B;IAsB1C,OAAO,CAAC,cAAc;YAkBR,uBAAuB;IAKxB,UAAU,CAAC,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,mBAAmB,CAAC;YAmC7E,qBAAqB;YAKrB,kCAAkC;YA2BlC,qCAAqC;IAcnD,OAAO,CAAC,iBAAiB;YAWX,sBAAsB;IA8BvB,cAAc,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,6BAA6B,CAAC;IAwDpF,iBAAiB,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAsF3F,mBAAmB,CAC/B,IAAI,EAAE,sBAAsB,GAC1B,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAgL9C;AAED,eAAO,MAAM,0BAA0B,4BAA4C,CAAC"}
1
+ {"version":3,"file":"MarketingMetricsRepository.d.ts","sourceRoot":"/","sources":["modules/marketing/patterns/repository/MarketingMetricsRepository.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,QAAQ,EAAmB,MAAM,sBAAsB,CAAC;AAC/E,OAAO,EAEN,QAAQ,EAGR,YAAY,EAEZ,MAAM,2CAA2C,CAAC;AACnD,OAAO,EAEN,sBAAsB,EACtB,mBAAmB,EACnB,6BAA6B,EAC7B,MAAM,gCAAgC,CAAC;AAIxC,OAAO,EAAE,aAAa,EAAE,MAAM,mCAAmC,CAAC;AAElE,OAAO,EAAE,QAAQ,EAAE,MAAM,iEAAiE,CAAC;AAI3F,qBACa,0BAA0B;IACtC,OAAO,CAAC,KAAK,CAAiD;IAC9D,OAAO,CAAC,UAAU,CAA2D;;IAOtE,+BAA+B,CACrC,KAAK,EAAE,YAAY,CAAC,YAAY,CAAC,GAAG;QAAE,SAAS,EAAE,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAA;KAAE,GACzE,GAAG,CAAC,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE,MAAM,CAAC;IAiD1B,uBAAuB,CACnC,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EACpC,QAAQ,CAAC,EAAE,QAAQ,GACjB,OAAO,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,aAAa,CAAA;KAAE,CAAC;YA4B9C,uBAAuB;YAqCvB,0BAA0B;YAyB1B,4BAA4B;IAsB1C,OAAO,CAAC,cAAc;YAkBR,uBAAuB;IAKxB,UAAU,CAAC,WAAW,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC,mBAAmB,CAAC;YAqC7E,qBAAqB;YAKrB,kCAAkC;YA2BlC,qCAAqC;IAcnD,OAAO,CAAC,iBAAiB;YAWX,sBAAsB;IA8BvB,cAAc,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,6BAA6B,CAAC;IAwDpF,iBAAiB,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAsF3F,mBAAmB,CAC/B,IAAI,EAAE,sBAAsB,GAC1B,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CAgL9C;AAED,eAAO,MAAM,0BAA0B,4BAA4C,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"MarketingMetricsRepository.js","sourceRoot":"/","sources":["modules/marketing/patterns/repository/MarketingMetricsRepository.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, { Service } from 'typedi';\nimport { dayjs } from '@lyxa.ai/core/dist/utilities/dayjs';\nimport { DocumentType, mongoose, ReturnModelType } from '@typegoose/typegoose';\nimport {\n\tFeaturedMarketing,\n\tLineItem,\n\tMarketingModel,\n\tMarketing as Model,\n\tRegularOrder,\n\tRegularOrderModel,\n} from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport {\n\tIncreaseDuringDiscountDTO,\n\tMarketingGraphInputDTO,\n\tMarketingMetricsDTO,\n\tMarketingOrdersGraphOutputDTO,\n} from '@modules/marketing/validations';\nimport { SoftDeleteModel } from '@lyxa.ai/core/dist/libraries/mongo/plugins/soft-delete-plugin';\nimport { GraphType, OrderType, RegularOrderStatus } from '@lyxa.ai/core/dist/utilities/enum';\nimport { productMarketingService } from '@modules/marketing/services/product-marketing.service';\nimport { MarketingType } from '@lyxa.ai/core/dist/utilities/enum';\nimport { notFoundError } from '@lyxa.ai/core/dist/utilities/error-common';\nimport { Duration } from '@lyxa.ai/core/dist/libraries/mongo/models/shared/duration.model';\nimport { LyxaTimezone } from '@lyxa.ai/core/dist/utilities/time';\nimport { fillMissingPeriods } from '@utility/utils';\n\n@Service()\nexport class MarketingMetricsRepository {\n\tprivate model: typeof MarketingModel & SoftDeleteModel<Model>;\n\tprivate orderModel: typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\n\tconstructor() {\n\t\tthis.model = MarketingModel as typeof MarketingModel & SoftDeleteModel<Model>;\n\t\tthis.orderModel = RegularOrderModel as typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\t}\n\n\tpublic calculateMarketingSpendPerOrder(\n\t\torder: DocumentType<RegularOrder> & { lineItems: DocumentType<LineItem>[] }\n\t): Map<mongoose.Types.ObjectId, number> {\n\t\tconst spendMap = new Map<mongoose.Types.ObjectId, number>();\n\n\t\tconst addSpend = (marketingId: mongoose.Types.ObjectId, amount: number) => {\n\t\t\tif (!amount || amount <= 0) return;\n\t\t\tspendMap.set(marketingId, (spendMap.get(marketingId) ?? 0) + amount);\n\t\t};\n\n\t\t/**\n\t\t * ITEM-BASED (DISCOUNT / B1G1)\n\t\t */\n\t\tfor (const lineItem of order.lineItems ?? []) {\n\t\t\tfor (const marketingId of lineItem.marketings ?? []) {\n\t\t\t\tconst snap = lineItem.calculationSnap ?? {};\n\t\t\t\taddSpend(\n\t\t\t\t\tmarketingId._id,\n\t\t\t\t\t(Number(snap.itemDiscountByCompany) || 0) +\n\t\t\t\t\t\t(Number(snap.itemDiscountByShop) || 0) +\n\t\t\t\t\t\t(Number(snap.b1g1DiscountByCompany) || 0) +\n\t\t\t\t\t\t(Number(snap.b1g1DiscountByShop) || 0)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * FREE DELIVERY\n\t\t */\n\t\tif (order.adjustedFinance?.freeDelivery) {\n\t\t\tfor (const marketingId of order.marketings ?? []) {\n\t\t\t\taddSpend(\n\t\t\t\t\tmarketingId._id,\n\t\t\t\t\t(order.adjustedFinance.freeDelivery.companyCut ?? 0) +\n\t\t\t\t\t\t(order.adjustedFinance.freeDelivery.shopCut ?? 0)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * PUNCH MARKETING\n\t\t */\n\t\tif (order.adjustedFinance?.pricing?.punchMarketingDiscount) {\n\t\t\tfor (const marketingId of order.marketings ?? []) {\n\t\t\t\taddSpend(marketingId._id, order.adjustedFinance.pricing.punchMarketingDiscount);\n\t\t\t}\n\t\t}\n\n\t\treturn spendMap;\n\t}\n\n\tpublic async calculateMarketingSpent(\n\t\tmarketingId: mongoose.Types.ObjectId,\n\t\tduration?: Duration\n\t): Promise<{ amount: number; marketingType: MarketingType }> {\n\t\tconst marketing = await this.model.findById(marketingId).lean();\n\n\t\tif (!marketing) {\n\t\t\tnotFoundError('Marketing not found');\n\t\t}\n\n\t\tconst calculators: Record<MarketingType, () => Promise<number>> = {\n\t\t\t[MarketingType.FREE_DELIVERY]: () => this.calculateFreeDeliverySpent(marketingId, duration),\n\n\t\t\t[MarketingType.DISCOUNT]: () => this.calculateItemBasedSpent(marketingId, duration),\n\n\t\t\t[MarketingType.BUY1GET1]: () => this.calculateItemBasedSpent(marketingId, duration),\n\n\t\t\t[MarketingType.PUNCH_MARKETING]: () => this.calculatePunchMarketingSpent(marketingId, duration),\n\t\t\t[MarketingType.FEATURED]: function (): Promise<number> {\n\t\t\t\treturn Promise.resolve((marketing as DocumentType<FeaturedMarketing>).amount || 0);\n\t\t\t},\n\t\t};\n\n\t\tconst amount = calculators[marketing.marketingType] ? await calculators[marketing.marketingType]() : 0;\n\n\t\treturn {\n\t\t\tamount,\n\t\t\tmarketingType: marketing.marketingType,\n\t\t};\n\t}\n\n\tprivate async calculateItemBasedSpent(\n\t\tmarketingId: mongoose.Types.ObjectId,\n\t\tduration?: Duration\n\t): Promise<number> {\n\t\tconst pipeline: mongoose.PipelineStage[] = [\n\t\t\tthis.buildBaseMatch(marketingId, duration),\n\n\t\t\t{\n\t\t\t\t$lookup: {\n\t\t\t\t\tfrom: 'lineItems',\n\t\t\t\t\tlocalField: 'cart',\n\t\t\t\t\tforeignField: 'cart',\n\t\t\t\t\tas: 'lineItems',\n\t\t\t\t},\n\t\t\t},\n\t\t\t{ $unwind: '$lineItems' },\n\n\t\t\t{\n\t\t\t\t$group: {\n\t\t\t\t\t_id: null,\n\t\t\t\t\ttotalSpent: {\n\t\t\t\t\t\t$sum: {\n\t\t\t\t\t\t\t$add: [\n\t\t\t\t\t\t\t\t{ $ifNull: ['$lineItems.calculationSnap.itemDiscountByCompany', 0] },\n\t\t\t\t\t\t\t\t{ $ifNull: ['$lineItems.calculationSnap.itemDiscountByShop', 0] },\n\t\t\t\t\t\t\t\t{ $ifNull: ['$lineItems.calculationSnap.b1g1DiscountByCompany', 0] },\n\t\t\t\t\t\t\t\t{ $ifNull: ['$lineItems.calculationSnap.b1g1DiscountByShop', 0] },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\n\t\treturn this.runAggregateAndGetTotal(pipeline, 'totalSpent');\n\t}\n\n\tprivate async calculateFreeDeliverySpent(\n\t\tmarketingId: mongoose.Types.ObjectId,\n\t\tduration?: Duration\n\t): Promise<number> {\n\t\tconst pipeline: mongoose.PipelineStage[] = [\n\t\t\tthis.buildBaseMatch(marketingId, duration),\n\n\t\t\t{\n\t\t\t\t$group: {\n\t\t\t\t\t_id: null,\n\t\t\t\t\ttotalSpent: {\n\t\t\t\t\t\t$sum: {\n\t\t\t\t\t\t\t$add: [\n\t\t\t\t\t\t\t\t{ $ifNull: ['$adjustedFinance.freeDelivery.companyCut', 0] },\n\t\t\t\t\t\t\t\t{ $ifNull: ['$adjustedFinance.freeDelivery.shopCut', 0] },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\n\t\treturn this.runAggregateAndGetTotal(pipeline, 'totalSpent');\n\t}\n\n\tprivate async calculatePunchMarketingSpent(\n\t\tmarketingId: mongoose.Types.ObjectId,\n\t\tduration?: Duration\n\t): Promise<number> {\n\t\tconst pipeline: mongoose.PipelineStage[] = [\n\t\t\tthis.buildBaseMatch(marketingId, duration),\n\n\t\t\t{\n\t\t\t\t$group: {\n\t\t\t\t\t_id: null,\n\t\t\t\t\ttotalSpent: {\n\t\t\t\t\t\t$sum: {\n\t\t\t\t\t\t\t$ifNull: ['$adjustedFinance.pricing.punchMarketingDiscount', 0],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\n\t\treturn this.runAggregateAndGetTotal(pipeline, 'totalSpent');\n\t}\n\n\tprivate buildBaseMatch(\n\t\tmarketingId: mongoose.Types.ObjectId,\n\t\tduration?: Duration\n\t): mongoose.PipelineStage.Match {\n\t\treturn {\n\t\t\t$match: {\n\t\t\t\tmarketings: marketingId,\n\t\t\t\tstatus: { $ne: RegularOrderStatus.CANCELLED },\n\t\t\t\t...(duration && {\n\t\t\t\t\tprocessedAt: {\n\t\t\t\t\t\t$gte: duration.start,\n\t\t\t\t\t\t$lte: duration.end,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t};\n\t}\n\n\tprivate async runAggregateAndGetTotal(pipeline: mongoose.PipelineStage[], field: string): Promise<number> {\n\t\tconst [result] = await this.orderModel.aggregate(pipeline);\n\t\treturn result?.[field] ?? 0;\n\t}\n\n\tpublic async getMetrics(marketingId: mongoose.Types.ObjectId): Promise<MarketingMetricsDTO> {\n\t\tconst marketing = await this.model.findById(marketingId).lean();\n\n\t\tif (!marketing) {\n\t\t\tnotFoundError('Marketing not found');\n\t\t}\n\n\t\tconst currentDuration = { start: marketing.duration.start, end: dayjs().toDate() };\n\t\tconst previousDuration = {\n\t\t\tstart: dayjs(marketing.duration.start).subtract(dayjs().diff(marketing.duration.start)).toDate(),\n\t\t\tend: marketing.duration.start,\n\t\t};\n\n\t\tlet metrics: MarketingMetricsDTO = {};\n\n\t\tif ([MarketingType.DISCOUNT, MarketingType.BUY1GET1].includes(marketing.marketingType)) {\n\t\t\tmetrics.numberOfItems = await this.getMarketingItemCount(marketingId);\n\t\t}\n\n\t\tmetrics.orderIncreaseWithDiscount = await this.calculateOrderIncreaseWithDiscount(\n\t\t\tmarketingId,\n\t\t\tmarketing.shop._id,\n\t\t\tcurrentDuration,\n\t\t\tpreviousDuration\n\t\t);\n\t\tmetrics.customerIncreaseWithDiscount = await this.calculateCustomerIncreaseWithDiscount(\n\t\t\tmarketingId,\n\t\t\tmarketing.shop._id,\n\t\t\tcurrentDuration,\n\t\t\tpreviousDuration\n\t\t);\n\n\t\treturn metrics;\n\t}\n\n\tprivate async getMarketingItemCount(marketingId: mongoose.Types.ObjectId): Promise<number> {\n\t\tconst result = await productMarketingService.countDocuments({ marketing: marketingId });\n\t\treturn result ?? 0;\n\t}\n\n\tprivate async calculateOrderIncreaseWithDiscount(\n\t\tmarketingId: mongoose.Types.ObjectId,\n\t\tshopId: mongoose.Types.ObjectId,\n\t\tcurrentDuration: Duration,\n\t\tpreviousDuration: Duration\n\t): Promise<IncreaseDuringDiscountDTO> {\n\t\tconst [currentOrders, previousOrders] = await Promise.all([\n\t\t\tthis.orderModel.countDocuments({\n\t\t\t\tcreatedAt: {\n\t\t\t\t\t$gte: currentDuration.start,\n\t\t\t\t\t$lte: currentDuration.end,\n\t\t\t\t},\n\t\t\t\tmarketings: marketingId, // marketing must be applied\n\t\t\t\tshop: shopId,\n\t\t\t}),\n\t\t\tthis.orderModel.countDocuments({\n\t\t\t\tcreatedAt: {\n\t\t\t\t\t$gte: previousDuration.start,\n\t\t\t\t\t$lte: previousDuration.end,\n\t\t\t\t},\n\t\t\t\tshop: shopId,\n\t\t\t}),\n\t\t]);\n\n\t\treturn this.calculateIncrease(currentOrders, previousOrders);\n\t}\n\n\tprivate async calculateCustomerIncreaseWithDiscount(\n\t\tmarketingId: mongoose.Types.ObjectId,\n\t\tshopId: mongoose.Types.ObjectId,\n\t\tcurrentDuration: Duration,\n\t\tpreviousDuration: Duration\n\t): Promise<IncreaseDuringDiscountDTO> {\n\t\tconst [currentNewCustomers, previousNewCustomers] = await Promise.all([\n\t\t\tthis.getNewCustomersForShop(shopId, currentDuration, { marketings: marketingId }),\n\t\t\tthis.getNewCustomersForShop(shopId, previousDuration),\n\t\t]);\n\n\t\treturn this.calculateIncrease(currentNewCustomers, previousNewCustomers);\n\t}\n\n\tprivate calculateIncrease(current: number, previous: number): IncreaseDuringDiscountDTO {\n\t\tconst count = current - previous;\n\n\t\tconst percentageIncrease = previous === 0 ? (current > 0 ? 100 : 0) : (count / previous) * 100;\n\n\t\treturn {\n\t\t\tcount,\n\t\t\tpercentageIncrease,\n\t\t};\n\t}\n\n\tprivate async getNewCustomersForShop(\n\t\tshopId: mongoose.Types.ObjectId,\n\t\tduration: Duration,\n\t\textraMatch: Record<string, any> = {}\n\t): Promise<number> {\n\t\t// Customers who ordered during the period\n\t\tconst customersInPeriod = await this.orderModel.distinct('user', {\n\t\t\tcreatedAt: {\n\t\t\t\t$gte: duration.start,\n\t\t\t\t$lte: duration.end,\n\t\t\t},\n\t\t\tshop: shopId,\n\t\t\t...extraMatch,\n\t\t});\n\n\t\tif (customersInPeriod.length === 0) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Customers who had ordered from this shop BEFORE the period\n\t\tconst existingCustomers = await this.orderModel.distinct('user', {\n\t\t\tshop: shopId,\n\t\t\tcreatedAt: { $lt: duration.start },\n\t\t\tuser: { $in: customersInPeriod },\n\t\t});\n\n\t\t// New customers = in period − existing\n\t\treturn customersInPeriod.length - existingCustomers.length;\n\t}\n\n\tpublic async getOrdersGraph(data: MarketingGraphInputDTO): Promise<MarketingOrdersGraphOutputDTO> {\n\t\tconst dateFormat = data.type === GraphType.MONTHLY ? '%Y-%m' : '%Y-%m-%d';\n\n\t\tconst pipeline: mongoose.PipelineStage[] = [\n\t\t\t// Filter only delivered orders within the given date range\n\t\t\tthis.buildBaseMatch(new mongoose.Types.ObjectId(data.marketingId), {\n\t\t\t\tstart: data.startDate,\n\t\t\t\tend: data.endDate,\n\t\t\t}),\n\n\t\t\t// Extract formatted date from 'processedAt' for grouping\n\t\t\t{\n\t\t\t\t$project: {\n\t\t\t\t\tdate: {\n\t\t\t\t\t\t$dateToString: {\n\t\t\t\t\t\t\tformat: dateFormat,\n\t\t\t\t\t\t\tdate: '$processedAt',\n\t\t\t\t\t\t\ttimezone: LyxaTimezone,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Group by formatted date and count orders\n\t\t\t{\n\t\t\t\t$group: {\n\t\t\t\t\t_id: '$date',\n\t\t\t\t\torders: { $sum: 1 },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Sort results chronologically\n\t\t\t{\n\t\t\t\t$sort: { _id: 1 },\n\t\t\t},\n\n\t\t\t// Format the response to match output DTO structure\n\t\t\t{\n\t\t\t\t$project: {\n\t\t\t\t\t_id: 0,\n\t\t\t\t\tdate: '$_id',\n\t\t\t\t\torders: 1,\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\n\t\t// Execute aggregation pipeline\n\t\tconst results = await this.orderModel.aggregate(pipeline).allowDiskUse(true).exec();\n\n\t\tconst graphData = fillMissingPeriods(results, data.startDate, data.endDate, data.type, {\n\t\t\torders: 0,\n\t\t});\n\n\t\treturn graphData;\n\t}\n\n\tpublic async getCustomersGraph(data: MarketingGraphInputDTO): Promise<{ date: string; users: number }[]> {\n\t\t// 1️⃣ Get shopId from marketing\n\t\tconst marketing = await this.model.findById(data.marketingId).select('shop').lean();\n\n\t\tif (!marketing) {\n\t\t\tnotFoundError('Marketing not found');\n\t\t}\n\n\t\tconst shopId = marketing.shop._id;\n\n\t\t// 2️⃣ Fetch users who ordered from this shop BEFORE the start date\n\t\tconst oldUsers = await this.orderModel.distinct('user', {\n\t\t\tshop: shopId,\n\t\t\tstatus: RegularOrderStatus.DELIVERED,\n\t\t\tprocessedAt: { $lt: data.startDate },\n\t\t});\n\n\t\tconst dateFormat = data.type === GraphType.MONTHLY ? '%Y-%m' : '%Y-%m-%d';\n\n\t\t// 3️⃣ Aggregation pipeline\n\t\tconst pipeline: mongoose.PipelineStage[] = [\n\t\t\t// Orders during the period with this marketing\n\t\t\t{\n\t\t\t\t$match: {\n\t\t\t\t\torderType: OrderType.REGULAR,\n\t\t\t\t\tstatus: RegularOrderStatus.DELIVERED,\n\t\t\t\t\tshop: shopId,\n\t\t\t\t\tmarketings: new mongoose.Types.ObjectId(data.marketingId),\n\t\t\t\t\tprocessedAt: { $gte: data.startDate, $lte: data.endDate },\n\t\t\t\t\tuser: { $nin: oldUsers }, // 🚫 exclude old users\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Sort so earliest order per user comes first\n\t\t\t{ $sort: { processedAt: 1 } },\n\n\t\t\t// First order per user (new users only)\n\t\t\t{\n\t\t\t\t$group: {\n\t\t\t\t\t_id: '$user',\n\t\t\t\t\tfirstOrderDate: { $first: '$processedAt' },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Format date\n\t\t\t{\n\t\t\t\t$project: {\n\t\t\t\t\tdate: {\n\t\t\t\t\t\t$dateToString: {\n\t\t\t\t\t\t\tformat: dateFormat,\n\t\t\t\t\t\t\tdate: '$firstOrderDate',\n\t\t\t\t\t\t\ttimezone: LyxaTimezone,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Group by date\n\t\t\t{\n\t\t\t\t$group: {\n\t\t\t\t\t_id: '$date',\n\t\t\t\t\tusers: { $sum: 1 },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Sort chronologically\n\t\t\t{ $sort: { _id: 1 } },\n\n\t\t\t// Shape response\n\t\t\t{\n\t\t\t\t$project: {\n\t\t\t\t\t_id: 0,\n\t\t\t\t\tdate: '$_id',\n\t\t\t\t\tusers: 1,\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\n\t\tconst results = await this.orderModel.aggregate(pipeline).allowDiskUse(true).exec();\n\n\t\t// 4️⃣ Fill missing periods\n\t\treturn fillMissingPeriods(results, data.startDate, data.endDate, data.type, {\n\t\t\tusers: 0,\n\t\t});\n\t}\n\n\tpublic async getAmountSpentGraph(\n\t\tdata: MarketingGraphInputDTO\n\t): Promise<{ date: string; amount: number }[]> {\n\t\tconst marketing = await this.model.findById(data.marketingId).lean();\n\n\t\tif (!marketing) {\n\t\t\tnotFoundError('Marketing not found');\n\t\t}\n\n\t\tconst marketingId = new mongoose.Types.ObjectId(data.marketingId);\n\t\tconst dateFormat = data.type === GraphType.MONTHLY ? '%Y-%m' : '%Y-%m-%d';\n\n\t\tlet pipeline: mongoose.PipelineStage[] | null = null;\n\n\t\t/**\n\t\t * ITEM-BASED (DISCOUNT / BUY1GET1)\n\t\t */\n\t\tif ([MarketingType.DISCOUNT, MarketingType.BUY1GET1].includes(marketing.marketingType)) {\n\t\t\tpipeline = [\n\t\t\t\tthis.buildBaseMatch(marketingId, {\n\t\t\t\t\tstart: data.startDate,\n\t\t\t\t\tend: data.endDate,\n\t\t\t\t}),\n\t\t\t\t{\n\t\t\t\t\t$lookup: {\n\t\t\t\t\t\tfrom: 'lineItems',\n\t\t\t\t\t\tlocalField: 'cart',\n\t\t\t\t\t\tforeignField: 'cart',\n\t\t\t\t\t\tas: 'lineItems',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{ $unwind: '$lineItems' },\n\t\t\t\t{\n\t\t\t\t\t$match: {\n\t\t\t\t\t\t'lineItems.marketings': marketingId,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$project: {\n\t\t\t\t\t\tdate: {\n\t\t\t\t\t\t\t$dateToString: {\n\t\t\t\t\t\t\t\tformat: dateFormat,\n\t\t\t\t\t\t\t\tdate: '$processedAt',\n\t\t\t\t\t\t\t\ttimezone: LyxaTimezone,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tamount: {\n\t\t\t\t\t\t\t$add: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t$cond: [\n\t\t\t\t\t\t\t\t\t\tmarketing.isAppliedByCompany,\n\t\t\t\t\t\t\t\t\t\t{ $ifNull: ['$lineItems.calculationSnap.itemDiscountByCompany', 0] },\n\t\t\t\t\t\t\t\t\t\t{ $ifNull: ['$lineItems.calculationSnap.itemDiscountByShop', 0] },\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t$cond: [\n\t\t\t\t\t\t\t\t\t\tmarketing.isAppliedByCompany,\n\t\t\t\t\t\t\t\t\t\t{ $ifNull: ['$lineItems.calculationSnap.b1g1DiscountByCompany', 0] },\n\t\t\t\t\t\t\t\t\t\t{ $ifNull: ['$lineItems.calculationSnap.b1g1DiscountByShop', 0] },\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$group: {\n\t\t\t\t\t\t_id: '$date',\n\t\t\t\t\t\tamount: { $sum: '$amount' },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{ $sort: { _id: 1 } },\n\t\t\t\t{\n\t\t\t\t\t$project: {\n\t\t\t\t\t\t_id: 0,\n\t\t\t\t\t\tdate: '$_id',\n\t\t\t\t\t\tamount: 1,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t];\n\t\t} else if (marketing.marketingType === MarketingType.FREE_DELIVERY) {\n\n\t\t/**\n\t\t * FREE DELIVERY\n\t\t */\n\t\t\tpipeline = [\n\t\t\t\tthis.buildBaseMatch(marketingId, {\n\t\t\t\t\tstart: data.startDate,\n\t\t\t\t\tend: data.endDate,\n\t\t\t\t}),\n\t\t\t\t{\n\t\t\t\t\t$project: {\n\t\t\t\t\t\tdate: {\n\t\t\t\t\t\t\t$dateToString: {\n\t\t\t\t\t\t\t\tformat: dateFormat,\n\t\t\t\t\t\t\t\tdate: '$processedAt',\n\t\t\t\t\t\t\t\ttimezone: LyxaTimezone,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tamount: {\n\t\t\t\t\t\t\t$cond: [\n\t\t\t\t\t\t\t\tmarketing.isAppliedByCompany,\n\t\t\t\t\t\t\t\t{ $ifNull: ['$adjustedFinance.freeDelivery.companyCut', 0] },\n\t\t\t\t\t\t\t\t{ $ifNull: ['$adjustedFinance.freeDelivery.shopCut', 0] },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$group: {\n\t\t\t\t\t\t_id: '$date',\n\t\t\t\t\t\tamount: { $sum: '$amount' },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{ $sort: { _id: 1 } },\n\t\t\t\t{\n\t\t\t\t\t$project: {\n\t\t\t\t\t\t_id: 0,\n\t\t\t\t\t\tdate: '$_id',\n\t\t\t\t\t\tamount: 1,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t];\n\t\t} else if (marketing.marketingType === MarketingType.PUNCH_MARKETING) {\n\n\t\t/**\n\t\t * PUNCH MARKETING\n\t\t */\n\t\t\tpipeline = [\n\t\t\t\tthis.buildBaseMatch(marketingId, {\n\t\t\t\t\tstart: data.startDate,\n\t\t\t\t\tend: data.endDate,\n\t\t\t\t}),\n\t\t\t\t{\n\t\t\t\t\t$project: {\n\t\t\t\t\t\tdate: {\n\t\t\t\t\t\t\t$dateToString: {\n\t\t\t\t\t\t\t\tformat: dateFormat,\n\t\t\t\t\t\t\t\tdate: '$processedAt',\n\t\t\t\t\t\t\t\ttimezone: LyxaTimezone,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tamount: {\n\t\t\t\t\t\t\t$ifNull: ['$adjustedFinance.pricing.punchMarketingDiscount', 0],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$group: {\n\t\t\t\t\t\t_id: '$date',\n\t\t\t\t\t\tamount: { $sum: '$amount' },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{ $sort: { _id: 1 } },\n\t\t\t\t{\n\t\t\t\t\t$project: {\n\t\t\t\t\t\t_id: 0,\n\t\t\t\t\t\tdate: '$_id',\n\t\t\t\t\t\tamount: 1,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\n\t\t// If marketing type doesn't produce spend graph → return empty graph\n\t\tif (!pipeline) {\n\t\t\treturn fillMissingPeriods([] as { date: string; amount: number }[], data.startDate, data.endDate, data.type, {\n\t\t\t\tamount: 0,\n\t\t\t});\n\t\t}\n\n\t\tconst results = await this.orderModel.aggregate(pipeline).allowDiskUse(true).exec();\n\n\t\treturn fillMissingPeriods(results, data.startDate, data.endDate, data.type, {\n\t\t\tamount: 0,\n\t\t});\n\t}\n}\n\nexport const marketingMetricsRepository = Container.get(MarketingMetricsRepository);\n"]}
1
+ {"version":3,"file":"MarketingMetricsRepository.js","sourceRoot":"/","sources":["modules/marketing/patterns/repository/MarketingMetricsRepository.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, { Service } from 'typedi';\nimport { dayjs } from '@lyxa.ai/core/dist/utilities/dayjs';\nimport { DocumentType, mongoose, ReturnModelType } from '@typegoose/typegoose';\nimport {\n\tFeaturedMarketing,\n\tLineItem,\n\tMarketingModel,\n\tMarketing as Model,\n\tRegularOrder,\n\tRegularOrderModel,\n} from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport {\n\tIncreaseDuringDiscountDTO,\n\tMarketingGraphInputDTO,\n\tMarketingMetricsDTO,\n\tMarketingOrdersGraphOutputDTO,\n} from '@modules/marketing/validations';\nimport { SoftDeleteModel } from '@lyxa.ai/core/dist/libraries/mongo/plugins/soft-delete-plugin';\nimport { GraphType, OrderType, RegularOrderStatus } from '@lyxa.ai/core/dist/utilities/enum';\nimport { productMarketingService } from '@modules/marketing/services/product-marketing.service';\nimport { MarketingType } from '@lyxa.ai/core/dist/utilities/enum';\nimport { notFoundError } from '@lyxa.ai/core/dist/utilities/error-common';\nimport { Duration } from '@lyxa.ai/core/dist/libraries/mongo/models/shared/duration.model';\nimport { LyxaTimezone } from '@lyxa.ai/core/dist/utilities/time';\nimport { fillMissingPeriods } from '@utility/utils';\n\n@Service()\nexport class MarketingMetricsRepository {\n\tprivate model: typeof MarketingModel & SoftDeleteModel<Model>;\n\tprivate orderModel: typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\n\tconstructor() {\n\t\tthis.model = MarketingModel as typeof MarketingModel & SoftDeleteModel<Model>;\n\t\tthis.orderModel = RegularOrderModel as typeof RegularOrderModel & SoftDeleteModel<RegularOrder>;\n\t}\n\n\tpublic calculateMarketingSpendPerOrder(\n\t\torder: DocumentType<RegularOrder> & { lineItems: DocumentType<LineItem>[] }\n\t): Map<mongoose.Types.ObjectId, number> {\n\t\tconst spendMap = new Map<mongoose.Types.ObjectId, number>();\n\n\t\tconst addSpend = (marketingId: mongoose.Types.ObjectId, amount: number) => {\n\t\t\tif (!amount || amount <= 0) return;\n\t\t\tspendMap.set(marketingId, (spendMap.get(marketingId) ?? 0) + amount);\n\t\t};\n\n\t\t/**\n\t\t * ITEM-BASED (DISCOUNT / B1G1)\n\t\t */\n\t\tfor (const lineItem of order.lineItems ?? []) {\n\t\t\tfor (const marketingId of lineItem.marketings ?? []) {\n\t\t\t\tconst snap = lineItem.calculationSnap ?? {};\n\t\t\t\taddSpend(\n\t\t\t\t\tmarketingId._id,\n\t\t\t\t\t(Number(snap.itemDiscountByCompany) || 0) +\n\t\t\t\t\t\t(Number(snap.itemDiscountByShop) || 0) +\n\t\t\t\t\t\t(Number(snap.b1g1DiscountByCompany) || 0) +\n\t\t\t\t\t\t(Number(snap.b1g1DiscountByShop) || 0)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * FREE DELIVERY\n\t\t */\n\t\tif (order.adjustedFinance?.freeDelivery) {\n\t\t\tfor (const marketingId of order.marketings ?? []) {\n\t\t\t\taddSpend(\n\t\t\t\t\tmarketingId._id,\n\t\t\t\t\t(order.adjustedFinance.freeDelivery.companyCut ?? 0) +\n\t\t\t\t\t\t(order.adjustedFinance.freeDelivery.shopCut ?? 0)\n\t\t\t\t);\n\t\t\t}\n\t\t}\n\n\t\t/**\n\t\t * PUNCH MARKETING\n\t\t */\n\t\tif (order.adjustedFinance?.pricing?.punchMarketingDiscount) {\n\t\t\tfor (const marketingId of order.marketings ?? []) {\n\t\t\t\taddSpend(marketingId._id, order.adjustedFinance.pricing.punchMarketingDiscount);\n\t\t\t}\n\t\t}\n\n\t\treturn spendMap;\n\t}\n\n\tpublic async calculateMarketingSpent(\n\t\tmarketingId: mongoose.Types.ObjectId,\n\t\tduration?: Duration\n\t): Promise<{ amount: number; marketingType: MarketingType }> {\n\t\tconst marketing = await this.model.findById(marketingId).lean();\n\n\t\tif (!marketing) {\n\t\t\tnotFoundError('Marketing not found');\n\t\t}\n\n\t\tconst calculators: Record<MarketingType, () => Promise<number>> = {\n\t\t\t[MarketingType.FREE_DELIVERY]: () => this.calculateFreeDeliverySpent(marketingId, duration),\n\n\t\t\t[MarketingType.DISCOUNT]: () => this.calculateItemBasedSpent(marketingId, duration),\n\n\t\t\t[MarketingType.BUY1GET1]: () => this.calculateItemBasedSpent(marketingId, duration),\n\n\t\t\t[MarketingType.PUNCH_MARKETING]: () => this.calculatePunchMarketingSpent(marketingId, duration),\n\t\t\t[MarketingType.FEATURED]: function (): Promise<number> {\n\t\t\t\treturn Promise.resolve((marketing as DocumentType<FeaturedMarketing>).amount || 0);\n\t\t\t},\n\t\t};\n\n\t\tconst amount = calculators[marketing.marketingType] ? await calculators[marketing.marketingType]() : 0;\n\n\t\treturn {\n\t\t\tamount,\n\t\t\tmarketingType: marketing.marketingType,\n\t\t};\n\t}\n\n\tprivate async calculateItemBasedSpent(\n\t\tmarketingId: mongoose.Types.ObjectId,\n\t\tduration?: Duration\n\t): Promise<number> {\n\t\tconst pipeline: mongoose.PipelineStage[] = [\n\t\t\tthis.buildBaseMatch(marketingId, duration),\n\n\t\t\t{\n\t\t\t\t$lookup: {\n\t\t\t\t\tfrom: 'lineItems',\n\t\t\t\t\tlocalField: 'cart',\n\t\t\t\t\tforeignField: 'cart',\n\t\t\t\t\tas: 'lineItems',\n\t\t\t\t},\n\t\t\t},\n\t\t\t{ $unwind: '$lineItems' },\n\n\t\t\t{\n\t\t\t\t$group: {\n\t\t\t\t\t_id: null,\n\t\t\t\t\ttotalSpent: {\n\t\t\t\t\t\t$sum: {\n\t\t\t\t\t\t\t$add: [\n\t\t\t\t\t\t\t\t{ $ifNull: ['$lineItems.calculationSnap.itemDiscountByCompany', 0] },\n\t\t\t\t\t\t\t\t{ $ifNull: ['$lineItems.calculationSnap.itemDiscountByShop', 0] },\n\t\t\t\t\t\t\t\t{ $ifNull: ['$lineItems.calculationSnap.b1g1DiscountByCompany', 0] },\n\t\t\t\t\t\t\t\t{ $ifNull: ['$lineItems.calculationSnap.b1g1DiscountByShop', 0] },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\n\t\treturn this.runAggregateAndGetTotal(pipeline, 'totalSpent');\n\t}\n\n\tprivate async calculateFreeDeliverySpent(\n\t\tmarketingId: mongoose.Types.ObjectId,\n\t\tduration?: Duration\n\t): Promise<number> {\n\t\tconst pipeline: mongoose.PipelineStage[] = [\n\t\t\tthis.buildBaseMatch(marketingId, duration),\n\n\t\t\t{\n\t\t\t\t$group: {\n\t\t\t\t\t_id: null,\n\t\t\t\t\ttotalSpent: {\n\t\t\t\t\t\t$sum: {\n\t\t\t\t\t\t\t$add: [\n\t\t\t\t\t\t\t\t{ $ifNull: ['$adjustedFinance.freeDelivery.companyCut', 0] },\n\t\t\t\t\t\t\t\t{ $ifNull: ['$adjustedFinance.freeDelivery.shopCut', 0] },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\n\t\treturn this.runAggregateAndGetTotal(pipeline, 'totalSpent');\n\t}\n\n\tprivate async calculatePunchMarketingSpent(\n\t\tmarketingId: mongoose.Types.ObjectId,\n\t\tduration?: Duration\n\t): Promise<number> {\n\t\tconst pipeline: mongoose.PipelineStage[] = [\n\t\t\tthis.buildBaseMatch(marketingId, duration),\n\n\t\t\t{\n\t\t\t\t$group: {\n\t\t\t\t\t_id: null,\n\t\t\t\t\ttotalSpent: {\n\t\t\t\t\t\t$sum: {\n\t\t\t\t\t\t\t$ifNull: ['$adjustedFinance.pricing.punchMarketingDiscount', 0],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\n\t\treturn this.runAggregateAndGetTotal(pipeline, 'totalSpent');\n\t}\n\n\tprivate buildBaseMatch(\n\t\tmarketingId: mongoose.Types.ObjectId,\n\t\tduration?: Duration\n\t): mongoose.PipelineStage.Match {\n\t\treturn {\n\t\t\t$match: {\n\t\t\t\tmarketings: marketingId,\n\t\t\t\tstatus: { $ne: RegularOrderStatus.CANCELLED },\n\t\t\t\t...(duration && {\n\t\t\t\t\tprocessedAt: {\n\t\t\t\t\t\t$gte: duration.start,\n\t\t\t\t\t\t$lte: duration.end,\n\t\t\t\t\t},\n\t\t\t\t}),\n\t\t\t},\n\t\t};\n\t}\n\n\tprivate async runAggregateAndGetTotal(pipeline: mongoose.PipelineStage[], field: string): Promise<number> {\n\t\tconst [result] = await this.orderModel.aggregate(pipeline);\n\t\treturn result?.[field] ?? 0;\n\t}\n\n\tpublic async getMetrics(marketingId: mongoose.Types.ObjectId): Promise<MarketingMetricsDTO> {\n\t\tconst marketing = await this.model.findById(marketingId).lean();\n\n\t\tif (!marketing) {\n\t\t\tnotFoundError('Marketing not found');\n\t\t}\n\n\t\t//TODO: fix current end and previous start\n\n\t\tconst currentDuration = { start: marketing.duration.start, end: dayjs().toDate() };\n\t\tconst previousDuration = {\n\t\t\tstart: dayjs(marketing.duration.start).subtract(dayjs().diff(marketing.duration.start)).toDate(),\n\t\t\tend: marketing.duration.start,\n\t\t};\n\n\t\tlet metrics: MarketingMetricsDTO = {};\n\n\t\tif ([MarketingType.DISCOUNT, MarketingType.BUY1GET1].includes(marketing.marketingType)) {\n\t\t\tmetrics.numberOfItems = await this.getMarketingItemCount(marketingId);\n\t\t}\n\n\t\tmetrics.orderIncreaseWithDiscount = await this.calculateOrderIncreaseWithDiscount(\n\t\t\tmarketingId,\n\t\t\tmarketing.shop._id,\n\t\t\tcurrentDuration,\n\t\t\tpreviousDuration\n\t\t);\n\t\tmetrics.customerIncreaseWithDiscount = await this.calculateCustomerIncreaseWithDiscount(\n\t\t\tmarketingId,\n\t\t\tmarketing.shop._id,\n\t\t\tcurrentDuration,\n\t\t\tpreviousDuration\n\t\t);\n\n\t\treturn metrics;\n\t}\n\n\tprivate async getMarketingItemCount(marketingId: mongoose.Types.ObjectId): Promise<number> {\n\t\tconst result = await productMarketingService.countDocuments({ marketing: marketingId });\n\t\treturn result ?? 0;\n\t}\n\n\tprivate async calculateOrderIncreaseWithDiscount(\n\t\tmarketingId: mongoose.Types.ObjectId,\n\t\tshopId: mongoose.Types.ObjectId,\n\t\tcurrentDuration: Duration,\n\t\tpreviousDuration: Duration\n\t): Promise<IncreaseDuringDiscountDTO> {\n\t\tconst [currentOrders, previousOrders] = await Promise.all([\n\t\t\tthis.orderModel.countDocuments({\n\t\t\t\tcreatedAt: {\n\t\t\t\t\t$gte: currentDuration.start,\n\t\t\t\t\t$lte: currentDuration.end,\n\t\t\t\t},\n\t\t\t\tmarketings: marketingId, // marketing must be applied\n\t\t\t\tshop: shopId,\n\t\t\t}),\n\t\t\tthis.orderModel.countDocuments({\n\t\t\t\tcreatedAt: {\n\t\t\t\t\t$gte: previousDuration.start,\n\t\t\t\t\t$lte: previousDuration.end,\n\t\t\t\t},\n\t\t\t\tshop: shopId,\n\t\t\t}),\n\t\t]);\n\n\t\treturn this.calculateIncrease(currentOrders, previousOrders);\n\t}\n\n\tprivate async calculateCustomerIncreaseWithDiscount(\n\t\tmarketingId: mongoose.Types.ObjectId,\n\t\tshopId: mongoose.Types.ObjectId,\n\t\tcurrentDuration: Duration,\n\t\tpreviousDuration: Duration\n\t): Promise<IncreaseDuringDiscountDTO> {\n\t\tconst [currentNewCustomers, previousNewCustomers] = await Promise.all([\n\t\t\tthis.getNewCustomersForShop(shopId, currentDuration, { marketings: marketingId }),\n\t\t\tthis.getNewCustomersForShop(shopId, previousDuration),\n\t\t]);\n\n\t\treturn this.calculateIncrease(currentNewCustomers, previousNewCustomers);\n\t}\n\n\tprivate calculateIncrease(current: number, previous: number): IncreaseDuringDiscountDTO {\n\t\tconst count = current - previous;\n\n\t\tconst percentageIncrease = previous === 0 ? (current > 0 ? 100 : 0) : (count / previous) * 100;\n\n\t\treturn {\n\t\t\tcount,\n\t\t\tpercentageIncrease,\n\t\t};\n\t}\n\n\tprivate async getNewCustomersForShop(\n\t\tshopId: mongoose.Types.ObjectId,\n\t\tduration: Duration,\n\t\textraMatch: Record<string, any> = {}\n\t): Promise<number> {\n\t\t// Customers who ordered during the period\n\t\tconst customersInPeriod = await this.orderModel.distinct('user', {\n\t\t\tcreatedAt: {\n\t\t\t\t$gte: duration.start,\n\t\t\t\t$lte: duration.end,\n\t\t\t},\n\t\t\tshop: shopId,\n\t\t\t...extraMatch,\n\t\t});\n\n\t\tif (customersInPeriod.length === 0) {\n\t\t\treturn 0;\n\t\t}\n\n\t\t// Customers who had ordered from this shop BEFORE the period\n\t\tconst existingCustomers = await this.orderModel.distinct('user', {\n\t\t\tshop: shopId,\n\t\t\tcreatedAt: { $lt: duration.start },\n\t\t\tuser: { $in: customersInPeriod },\n\t\t});\n\n\t\t// New customers = in period − existing\n\t\treturn customersInPeriod.length - existingCustomers.length;\n\t}\n\n\tpublic async getOrdersGraph(data: MarketingGraphInputDTO): Promise<MarketingOrdersGraphOutputDTO> {\n\t\tconst dateFormat = data.type === GraphType.MONTHLY ? '%Y-%m' : '%Y-%m-%d';\n\n\t\tconst pipeline: mongoose.PipelineStage[] = [\n\t\t\t// Filter only delivered orders within the given date range\n\t\t\tthis.buildBaseMatch(new mongoose.Types.ObjectId(data.marketingId), {\n\t\t\t\tstart: data.startDate,\n\t\t\t\tend: data.endDate,\n\t\t\t}),\n\n\t\t\t// Extract formatted date from 'processedAt' for grouping\n\t\t\t{\n\t\t\t\t$project: {\n\t\t\t\t\tdate: {\n\t\t\t\t\t\t$dateToString: {\n\t\t\t\t\t\t\tformat: dateFormat,\n\t\t\t\t\t\t\tdate: '$processedAt',\n\t\t\t\t\t\t\ttimezone: LyxaTimezone,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Group by formatted date and count orders\n\t\t\t{\n\t\t\t\t$group: {\n\t\t\t\t\t_id: '$date',\n\t\t\t\t\torders: { $sum: 1 },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Sort results chronologically\n\t\t\t{\n\t\t\t\t$sort: { _id: 1 },\n\t\t\t},\n\n\t\t\t// Format the response to match output DTO structure\n\t\t\t{\n\t\t\t\t$project: {\n\t\t\t\t\t_id: 0,\n\t\t\t\t\tdate: '$_id',\n\t\t\t\t\torders: 1,\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\n\t\t// Execute aggregation pipeline\n\t\tconst results = await this.orderModel.aggregate(pipeline).allowDiskUse(true).exec();\n\n\t\tconst graphData = fillMissingPeriods(results, data.startDate, data.endDate, data.type, {\n\t\t\torders: 0,\n\t\t});\n\n\t\treturn graphData;\n\t}\n\n\tpublic async getCustomersGraph(data: MarketingGraphInputDTO): Promise<{ date: string; users: number }[]> {\n\t\t// 1️⃣ Get shopId from marketing\n\t\tconst marketing = await this.model.findById(data.marketingId).select('shop').lean();\n\n\t\tif (!marketing) {\n\t\t\tnotFoundError('Marketing not found');\n\t\t}\n\n\t\tconst shopId = marketing.shop._id;\n\n\t\t// 2️⃣ Fetch users who ordered from this shop BEFORE the start date\n\t\tconst oldUsers = await this.orderModel.distinct('user', {\n\t\t\tshop: shopId,\n\t\t\tstatus: RegularOrderStatus.DELIVERED,\n\t\t\tprocessedAt: { $lt: data.startDate },\n\t\t});\n\n\t\tconst dateFormat = data.type === GraphType.MONTHLY ? '%Y-%m' : '%Y-%m-%d';\n\n\t\t// 3️⃣ Aggregation pipeline\n\t\tconst pipeline: mongoose.PipelineStage[] = [\n\t\t\t// Orders during the period with this marketing\n\t\t\t{\n\t\t\t\t$match: {\n\t\t\t\t\torderType: OrderType.REGULAR,\n\t\t\t\t\tstatus: RegularOrderStatus.DELIVERED,\n\t\t\t\t\tshop: shopId,\n\t\t\t\t\tmarketings: new mongoose.Types.ObjectId(data.marketingId),\n\t\t\t\t\tprocessedAt: { $gte: data.startDate, $lte: data.endDate },\n\t\t\t\t\tuser: { $nin: oldUsers }, // 🚫 exclude old users\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Sort so earliest order per user comes first\n\t\t\t{ $sort: { processedAt: 1 } },\n\n\t\t\t// First order per user (new users only)\n\t\t\t{\n\t\t\t\t$group: {\n\t\t\t\t\t_id: '$user',\n\t\t\t\t\tfirstOrderDate: { $first: '$processedAt' },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Format date\n\t\t\t{\n\t\t\t\t$project: {\n\t\t\t\t\tdate: {\n\t\t\t\t\t\t$dateToString: {\n\t\t\t\t\t\t\tformat: dateFormat,\n\t\t\t\t\t\t\tdate: '$firstOrderDate',\n\t\t\t\t\t\t\ttimezone: LyxaTimezone,\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Group by date\n\t\t\t{\n\t\t\t\t$group: {\n\t\t\t\t\t_id: '$date',\n\t\t\t\t\tusers: { $sum: 1 },\n\t\t\t\t},\n\t\t\t},\n\n\t\t\t// Sort chronologically\n\t\t\t{ $sort: { _id: 1 } },\n\n\t\t\t// Shape response\n\t\t\t{\n\t\t\t\t$project: {\n\t\t\t\t\t_id: 0,\n\t\t\t\t\tdate: '$_id',\n\t\t\t\t\tusers: 1,\n\t\t\t\t},\n\t\t\t},\n\t\t];\n\n\t\tconst results = await this.orderModel.aggregate(pipeline).allowDiskUse(true).exec();\n\n\t\t// 4️⃣ Fill missing periods\n\t\treturn fillMissingPeriods(results, data.startDate, data.endDate, data.type, {\n\t\t\tusers: 0,\n\t\t});\n\t}\n\n\tpublic async getAmountSpentGraph(\n\t\tdata: MarketingGraphInputDTO\n\t): Promise<{ date: string; amount: number }[]> {\n\t\tconst marketing = await this.model.findById(data.marketingId).lean();\n\n\t\tif (!marketing) {\n\t\t\tnotFoundError('Marketing not found');\n\t\t}\n\n\t\tconst marketingId = new mongoose.Types.ObjectId(data.marketingId);\n\t\tconst dateFormat = data.type === GraphType.MONTHLY ? '%Y-%m' : '%Y-%m-%d';\n\n\t\tlet pipeline: mongoose.PipelineStage[] | null = null;\n\n\t\t/**\n\t\t * ITEM-BASED (DISCOUNT / BUY1GET1)\n\t\t */\n\t\tif ([MarketingType.DISCOUNT, MarketingType.BUY1GET1].includes(marketing.marketingType)) {\n\t\t\tpipeline = [\n\t\t\t\tthis.buildBaseMatch(marketingId, {\n\t\t\t\t\tstart: data.startDate,\n\t\t\t\t\tend: data.endDate,\n\t\t\t\t}),\n\t\t\t\t{\n\t\t\t\t\t$lookup: {\n\t\t\t\t\t\tfrom: 'lineItems',\n\t\t\t\t\t\tlocalField: 'cart',\n\t\t\t\t\t\tforeignField: 'cart',\n\t\t\t\t\t\tas: 'lineItems',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{ $unwind: '$lineItems' },\n\t\t\t\t{\n\t\t\t\t\t$match: {\n\t\t\t\t\t\t'lineItems.marketings': marketingId,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$project: {\n\t\t\t\t\t\tdate: {\n\t\t\t\t\t\t\t$dateToString: {\n\t\t\t\t\t\t\t\tformat: dateFormat,\n\t\t\t\t\t\t\t\tdate: '$processedAt',\n\t\t\t\t\t\t\t\ttimezone: LyxaTimezone,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tamount: {\n\t\t\t\t\t\t\t$add: [\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t$cond: [\n\t\t\t\t\t\t\t\t\t\tmarketing.isAppliedByCompany,\n\t\t\t\t\t\t\t\t\t\t{ $ifNull: ['$lineItems.calculationSnap.itemDiscountByCompany', 0] },\n\t\t\t\t\t\t\t\t\t\t{ $ifNull: ['$lineItems.calculationSnap.itemDiscountByShop', 0] },\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t$cond: [\n\t\t\t\t\t\t\t\t\t\tmarketing.isAppliedByCompany,\n\t\t\t\t\t\t\t\t\t\t{ $ifNull: ['$lineItems.calculationSnap.b1g1DiscountByCompany', 0] },\n\t\t\t\t\t\t\t\t\t\t{ $ifNull: ['$lineItems.calculationSnap.b1g1DiscountByShop', 0] },\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$group: {\n\t\t\t\t\t\t_id: '$date',\n\t\t\t\t\t\tamount: { $sum: '$amount' },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{ $sort: { _id: 1 } },\n\t\t\t\t{\n\t\t\t\t\t$project: {\n\t\t\t\t\t\t_id: 0,\n\t\t\t\t\t\tdate: '$_id',\n\t\t\t\t\t\tamount: 1,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t];\n\t\t} else if (marketing.marketingType === MarketingType.FREE_DELIVERY) {\n\n\t\t/**\n\t\t * FREE DELIVERY\n\t\t */\n\t\t\tpipeline = [\n\t\t\t\tthis.buildBaseMatch(marketingId, {\n\t\t\t\t\tstart: data.startDate,\n\t\t\t\t\tend: data.endDate,\n\t\t\t\t}),\n\t\t\t\t{\n\t\t\t\t\t$project: {\n\t\t\t\t\t\tdate: {\n\t\t\t\t\t\t\t$dateToString: {\n\t\t\t\t\t\t\t\tformat: dateFormat,\n\t\t\t\t\t\t\t\tdate: '$processedAt',\n\t\t\t\t\t\t\t\ttimezone: LyxaTimezone,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tamount: {\n\t\t\t\t\t\t\t$cond: [\n\t\t\t\t\t\t\t\tmarketing.isAppliedByCompany,\n\t\t\t\t\t\t\t\t{ $ifNull: ['$adjustedFinance.freeDelivery.companyCut', 0] },\n\t\t\t\t\t\t\t\t{ $ifNull: ['$adjustedFinance.freeDelivery.shopCut', 0] },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$group: {\n\t\t\t\t\t\t_id: '$date',\n\t\t\t\t\t\tamount: { $sum: '$amount' },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{ $sort: { _id: 1 } },\n\t\t\t\t{\n\t\t\t\t\t$project: {\n\t\t\t\t\t\t_id: 0,\n\t\t\t\t\t\tdate: '$_id',\n\t\t\t\t\t\tamount: 1,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t];\n\t\t} else if (marketing.marketingType === MarketingType.PUNCH_MARKETING) {\n\n\t\t/**\n\t\t * PUNCH MARKETING\n\t\t */\n\t\t\tpipeline = [\n\t\t\t\tthis.buildBaseMatch(marketingId, {\n\t\t\t\t\tstart: data.startDate,\n\t\t\t\t\tend: data.endDate,\n\t\t\t\t}),\n\t\t\t\t{\n\t\t\t\t\t$project: {\n\t\t\t\t\t\tdate: {\n\t\t\t\t\t\t\t$dateToString: {\n\t\t\t\t\t\t\t\tformat: dateFormat,\n\t\t\t\t\t\t\t\tdate: '$processedAt',\n\t\t\t\t\t\t\t\ttimezone: LyxaTimezone,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t},\n\t\t\t\t\t\tamount: {\n\t\t\t\t\t\t\t$ifNull: ['$adjustedFinance.pricing.punchMarketingDiscount', 0],\n\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{\n\t\t\t\t\t$group: {\n\t\t\t\t\t\t_id: '$date',\n\t\t\t\t\t\tamount: { $sum: '$amount' },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t{ $sort: { _id: 1 } },\n\t\t\t\t{\n\t\t\t\t\t$project: {\n\t\t\t\t\t\t_id: 0,\n\t\t\t\t\t\tdate: '$_id',\n\t\t\t\t\t\tamount: 1,\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t];\n\t\t}\n\n\t\t// If marketing type doesn't produce spend graph → return empty graph\n\t\tif (!pipeline) {\n\t\t\treturn fillMissingPeriods([] as { date: string; amount: number }[], data.startDate, data.endDate, data.type, {\n\t\t\t\tamount: 0,\n\t\t\t});\n\t\t}\n\n\t\tconst results = await this.orderModel.aggregate(pipeline).allowDiskUse(true).exec();\n\n\t\treturn fillMissingPeriods(results, data.startDate, data.endDate, data.type, {\n\t\t\tamount: 0,\n\t\t});\n\t}\n}\n\nexport const marketingMetricsRepository = Container.get(MarketingMetricsRepository);\n"]}
@@ -95,6 +95,11 @@ export declare const marketingRouter: import("@trpc/server").TRPCBuiltRouter<{
95
95
  output: string;
96
96
  meta: object;
97
97
  }>;
98
+ syncAllProductsMarketingInfoLocal: import("@trpc/server").TRPCMutationProcedure<{
99
+ input: void;
100
+ output: any;
101
+ meta: object;
102
+ }>;
98
103
  syncProductMarketingInfoByProductId: import("@trpc/server").TRPCQueryProcedure<{
99
104
  input: void;
100
105
  output: string;
@@ -1 +1 @@
1
- {"version":3,"file":"marketing.router.d.ts","sourceRoot":"/","sources":["modules/marketing/routers/marketing.router.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAGhD,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAOrB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgIN,CAAC"}
1
+ {"version":3,"file":"marketing.router.d.ts","sourceRoot":"/","sources":["modules/marketing/routers/marketing.router.ts"],"names":[],"mappings":"AAsBA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAGhD,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4BAOrB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsIN,CAAC"}
@@ -55,6 +55,9 @@ exports.marketingRouter = (0, trpc_1.createTRPCRouter)({
55
55
  syncAllProductsMarketingInfo: trpc_1.publicProcedure.query(async ({}) => error_handler_1.ErrorHandler.wrapAsync(async () => {
56
56
  return await services_2.synchronizeProductMarketingService.publishAllProductsProductMarketingInfoProcessEvent();
57
57
  })),
58
+ syncAllProductsMarketingInfoLocal: trpc_1.publicProcedure.mutation(async ({}) => error_handler_1.ErrorHandler.wrapAsync(async () => {
59
+ return await services_2.synchronizeProductMarketingService.syncAllProductsMarketingInfo();
60
+ })),
58
61
  syncProductMarketingInfoByProductId: trpc_1.publicProcedure.query(async ({}) => error_handler_1.ErrorHandler.wrapAsync(async () => {
59
62
  const productId = new typegoose_1.mongoose.Types.ObjectId('68f663c355f42c826a129fc6');
60
63
  return await services_2.synchronizeProductMarketingService.syncProductMarketingInfoByProductId(productId);
@@ -1 +1 @@
1
- {"version":3,"file":"marketing.router.js","sourceRoot":"/","sources":["modules/marketing/routers/marketing.router.ts"],"names":[],"mappings":"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","sourcesContent":["import { createTRPCRouter, publicProcedure } from '@lyxa.ai/core/dist/libraries/trpc';\nimport { createAuthenticatedProcedure } from '@lyxa.ai/core/dist/libraries/trpc/middlewares/auth';\nimport { marketingService as service } from '@modules/marketing/services';\nimport { synchronizeProductMarketingService as syncMarketingProductInfoService } from '@modules/marketing/services';\nimport {\n\tAllMarketingsValidationSchema,\n\tMarketingResponseSchema as ResponseSchema,\n\tAllMarketingsUpdateSchema,\n\tProductEntireMenuMarketingHandlerSchema,\n\tMarketingSpendLimitsEvaluationSchema,\n\tSyncProductMarketingForMultipleProductsSchema,\n\tMarketingGraphInputSchema,\n} from '@modules/marketing/validations';\nimport { response } from '@lyxa.ai/core/dist/utilities/response';\nimport {\n\tFilterSchema,\n\tDeleteSchema,\n\tGetByIdInputSchema,\n\tIdSchema,\n} from '@lyxa.ai/core/dist/utilities/validation';\nimport { ErrorHandler } from '@lyxa.ai/core/dist/utilities/error-handler';\nimport { AuthEntityType } from '@lyxa.ai/core/dist/libraries/auth';\nimport { mongoose } from '@typegoose/typegoose';\nimport { marketingMetricsRepository } from '../patterns/repository/MarketingMetricsRepository';\n\nexport const marketingRouter = createTRPCRouter({\n\tcreate: createAuthenticatedProcedure({ entityTypes: [AuthEntityType.CRM, AuthEntityType.SELLER] })\n\t\t.input(AllMarketingsValidationSchema)\n\t\t.output(ResponseSchema)\n\t\t.mutation(async ({ ctx, input }) =>\n\t\t\tErrorHandler.wrapAsync(async () => {\n\t\t\t\tconst isAdmin = ctx.entity?.type == AuthEntityType.CRM;\n\t\t\t\tawait service.create(input, isAdmin ? new mongoose.Types.ObjectId(ctx.entity?.id) : undefined);\n\t\t\t\treturn response('Marketing created successfully');\n\t\t\t})\n\t\t),\n\n\tgetById: publicProcedure.input(GetByIdInputSchema).query(async ({ input }) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst result = await service.findById(input);\n\t\t\treturn response('Marketing fetched successfully', result);\n\t\t})\n\t),\n\n\tget: publicProcedure.input(FilterSchema).query(async ({ input }) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst result = await service.find(input);\n\t\t\treturn response('Marketing fetched successfully', result);\n\t\t})\n\t),\n\n\tupdate: createAuthenticatedProcedure({ entityTypes: [AuthEntityType.CRM, AuthEntityType.SELLER] })\n\t\t.input(AllMarketingsUpdateSchema)\n\t\t.output(ResponseSchema)\n\t\t.mutation(async ({ ctx, input }) =>\n\t\t\tErrorHandler.wrapAsync(async () => {\n\t\t\t\tconst { _id, ...rest } = input;\n\t\t\t\tconst isAdmin = ctx.entity?.type == AuthEntityType.CRM;\n\n\t\t\t\tawait service.update(_id, rest, isAdmin ? new mongoose.Types.ObjectId(ctx.entity?.id) : undefined);\n\t\t\t\treturn response('Marketing updated successfully');\n\t\t\t})\n\t\t),\n\n\tdeleteById: createAuthenticatedProcedure({ entityTypes: [AuthEntityType.CRM, AuthEntityType.SELLER] })\n\t\t.input(DeleteSchema)\n\t\t.output(ResponseSchema)\n\t\t.mutation(async ({ ctx, input }) =>\n\t\t\tErrorHandler.wrapAsync(async () => {\n\t\t\t\tconst isAdmin = ctx.entity?.type == AuthEntityType.CRM;\n\t\t\t\tawait service.deleteById(input, isAdmin ? new mongoose.Types.ObjectId(ctx.entity?.id) : undefined);\n\t\t\t\treturn response('Marketing deleted successfully');\n\t\t\t})\n\t\t),\n\n\thandleNewProductForEntireMenuMarketing: publicProcedure\n\t\t.input(ProductEntireMenuMarketingHandlerSchema)\n\t\t.mutation(async ({ input }) =>\n\t\t\tErrorHandler.wrapAsync(async () => {\n\t\t\t\tawait service.handleNewProductForEntireMenuMarketing(input);\n\t\t\t\treturn response('Product handled successfully');\n\t\t\t})\n\t\t),\n\n\tsyncAllProductsMarketingInfo: publicProcedure.query(async ({}) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\treturn await syncMarketingProductInfoService.publishAllProductsProductMarketingInfoProcessEvent();\n\t\t})\n\t),\n\n\tsyncProductMarketingInfoByProductId: publicProcedure.query(async ({}) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst productId = new mongoose.Types.ObjectId('68f663c355f42c826a129fc6'); // Todo: use productId sent from param\n\t\t\treturn await syncMarketingProductInfoService.syncProductMarketingInfoByProductId(productId);\n\t\t})\n\t),\n\n\tsyncProductMarketingInfoByProductIds: publicProcedure\n\t\t.input(SyncProductMarketingForMultipleProductsSchema)\n\t\t.mutation(async ({ input }) =>\n\t\t\tErrorHandler.wrapAsync(async () => {\n\t\t\t\treturn await syncMarketingProductInfoService.syncProductMarketingInfoByProductIds(input.productIds);\n\t\t\t})\n\t\t),\n\n\tcalculateMarketingSpent: publicProcedure.input(IdSchema).mutation(async ({ ctx, input }) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst result = await marketingMetricsRepository.calculateMarketingSpent(input);\n\t\t\treturn response('Marketing amount spent calculated successfully', result);\n\t\t})\n\t),\n\n\tincrementMarketingSpentFromOrder: publicProcedure.input(IdSchema).mutation(async ({ ctx, input }) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst result = await service.incrementMarketingSpentFromOrder(input);\n\t\t\treturn response('Marketing amount spent incremented successfully', result);\n\t\t})\n\t),\n\n\tdecrementMarketingSpentFromOrder: publicProcedure.input(IdSchema).mutation(async ({ ctx, input }) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst result = await service.decrementMarketingSpentFromOrder(input);\n\t\t\treturn response('Marketing amount spent decremented successfully', result);\n\t\t})\n\t),\n\n\trecomputeAndSyncAllMarketingSpent: publicProcedure.mutation(async ({}) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst result = await service.recomputeAndSyncAllMarketingSpent();\n\t\t\treturn response('Marketing amount spent recomputed and synced successfully', result);\n\t\t})\n\t),\n\n\tgetMetrics: publicProcedure.input(IdSchema).query(async ({ input }) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst result = await marketingMetricsRepository.getMetrics(input);\n\t\t\treturn response('Marketing metrics fetched successfully', result);\n\t\t})\n\t),\n\n\tgetOrdersGraph: publicProcedure.input(MarketingGraphInputSchema).query(async ({ input }) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst result = await marketingMetricsRepository.getOrdersGraph(input);\n\t\t\treturn response('Marketing orders graph data fetched successfully', result);\n\t\t})\n\t),\n\n\tgetCustomersGraph: publicProcedure.input(MarketingGraphInputSchema).query(async ({ input }) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst result = await marketingMetricsRepository.getCustomersGraph(input);\n\t\t\treturn response('Marketing customers graph data fetched successfully', result);\n\t\t})\n\t),\n\n\tgetAmountSpentGraph: publicProcedure.input(MarketingGraphInputSchema).query(async ({ input }) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst result = await marketingMetricsRepository.getAmountSpentGraph(input);\n\t\t\treturn response('Marketing amount spent graph data fetched successfully', result);\n\t\t})\n\t),\n});\n"]}
1
+ {"version":3,"file":"marketing.router.js","sourceRoot":"/","sources":["modules/marketing/routers/marketing.router.ts"],"names":[],"mappings":"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","sourcesContent":["import { createTRPCRouter, publicProcedure } from '@lyxa.ai/core/dist/libraries/trpc';\nimport { createAuthenticatedProcedure } from '@lyxa.ai/core/dist/libraries/trpc/middlewares/auth';\nimport { marketingService as service } from '@modules/marketing/services';\nimport { synchronizeProductMarketingService as syncMarketingProductInfoService } from '@modules/marketing/services';\nimport {\n\tAllMarketingsValidationSchema,\n\tMarketingResponseSchema as ResponseSchema,\n\tAllMarketingsUpdateSchema,\n\tProductEntireMenuMarketingHandlerSchema,\n\tMarketingSpendLimitsEvaluationSchema,\n\tSyncProductMarketingForMultipleProductsSchema,\n\tMarketingGraphInputSchema,\n} from '@modules/marketing/validations';\nimport { response } from '@lyxa.ai/core/dist/utilities/response';\nimport {\n\tFilterSchema,\n\tDeleteSchema,\n\tGetByIdInputSchema,\n\tIdSchema,\n} from '@lyxa.ai/core/dist/utilities/validation';\nimport { ErrorHandler } from '@lyxa.ai/core/dist/utilities/error-handler';\nimport { AuthEntityType } from '@lyxa.ai/core/dist/libraries/auth';\nimport { mongoose } from '@typegoose/typegoose';\nimport { marketingMetricsRepository } from '../patterns/repository/MarketingMetricsRepository';\n\nexport const marketingRouter = createTRPCRouter({\n\tcreate: createAuthenticatedProcedure({ entityTypes: [AuthEntityType.CRM, AuthEntityType.SELLER] })\n\t\t.input(AllMarketingsValidationSchema)\n\t\t.output(ResponseSchema)\n\t\t.mutation(async ({ ctx, input }) =>\n\t\t\tErrorHandler.wrapAsync(async () => {\n\t\t\t\tconst isAdmin = ctx.entity?.type == AuthEntityType.CRM;\n\t\t\t\tawait service.create(input, isAdmin ? new mongoose.Types.ObjectId(ctx.entity?.id) : undefined);\n\t\t\t\treturn response('Marketing created successfully');\n\t\t\t})\n\t\t),\n\n\tgetById: publicProcedure.input(GetByIdInputSchema).query(async ({ input }) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst result = await service.findById(input);\n\t\t\treturn response('Marketing fetched successfully', result);\n\t\t})\n\t),\n\n\tget: publicProcedure.input(FilterSchema).query(async ({ input }) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst result = await service.find(input);\n\t\t\treturn response('Marketing fetched successfully', result);\n\t\t})\n\t),\n\n\tupdate: createAuthenticatedProcedure({ entityTypes: [AuthEntityType.CRM, AuthEntityType.SELLER] })\n\t\t.input(AllMarketingsUpdateSchema)\n\t\t.output(ResponseSchema)\n\t\t.mutation(async ({ ctx, input }) =>\n\t\t\tErrorHandler.wrapAsync(async () => {\n\t\t\t\tconst { _id, ...rest } = input;\n\t\t\t\tconst isAdmin = ctx.entity?.type == AuthEntityType.CRM;\n\n\t\t\t\tawait service.update(_id, rest, isAdmin ? new mongoose.Types.ObjectId(ctx.entity?.id) : undefined);\n\t\t\t\treturn response('Marketing updated successfully');\n\t\t\t})\n\t\t),\n\n\tdeleteById: createAuthenticatedProcedure({ entityTypes: [AuthEntityType.CRM, AuthEntityType.SELLER] })\n\t\t.input(DeleteSchema)\n\t\t.output(ResponseSchema)\n\t\t.mutation(async ({ ctx, input }) =>\n\t\t\tErrorHandler.wrapAsync(async () => {\n\t\t\t\tconst isAdmin = ctx.entity?.type == AuthEntityType.CRM;\n\t\t\t\tawait service.deleteById(input, isAdmin ? new mongoose.Types.ObjectId(ctx.entity?.id) : undefined);\n\t\t\t\treturn response('Marketing deleted successfully');\n\t\t\t})\n\t\t),\n\n\thandleNewProductForEntireMenuMarketing: publicProcedure\n\t\t.input(ProductEntireMenuMarketingHandlerSchema)\n\t\t.mutation(async ({ input }) =>\n\t\t\tErrorHandler.wrapAsync(async () => {\n\t\t\t\tawait service.handleNewProductForEntireMenuMarketing(input);\n\t\t\t\treturn response('Product handled successfully');\n\t\t\t})\n\t\t),\n\n\tsyncAllProductsMarketingInfo: publicProcedure.query(async ({}) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\treturn await syncMarketingProductInfoService.publishAllProductsProductMarketingInfoProcessEvent();\n\t\t})\n\t),\n\n\tsyncAllProductsMarketingInfoLocal: publicProcedure.mutation(async ({}) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\treturn await syncMarketingProductInfoService.syncAllProductsMarketingInfo();\n\t\t})\n\t),\n\n\tsyncProductMarketingInfoByProductId: publicProcedure.query(async ({}) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst productId = new mongoose.Types.ObjectId('68f663c355f42c826a129fc6'); // Todo: use productId sent from param\n\t\t\treturn await syncMarketingProductInfoService.syncProductMarketingInfoByProductId(productId);\n\t\t})\n\t),\n\n\tsyncProductMarketingInfoByProductIds: publicProcedure\n\t\t.input(SyncProductMarketingForMultipleProductsSchema)\n\t\t.mutation(async ({ input }) =>\n\t\t\tErrorHandler.wrapAsync(async () => {\n\t\t\t\treturn await syncMarketingProductInfoService.syncProductMarketingInfoByProductIds(input.productIds);\n\t\t\t})\n\t\t),\n\n\tcalculateMarketingSpent: publicProcedure.input(IdSchema).mutation(async ({ ctx, input }) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst result = await marketingMetricsRepository.calculateMarketingSpent(input);\n\t\t\treturn response('Marketing amount spent calculated successfully', result);\n\t\t})\n\t),\n\n\tincrementMarketingSpentFromOrder: publicProcedure.input(IdSchema).mutation(async ({ ctx, input }) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst result = await service.incrementMarketingSpentFromOrder(input);\n\t\t\treturn response('Marketing amount spent incremented successfully', result);\n\t\t})\n\t),\n\n\tdecrementMarketingSpentFromOrder: publicProcedure.input(IdSchema).mutation(async ({ ctx, input }) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst result = await service.decrementMarketingSpentFromOrder(input);\n\t\t\treturn response('Marketing amount spent decremented successfully', result);\n\t\t})\n\t),\n\n\trecomputeAndSyncAllMarketingSpent: publicProcedure.mutation(async ({}) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst result = await service.recomputeAndSyncAllMarketingSpent();\n\t\t\treturn response('Marketing amount spent recomputed and synced successfully', result);\n\t\t})\n\t),\n\n\tgetMetrics: publicProcedure.input(IdSchema).query(async ({ input }) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst result = await marketingMetricsRepository.getMetrics(input);\n\t\t\treturn response('Marketing metrics fetched successfully', result);\n\t\t})\n\t),\n\n\tgetOrdersGraph: publicProcedure.input(MarketingGraphInputSchema).query(async ({ input }) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst result = await marketingMetricsRepository.getOrdersGraph(input);\n\t\t\treturn response('Marketing orders graph data fetched successfully', result);\n\t\t})\n\t),\n\n\tgetCustomersGraph: publicProcedure.input(MarketingGraphInputSchema).query(async ({ input }) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst result = await marketingMetricsRepository.getCustomersGraph(input);\n\t\t\treturn response('Marketing customers graph data fetched successfully', result);\n\t\t})\n\t),\n\n\tgetAmountSpentGraph: publicProcedure.input(MarketingGraphInputSchema).query(async ({ input }) =>\n\t\tErrorHandler.wrapAsync(async () => {\n\t\t\tconst result = await marketingMetricsRepository.getAmountSpentGraph(input);\n\t\t\treturn response('Marketing amount spent graph data fetched successfully', result);\n\t\t})\n\t),\n});\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"synchronize-product-marketing.service.d.ts","sourceRoot":"/","sources":["modules/marketing/services/synchronize-product-marketing.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAKhD,OAAO,EAAE,6CAA6C,EAAE,MAAM,0FAA0F,CAAC;AACzJ,qBACa,kCAAkC;IAC9C,OAAO,CAAC,YAAY,CAA+C;;IAMtD,kDAAkD;IAKxD,2CAA2C,CACjD,OAAO,EAAE,6CAA6C,GACpD,MAAM;IAKF,4BAA4B,QAAa,OAAO,CAAC,GAAG,CAAC,CAsD1D;YAEY,oBAAoB;YAsDpB,kCAAkC;IAqCnC,mCAAmC,CAAC,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ;IAsCtE,oCAAoC,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE;CA+CvF;AAED,eAAO,MAAM,kCAAkC,oCAAoD,CAAC"}
1
+ {"version":3,"file":"synchronize-product-marketing.service.d.ts","sourceRoot":"/","sources":["modules/marketing/services/synchronize-product-marketing.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAKhD,OAAO,EAAE,6CAA6C,EAAE,MAAM,0FAA0F,CAAC;AACzJ,qBACa,kCAAkC;IAC9C,OAAO,CAAC,YAAY,CAA+C;;IAMtD,kDAAkD;IAKxD,2CAA2C,CACjD,OAAO,EAAE,6CAA6C,GACpD,MAAM;IAKF,4BAA4B,QAAa,OAAO,CAAC,GAAG,CAAC,CAsD1D;YAEY,oBAAoB;YAsDpB,kCAAkC;IAqCnC,mCAAmC,CAAC,SAAS,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ;IAsCtE,oCAAoC,CAAC,UAAU,EAAE,QAAQ,CAAC,KAAK,CAAC,QAAQ,EAAE;CAgFvF;AAED,eAAO,MAAM,kCAAkC,oCAAoD,CAAC"}
@@ -200,19 +200,37 @@ let SynchronizeProductMarketingService = class SynchronizeProductMarketingServic
200
200
  return 'Synchronized product marketing info';
201
201
  }
202
202
  async syncProductMarketingInfoByProductIds(productIds) {
203
+ console.time('SYNC_PRODUCT_IDS_TIME');
204
+ console.log(`Starting sync for ${productIds.length} product IDs`);
203
205
  if (!productIds.length)
204
206
  return 'No products to sync';
205
207
  const adminSettings = (await (0, core_1.getLibraries)().getCachedSettingsService().getSettings());
206
208
  const exchangeRate = adminSettings?.currencySetting?.exchangeRate ?? 0;
207
209
  const secondaryCurrencyName = adminSettings?.currencySetting?.secondaryCurrency?.name ?? 'LBP';
208
- const results = await this.productModel.aggregate([
209
- {
210
- $match: {
211
- _id: { $in: productIds },
210
+ const BATCH_SIZE = 500;
211
+ const results = [];
212
+ const totalBatches = Math.ceil(productIds.length / BATCH_SIZE);
213
+ console.time('[ProductAggregate] Total Execution');
214
+ for (let i = 0; i < productIds.length; i += BATCH_SIZE) {
215
+ const batchIndex = i / BATCH_SIZE + 1;
216
+ const batchIds = productIds.slice(i, i + BATCH_SIZE);
217
+ const label = `[ProductAggregate] Batch ${batchIndex}/${totalBatches}`;
218
+ console.log(`${label} → starting (${batchIds.length} ids)`);
219
+ console.time(label);
220
+ const batchResults = await this.productModel.aggregate([
221
+ {
222
+ $match: {
223
+ _id: { $in: batchIds },
224
+ },
212
225
  },
213
- },
214
- ...(0, product_pipeline_stages_1.addProductMarketingInfo)(exchangeRate, secondaryCurrencyName),
215
- ]);
226
+ ...(0, product_pipeline_stages_1.addProductMarketingInfo)(exchangeRate, secondaryCurrencyName),
227
+ ]);
228
+ console.timeEnd(label);
229
+ console.log(`${label} → completed (${batchResults.length} docs)`);
230
+ results.push(...batchResults);
231
+ }
232
+ console.timeEnd('[ProductAggregate] Total Execution');
233
+ console.log(`[ProductAggregate] Total results: ${results.length}`);
216
234
  if (!results.length)
217
235
  return 'No matching products found';
218
236
  const bulkOps = results.map(product => {
@@ -237,7 +255,10 @@ let SynchronizeProductMarketingService = class SynchronizeProductMarketingServic
237
255
  },
238
256
  };
239
257
  });
258
+ console.timeEnd('SYNC_PRODUCT_IDS_TIME');
259
+ console.time('BULK_WRITE_TIME');
240
260
  await this.productModel.bulkWrite(bulkOps);
261
+ console.timeEnd('BULK_WRITE_TIME');
241
262
  return `Synchronized product marketing info for ${bulkOps.length} products`;
242
263
  }
243
264
  };
@@ -1 +1 @@
1
- {"version":3,"file":"synchronize-product-marketing.service.js","sourceRoot":"/","sources":["modules/marketing/services/synchronize-product-marketing.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, { Service } from 'typedi';\nimport { getLibraries } from '@lyxa.ai/core';\nimport { mongoose } from '@typegoose/typegoose';\nimport { SoftDeleteModel } from '@lyxa.ai/core/dist/libraries/mongo/plugins/soft-delete-plugin';\nimport { ProductModel, Product as Model, Setting } from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport { addProductMarketingInfo } from '@lyxa.ai/core/dist/utilities/pipelines/product-pipeline-stages';\nimport { publishAllProductsProductMarketingInfoProcessEvent } from '@lyxa.ai/core/dist/utilities/events-common-methods';\nimport { SynchronizeAllProductsProductMarketingInfoDTO } from '@lyxa.ai/core/dist/libraries/event/events/sync-all-products-product-marketing-info-event';\n@Service()\nexport class SynchronizeProductMarketingService {\n\tprivate productModel: typeof ProductModel & SoftDeleteModel<Model>;\n\n\tconstructor() {\n\t\tthis.productModel = ProductModel as typeof ProductModel & SoftDeleteModel<Model>;\n\t}\n\n\tpublic async publishAllProductsProductMarketingInfoProcessEvent() {\n\t\tawait publishAllProductsProductMarketingInfoProcessEvent({});\n\t\treturn 'Processing all products product marketing information! ';\n\t}\n\n\tpublic processAllProductsProductMarketingInfoEvent(\n\t\tpayload: SynchronizeAllProductsProductMarketingInfoDTO\n\t): string {\n\t\tthis.syncAllProductsMarketingInfo();\n\t\treturn 'Processing all products product marketing information! ';\n\t}\n\n\tpublic syncAllProductsMarketingInfo = async (): Promise<any> => {\n\t\tconst CHUNK_SIZE = 500;\n\n\t\tconsole.time('TOTAL_SYNC_TIME');\n\t\tconsole.log('[SYNC] Starting product marketing info sync');\n\n\t\tconst cursor = this.productModel.find().select('_id shop price priceBreakdowns').lean().cursor();\n\n\t\tconst adminSettings = (await getLibraries().getCachedSettingsService().getSettings()) as Setting;\n\n\t\tconst exchangeRate = adminSettings?.currencySetting?.exchangeRate ?? 0;\n\t\tconst secondaryCurrencyName = adminSettings?.currencySetting?.secondaryCurrency?.name ?? 'LBP';\n\n\t\tlet batch: any[] = [];\n\t\tlet batchIndex = 0;\n\t\tlet totalProcessed = 0;\n\n\t\tfor await (const product of cursor) {\n\t\t\tbatch.push(product);\n\n\t\t\tif (batch.length === CHUNK_SIZE) {\n\t\t\t\tbatchIndex++;\n\t\t\t\ttotalProcessed += batch.length;\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t`[SYNC][BATCH ${batchIndex}] Processing ${batch.length} products (Total processed: ${totalProcessed})`\n\t\t\t\t);\n\n\t\t\t\tconsole.time(`[BATCH ${batchIndex}] TIME`);\n\t\t\t\tawait this.processProductsBatch(batch, exchangeRate, secondaryCurrencyName, batchIndex);\n\t\t\t\tconsole.timeEnd(`[BATCH ${batchIndex}] TIME`);\n\n\t\t\t\tbatch = [];\n\t\t\t}\n\t\t}\n\n\t\t// Process remaining products\n\t\tif (batch.length) {\n\t\t\tbatchIndex++;\n\t\t\ttotalProcessed += batch.length;\n\n\t\t\tconsole.log(\n\t\t\t\t`[SYNC][BATCH ${batchIndex}] Processing remaining ${batch.length} products (Total processed: ${totalProcessed})`\n\t\t\t);\n\n\t\t\tconsole.time(`[BATCH ${batchIndex}] TIME`);\n\t\t\tawait this.processProductsBatch(batch, exchangeRate, secondaryCurrencyName, batchIndex);\n\t\t\tconsole.timeEnd(`[BATCH ${batchIndex}] TIME`);\n\t\t}\n\n\t\tconsole.log(`[SYNC] Completed. Total batches: ${batchIndex}, Total products: ${totalProcessed}`);\n\t\tconsole.timeEnd('TOTAL_SYNC_TIME');\n\n\t\treturn 'Bulk product marketing info sync completed';\n\t};\n\n\tprivate async processProductsBatch(\n\t\tproductsBatch: any[],\n\t\texchangeRate: number,\n\t\tsecondaryCurrencyName: string,\n\t\tbatchIndex: number\n\t): Promise<void> {\n\t\tconst productIds = productsBatch.map(p => p._id);\n\n\t\tconsole.log(\n\t\t\t`[BATCH ${batchIndex}] Aggregating marketing info for ${productIds.length} products`,\n\t\t\t`| First ID: ${productIds[0]}`,\n\t\t\t`| Last ID: ${productIds[productIds.length - 1]}`\n\t\t);\n\n\t\tconst results = await this.productModel.aggregate([\n\t\t\t{ $match: { _id: { $in: productIds } } },\n\t\t\t...addProductMarketingInfo(exchangeRate, secondaryCurrencyName),\n\t\t\t{\n\t\t\t\t$group: {\n\t\t\t\t\t_id: '$_id',\n\t\t\t\t\tproductMarketingInfo: { $push: '$productMarketing' },\n\t\t\t\t},\n\t\t\t},\n\t\t]);\n\n\t\tconsole.log(`[BATCH ${batchIndex}] Aggregation completed. Result count: ${results.length}`);\n\n\t\tconst bulkOps = results.map(r => ({\n\t\t\tupdateOne: {\n\t\t\t\tfilter: { _id: r._id },\n\t\t\t\tupdate: {\n\t\t\t\t\t$set: {\n\t\t\t\t\t\tproductMarketingInfo: (r.productMarketingInfo ?? []).filter(Boolean).map((pm: any) => ({\n\t\t\t\t\t\t\tmarketing: pm.marketingInfo,\n\t\t\t\t\t\t\tisBuy1Get1: pm.isBuy1Get1,\n\t\t\t\t\t\t\tvalueType: pm.valueType,\n\t\t\t\t\t\t\tvalue: pm.value,\n\t\t\t\t\t\t\tsecondaryCurrencyValue: pm.secondaryCurrencyValue,\n\t\t\t\t\t\t\tlabel: pm.label,\n\t\t\t\t\t\t})),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}));\n\n\t\tif (bulkOps.length) {\n\t\t\tconsole.log(`[BATCH ${batchIndex}] bulkWrite started (${bulkOps.length} ops)`);\n\t\t\tawait this.productModel.bulkWrite(bulkOps, { ordered: false });\n\t\t\tconsole.log(`[BATCH ${batchIndex}] bulkWrite completed`);\n\t\t} else {\n\t\t\tconsole.log(`[BATCH ${batchIndex}] No bulk operations to write`);\n\t\t}\n\t}\n\n\tprivate async getProductMarketingInfoByProductId(productId: mongoose.Types.ObjectId): Promise<any[]> {\n\t\tconst adminSettings = (await getLibraries().getCachedSettingsService().getSettings()) as Setting;\n\n\t\tconst exchangeRate = adminSettings?.currencySetting?.exchangeRate ?? 0;\n\t\tconst secondaryCurrencyName = adminSettings?.currencySetting?.secondaryCurrency?.name ?? 'LBP';\n\n\t\tconst result = await this.productModel.aggregate([\n\t\t\t{\n\t\t\t\t$match: { _id: productId },\n\t\t\t},\n\t\t\t...addProductMarketingInfo(exchangeRate, secondaryCurrencyName),\n\t\t\t{\n\t\t\t\t$group: {\n\t\t\t\t\t_id: '$_id',\n\t\t\t\t\tproductMarketingInfo: {\n\t\t\t\t\t\t$push: '$productMarketing',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t]);\n\n\t\tconst productMarketingInfo = result?.[0]?.productMarketing\n\t\t\t? [\n\t\t\t\t\t{\n\t\t\t\t\t\tmarketing: result?.[0].productMarketing.marketingInfo,\n\t\t\t\t\t\tisBuy1Get1: result?.[0].productMarketing.isBuy1Get1,\n\t\t\t\t\t\tvalueType: result?.[0].productMarketing.valueType,\n\t\t\t\t\t\tvalue: result?.[0].productMarketing.value,\n\t\t\t\t\t\tsecondaryCurrencyValue: result?.[0].productMarketing.secondaryCurrencyValue,\n\t\t\t\t\t\tlabel: result?.[0].productMarketing.label,\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t\t: [];\n\n\t\treturn productMarketingInfo;\n\t}\n\n\tpublic async syncProductMarketingInfoByProductId(productId: mongoose.Types.ObjectId) {\n\t\tconst adminSettings = (await getLibraries().getCachedSettingsService().getSettings()) as Setting;\n\t\tconst exchangeRate = adminSettings?.currencySetting?.exchangeRate ?? 0;\n\n\t\tconst secondaryCurrencyName = adminSettings?.currencySetting?.secondaryCurrency?.name ?? 'LBP';\n\t\tconst result = await this.productModel.aggregate([\n\t\t\t{\n\t\t\t\t$match: {\n\t\t\t\t\t_id: productId,\n\t\t\t\t},\n\t\t\t},\n\t\t\t...addProductMarketingInfo(exchangeRate, secondaryCurrencyName),\n\t\t]);\n\n\t\tconst productMarketingInfo = result?.[0]?.productMarketing\n\t\t\t? [\n\t\t\t\t\t{\n\t\t\t\t\t\tmarketing: result?.[0].productMarketing.marketingInfo,\n\t\t\t\t\t\tisBuy1Get1: result?.[0].productMarketing.isBuy1Get1,\n\t\t\t\t\t\tvalueType: result?.[0].productMarketing.valueType,\n\t\t\t\t\t\tvalue: result?.[0].productMarketing.value,\n\t\t\t\t\t\tsecondaryCurrencyValue: result?.[0].productMarketing.secondaryCurrencyValue,\n\t\t\t\t\t\tlabel: result?.[0].productMarketing.label,\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t\t: [];\n\n\t\tawait this.productModel.updateOne(\n\t\t\t{ _id: productId },\n\t\t\t{\n\t\t\t\t$set: {\n\t\t\t\t\tproductMarketingInfo,\n\t\t\t\t},\n\t\t\t}\n\t\t);\n\t\treturn 'Synchronized product marketing info';\n\t}\n\n\tpublic async syncProductMarketingInfoByProductIds(productIds: mongoose.Types.ObjectId[]) {\n\t\tif (!productIds.length) return 'No products to sync';\n\n\t\tconst adminSettings = (await getLibraries().getCachedSettingsService().getSettings()) as Setting;\n\n\t\tconst exchangeRate = adminSettings?.currencySetting?.exchangeRate ?? 0;\n\t\tconst secondaryCurrencyName = adminSettings?.currencySetting?.secondaryCurrency?.name ?? 'LBP';\n\n\t\tconst results = await this.productModel.aggregate([\n\t\t\t{\n\t\t\t\t$match: {\n\t\t\t\t\t_id: { $in: productIds },\n\t\t\t\t},\n\t\t\t},\n\t\t\t...addProductMarketingInfo(exchangeRate, secondaryCurrencyName),\n\t\t]);\n\n\t\tif (!results.length) return 'No matching products found';\n\n\t\tconst bulkOps = results.map(product => {\n\t\t\tconst productMarketingInfo = product?.productMarketing\n\t\t\t\t? [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmarketing: product.productMarketing.marketingInfo,\n\t\t\t\t\t\t\tisBuy1Get1: product.productMarketing.isBuy1Get1,\n\t\t\t\t\t\t\tvalueType: product.productMarketing.valueType,\n\t\t\t\t\t\t\tvalue: product.productMarketing.value,\n\t\t\t\t\t\t\tsecondaryCurrencyValue: product.productMarketing.secondaryCurrencyValue,\n\t\t\t\t\t\t\tlabel: product.productMarketing.label,\n\t\t\t\t\t\t},\n\t\t\t\t\t]\n\t\t\t\t: [];\n\n\t\t\treturn {\n\t\t\t\tupdateOne: {\n\t\t\t\t\tfilter: { _id: product._id },\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\t$set: { productMarketingInfo },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t};\n\t\t});\n\n\t\tawait this.productModel.bulkWrite(bulkOps);\n\n\t\treturn `Synchronized product marketing info for ${bulkOps.length} products`;\n\t}\n}\n\nexport const synchronizeProductMarketingService = Container.get(SynchronizeProductMarketingService);\n"]}
1
+ {"version":3,"file":"synchronize-product-marketing.service.js","sourceRoot":"/","sources":["modules/marketing/services/synchronize-product-marketing.service.ts"],"names":[],"mappings":"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","sourcesContent":["import Container, { Service } from 'typedi';\nimport { getLibraries } from '@lyxa.ai/core';\nimport { mongoose } from '@typegoose/typegoose';\nimport { SoftDeleteModel } from '@lyxa.ai/core/dist/libraries/mongo/plugins/soft-delete-plugin';\nimport { ProductModel, Product as Model, Setting } from '@lyxa.ai/core/dist/libraries/mongo/models';\nimport { addProductMarketingInfo } from '@lyxa.ai/core/dist/utilities/pipelines/product-pipeline-stages';\nimport { publishAllProductsProductMarketingInfoProcessEvent } from '@lyxa.ai/core/dist/utilities/events-common-methods';\nimport { SynchronizeAllProductsProductMarketingInfoDTO } from '@lyxa.ai/core/dist/libraries/event/events/sync-all-products-product-marketing-info-event';\n@Service()\nexport class SynchronizeProductMarketingService {\n\tprivate productModel: typeof ProductModel & SoftDeleteModel<Model>;\n\n\tconstructor() {\n\t\tthis.productModel = ProductModel as typeof ProductModel & SoftDeleteModel<Model>;\n\t}\n\n\tpublic async publishAllProductsProductMarketingInfoProcessEvent() {\n\t\tawait publishAllProductsProductMarketingInfoProcessEvent({});\n\t\treturn 'Processing all products product marketing information! ';\n\t}\n\n\tpublic processAllProductsProductMarketingInfoEvent(\n\t\tpayload: SynchronizeAllProductsProductMarketingInfoDTO\n\t): string {\n\t\tthis.syncAllProductsMarketingInfo();\n\t\treturn 'Processing all products product marketing information! ';\n\t}\n\n\tpublic syncAllProductsMarketingInfo = async (): Promise<any> => {\n\t\tconst CHUNK_SIZE = 500;\n\n\t\tconsole.time('TOTAL_SYNC_TIME');\n\t\tconsole.log('[SYNC] Starting product marketing info sync');\n\n\t\tconst cursor = this.productModel.find().select('_id shop price priceBreakdowns').lean().cursor();\n\n\t\tconst adminSettings = (await getLibraries().getCachedSettingsService().getSettings()) as Setting;\n\n\t\tconst exchangeRate = adminSettings?.currencySetting?.exchangeRate ?? 0;\n\t\tconst secondaryCurrencyName = adminSettings?.currencySetting?.secondaryCurrency?.name ?? 'LBP';\n\n\t\tlet batch: any[] = [];\n\t\tlet batchIndex = 0;\n\t\tlet totalProcessed = 0;\n\n\t\tfor await (const product of cursor) {\n\t\t\tbatch.push(product);\n\n\t\t\tif (batch.length === CHUNK_SIZE) {\n\t\t\t\tbatchIndex++;\n\t\t\t\ttotalProcessed += batch.length;\n\n\t\t\t\tconsole.log(\n\t\t\t\t\t`[SYNC][BATCH ${batchIndex}] Processing ${batch.length} products (Total processed: ${totalProcessed})`\n\t\t\t\t);\n\n\t\t\t\tconsole.time(`[BATCH ${batchIndex}] TIME`);\n\t\t\t\tawait this.processProductsBatch(batch, exchangeRate, secondaryCurrencyName, batchIndex);\n\t\t\t\tconsole.timeEnd(`[BATCH ${batchIndex}] TIME`);\n\n\t\t\t\tbatch = [];\n\t\t\t}\n\t\t}\n\n\t\t// Process remaining products\n\t\tif (batch.length) {\n\t\t\tbatchIndex++;\n\t\t\ttotalProcessed += batch.length;\n\n\t\t\tconsole.log(\n\t\t\t\t`[SYNC][BATCH ${batchIndex}] Processing remaining ${batch.length} products (Total processed: ${totalProcessed})`\n\t\t\t);\n\n\t\t\tconsole.time(`[BATCH ${batchIndex}] TIME`);\n\t\t\tawait this.processProductsBatch(batch, exchangeRate, secondaryCurrencyName, batchIndex);\n\t\t\tconsole.timeEnd(`[BATCH ${batchIndex}] TIME`);\n\t\t}\n\n\t\tconsole.log(`[SYNC] Completed. Total batches: ${batchIndex}, Total products: ${totalProcessed}`);\n\t\tconsole.timeEnd('TOTAL_SYNC_TIME');\n\n\t\treturn 'Bulk product marketing info sync completed';\n\t};\n\n\tprivate async processProductsBatch(\n\t\tproductsBatch: any[],\n\t\texchangeRate: number,\n\t\tsecondaryCurrencyName: string,\n\t\tbatchIndex: number\n\t): Promise<void> {\n\t\tconst productIds = productsBatch.map(p => p._id);\n\n\t\tconsole.log(\n\t\t\t`[BATCH ${batchIndex}] Aggregating marketing info for ${productIds.length} products`,\n\t\t\t`| First ID: ${productIds[0]}`,\n\t\t\t`| Last ID: ${productIds[productIds.length - 1]}`\n\t\t);\n\n\t\tconst results = await this.productModel.aggregate([\n\t\t\t{ $match: { _id: { $in: productIds } } },\n\t\t\t...addProductMarketingInfo(exchangeRate, secondaryCurrencyName),\n\t\t\t{\n\t\t\t\t$group: {\n\t\t\t\t\t_id: '$_id',\n\t\t\t\t\tproductMarketingInfo: { $push: '$productMarketing' },\n\t\t\t\t},\n\t\t\t},\n\t\t]);\n\n\t\tconsole.log(`[BATCH ${batchIndex}] Aggregation completed. Result count: ${results.length}`);\n\n\t\tconst bulkOps = results.map(r => ({\n\t\t\tupdateOne: {\n\t\t\t\tfilter: { _id: r._id },\n\t\t\t\tupdate: {\n\t\t\t\t\t$set: {\n\t\t\t\t\t\tproductMarketingInfo: (r.productMarketingInfo ?? []).filter(Boolean).map((pm: any) => ({\n\t\t\t\t\t\t\tmarketing: pm.marketingInfo,\n\t\t\t\t\t\t\tisBuy1Get1: pm.isBuy1Get1,\n\t\t\t\t\t\t\tvalueType: pm.valueType,\n\t\t\t\t\t\t\tvalue: pm.value,\n\t\t\t\t\t\t\tsecondaryCurrencyValue: pm.secondaryCurrencyValue,\n\t\t\t\t\t\t\tlabel: pm.label,\n\t\t\t\t\t\t})),\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t}));\n\n\t\tif (bulkOps.length) {\n\t\t\tconsole.log(`[BATCH ${batchIndex}] bulkWrite started (${bulkOps.length} ops)`);\n\t\t\tawait this.productModel.bulkWrite(bulkOps, { ordered: false });\n\t\t\tconsole.log(`[BATCH ${batchIndex}] bulkWrite completed`);\n\t\t} else {\n\t\t\tconsole.log(`[BATCH ${batchIndex}] No bulk operations to write`);\n\t\t}\n\t}\n\n\tprivate async getProductMarketingInfoByProductId(productId: mongoose.Types.ObjectId): Promise<any[]> {\n\t\tconst adminSettings = (await getLibraries().getCachedSettingsService().getSettings()) as Setting;\n\n\t\tconst exchangeRate = adminSettings?.currencySetting?.exchangeRate ?? 0;\n\t\tconst secondaryCurrencyName = adminSettings?.currencySetting?.secondaryCurrency?.name ?? 'LBP';\n\n\t\tconst result = await this.productModel.aggregate([\n\t\t\t{\n\t\t\t\t$match: { _id: productId },\n\t\t\t},\n\t\t\t...addProductMarketingInfo(exchangeRate, secondaryCurrencyName),\n\t\t\t{\n\t\t\t\t$group: {\n\t\t\t\t\t_id: '$_id',\n\t\t\t\t\tproductMarketingInfo: {\n\t\t\t\t\t\t$push: '$productMarketing',\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t},\n\t\t]);\n\n\t\tconst productMarketingInfo = result?.[0]?.productMarketing\n\t\t\t? [\n\t\t\t\t\t{\n\t\t\t\t\t\tmarketing: result?.[0].productMarketing.marketingInfo,\n\t\t\t\t\t\tisBuy1Get1: result?.[0].productMarketing.isBuy1Get1,\n\t\t\t\t\t\tvalueType: result?.[0].productMarketing.valueType,\n\t\t\t\t\t\tvalue: result?.[0].productMarketing.value,\n\t\t\t\t\t\tsecondaryCurrencyValue: result?.[0].productMarketing.secondaryCurrencyValue,\n\t\t\t\t\t\tlabel: result?.[0].productMarketing.label,\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t\t: [];\n\n\t\treturn productMarketingInfo;\n\t}\n\n\tpublic async syncProductMarketingInfoByProductId(productId: mongoose.Types.ObjectId) {\n\t\tconst adminSettings = (await getLibraries().getCachedSettingsService().getSettings()) as Setting;\n\t\tconst exchangeRate = adminSettings?.currencySetting?.exchangeRate ?? 0;\n\n\t\tconst secondaryCurrencyName = adminSettings?.currencySetting?.secondaryCurrency?.name ?? 'LBP';\n\t\tconst result = await this.productModel.aggregate([\n\t\t\t{\n\t\t\t\t$match: {\n\t\t\t\t\t_id: productId,\n\t\t\t\t},\n\t\t\t},\n\t\t\t...addProductMarketingInfo(exchangeRate, secondaryCurrencyName),\n\t\t]);\n\n\t\tconst productMarketingInfo = result?.[0]?.productMarketing\n\t\t\t? [\n\t\t\t\t\t{\n\t\t\t\t\t\tmarketing: result?.[0].productMarketing.marketingInfo,\n\t\t\t\t\t\tisBuy1Get1: result?.[0].productMarketing.isBuy1Get1,\n\t\t\t\t\t\tvalueType: result?.[0].productMarketing.valueType,\n\t\t\t\t\t\tvalue: result?.[0].productMarketing.value,\n\t\t\t\t\t\tsecondaryCurrencyValue: result?.[0].productMarketing.secondaryCurrencyValue,\n\t\t\t\t\t\tlabel: result?.[0].productMarketing.label,\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t\t: [];\n\n\t\tawait this.productModel.updateOne(\n\t\t\t{ _id: productId },\n\t\t\t{\n\t\t\t\t$set: {\n\t\t\t\t\tproductMarketingInfo,\n\t\t\t\t},\n\t\t\t}\n\t\t);\n\t\treturn 'Synchronized product marketing info';\n\t}\n\n\tpublic async syncProductMarketingInfoByProductIds(productIds: mongoose.Types.ObjectId[]) {\n\t\tconsole.time('SYNC_PRODUCT_IDS_TIME');\n\t\tconsole.log(`Starting sync for ${productIds.length} product IDs`); // Debug log\n\t\tif (!productIds.length) return 'No products to sync';\n\n\t\tconst adminSettings = (await getLibraries().getCachedSettingsService().getSettings()) as Setting;\n\n\t\tconst exchangeRate = adminSettings?.currencySetting?.exchangeRate ?? 0;\n\t\tconst secondaryCurrencyName = adminSettings?.currencySetting?.secondaryCurrency?.name ?? 'LBP';\n\n\t\tconst BATCH_SIZE = 500;\n\t\tconst results: any[] = [];\n\n\t\tconst totalBatches = Math.ceil(productIds.length / BATCH_SIZE);\n\n\t\tconsole.time('[ProductAggregate] Total Execution');\n\n\t\tfor (let i = 0; i < productIds.length; i += BATCH_SIZE) {\n\t\t\tconst batchIndex = i / BATCH_SIZE + 1;\n\t\t\tconst batchIds = productIds.slice(i, i + BATCH_SIZE);\n\n\t\t\tconst label = `[ProductAggregate] Batch ${batchIndex}/${totalBatches}`;\n\n\t\t\tconsole.log(`${label} → starting (${batchIds.length} ids)`);\n\t\t\tconsole.time(label);\n\n\t\t\tconst batchResults = await this.productModel.aggregate([\n\t\t\t\t{\n\t\t\t\t\t$match: {\n\t\t\t\t\t\t_id: { $in: batchIds },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t\t...addProductMarketingInfo(exchangeRate, secondaryCurrencyName),\n\t\t\t]);\n\n\t\t\tconsole.timeEnd(label);\n\t\t\tconsole.log(`${label} → completed (${batchResults.length} docs)`);\n\n\t\t\tresults.push(...batchResults);\n\t\t}\n\n\t\tconsole.timeEnd('[ProductAggregate] Total Execution');\n\n\t\tconsole.log(`[ProductAggregate] Total results: ${results.length}`);\n\n\t\tif (!results.length) return 'No matching products found';\n\n\t\tconst bulkOps = results.map(product => {\n\t\t\tconst productMarketingInfo = product?.productMarketing\n\t\t\t\t? [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tmarketing: product.productMarketing.marketingInfo,\n\t\t\t\t\t\t\tisBuy1Get1: product.productMarketing.isBuy1Get1,\n\t\t\t\t\t\t\tvalueType: product.productMarketing.valueType,\n\t\t\t\t\t\t\tvalue: product.productMarketing.value,\n\t\t\t\t\t\t\tsecondaryCurrencyValue: product.productMarketing.secondaryCurrencyValue,\n\t\t\t\t\t\t\tlabel: product.productMarketing.label,\n\t\t\t\t\t\t},\n\t\t\t\t\t]\n\t\t\t\t: [];\n\n\t\t\treturn {\n\t\t\t\tupdateOne: {\n\t\t\t\t\tfilter: { _id: product._id },\n\t\t\t\t\tupdate: {\n\t\t\t\t\t\t$set: { productMarketingInfo },\n\t\t\t\t\t},\n\t\t\t\t},\n\t\t\t};\n\t\t});\n\n\t\tconsole.timeEnd('SYNC_PRODUCT_IDS_TIME');\n\n\t\tconsole.time('BULK_WRITE_TIME');\n\t\tawait this.productModel.bulkWrite(bulkOps);\n\n\t\tconsole.timeEnd('BULK_WRITE_TIME');\n\n\t\treturn `Synchronized product marketing info for ${bulkOps.length} products`;\n\t}\n}\n\nexport const synchronizeProductMarketingService = Container.get(SynchronizeProductMarketingService);\n"]}