@darkpos/pricing 1.0.128 → 1.0.129

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.
@@ -24,8 +24,9 @@ describe('Is valid Modifier', () => {
24
24
  },
25
25
  },
26
26
  };
27
- const isPromoValid =
28
- pricingService.modifier.isModifierValid(mockPromoModifier);
27
+ const isPromoValid = pricingService.modifier.isModifierValid({
28
+ modifier: mockPromoModifier,
29
+ });
29
30
 
30
31
  expect(isPromoValid).toBe(false);
31
32
  });
@@ -50,9 +51,91 @@ describe('Is valid Modifier', () => {
50
51
  },
51
52
  },
52
53
  };
53
- const isPromoValid =
54
- pricingService.modifier.isModifierValid(mockPromoModifier);
54
+ const isPromoValid = pricingService.modifier.isModifierValid({
55
+ modifier: mockPromoModifier,
56
+ });
55
57
 
56
58
  expect(isPromoValid).toBe(true);
57
59
  });
60
+
61
+ test('should return false when customer usage reached per-customer limit', () => {
62
+ const now = moment();
63
+ const mockPromoModifier = {
64
+ attributes: ['promotion'],
65
+ name: 'Per-Customer Limited Promo',
66
+ sku: '#CUSLIMIT',
67
+ properties: {
68
+ promotion: {
69
+ numberOfUses: 10,
70
+ numberOfUsesCustomerLimit: 2,
71
+ customerIds: ['cust-1', 'cust-1', 'cust-2'],
72
+ dateLimit: {
73
+ from: now.clone().subtract(1, 'day').format('YYYY-MM-DD'),
74
+ to: now.clone().add(1, 'day').format('YYYY-MM-DD'),
75
+ },
76
+ },
77
+ },
78
+ };
79
+
80
+ const isValid = pricingService.modifier.isModifierValid({
81
+ modifier: mockPromoModifier,
82
+ customer: { _id: 'cust-1' },
83
+ });
84
+
85
+ expect(isValid).toBe(false);
86
+ });
87
+
88
+ test('should return true when customer usage is below per-customer limit', () => {
89
+ const now = moment();
90
+ const mockPromoModifier = {
91
+ attributes: ['promotion'],
92
+ name: 'Per-Customer Limited Promo',
93
+ sku: '#CUSLIMIT2',
94
+ properties: {
95
+ promotion: {
96
+ numberOfUses: 5,
97
+ numberOfUsesCustomerLimit: 3,
98
+ customerIds: ['cust-1', 'cust-2', 'cust-1'],
99
+ dateLimit: {
100
+ from: now.clone().subtract(1, 'day').format('YYYY-MM-DD'),
101
+ to: now.clone().add(1, 'day').format('YYYY-MM-DD'),
102
+ },
103
+ },
104
+ },
105
+ };
106
+
107
+ const isValid = pricingService.modifier.isModifierValid({
108
+ modifier: mockPromoModifier,
109
+ customer: { _id: 'cust-1' },
110
+ });
111
+
112
+ expect(isValid).toBe(true);
113
+ });
114
+
115
+ test('should return true when per-customer limit exists but no customer provided', () => {
116
+ const now = moment();
117
+ const mockPromoModifier = {
118
+ attributes: ['promotion'],
119
+ name: 'Per-Customer Limited Promo (No Customer)',
120
+ sku: '#CUSLIMIT3',
121
+ properties: {
122
+ promotion: {
123
+ numberOfUses: 0,
124
+ numberOfUsesCustomerLimit: 1,
125
+ customerIds: [],
126
+ dateLimit: {
127
+ from: now.clone().subtract(1, 'day').format('YYYY-MM-DD'),
128
+ to: now.clone().add(1, 'day').format('YYYY-MM-DD'),
129
+ },
130
+ },
131
+ },
132
+ };
133
+
134
+ const isValid = pricingService.modifier.isModifierValid({
135
+ modifier: mockPromoModifier,
136
+ // customer omitted on purpose
137
+ });
138
+
139
+ expect(isValid).toBe(true);
140
+ });
58
141
  });
@@ -0,0 +1,11 @@
1
+ module.exports = ({ actions }) =>
2
+ function getCountPerCustomer({ modifier, customerId }) {
3
+ if (!actions.isPromotion(modifier)) return 0;
4
+
5
+ const customerIds = actions.getPromoCustomerIds(modifier) || [];
6
+
7
+ return customerIds.reduce(
8
+ (count, id) => (id === customerId ? count + 1 : count),
9
+ 0
10
+ );
11
+ };
@@ -0,0 +1,5 @@
1
+ module.exports = ({ actions, _ }) =>
2
+ function getMaxUsesPerCustomer(modifier) {
3
+ if (!actions.isPromotion(modifier)) return 0;
4
+ return _.get(modifier, 'properties.promotion.numberOfUsesCustomerLimit', 0);
5
+ };
@@ -0,0 +1,5 @@
1
+ module.exports = ({ actions, _ }) =>
2
+ function getPromoCustomerIds(modifier) {
3
+ if (!actions.isPromotion(modifier)) return [];
4
+ return _.get(modifier, 'properties.promotion.customerIds', []);
5
+ };
@@ -15,8 +15,6 @@ const duplicate = require('./duplicate');
15
15
  const enableAutoPopup = require('./enableAutoPopup');
16
16
  const filterByRequiredModifiers = require('./filterByRequiredModifiers');
17
17
  const findById = require('./findById');
18
- const getAvailablePromotions = require('./getAvailablePromotions');
19
- const getAvailablePromotionsOrSubscriptions = require('./getAvailablePromotionsOrSubscriptions');
20
18
  const getAvailableSubscriptions = require('./getAvailableSubscriptions');
21
19
  const getByAttribute = require('./getByAttribute');
22
20
  const getCreditModifier = require('./getCreditModifier');
@@ -29,7 +27,6 @@ const getDirectModifiers = require('./getDirectModifiers');
29
27
  const getDescriptions = require('./getDescriptions');
30
28
  const getEntityModifiers = require('./getEntityModifiers');
31
29
  const getExtendedTags = require('./getExtendedTags');
32
- const getEntityPromotions = require('./getEntityPromotions');
33
30
  const getGroupOfItemsModifiers = require('./getGroupOfItemsModifiers');
34
31
  const getGroupRelatedModifiers = require('./getGroupRelatedModifiers');
35
32
  const getGroupModifiers = require('./getGroupModifiers');
@@ -179,6 +176,9 @@ const isSplitDepartment = require('./isSplitDepartment');
179
176
  const isModifierValid = require('./isModifierValid');
180
177
  const markModifierAsNotValid = require('./markModifierAsNotValid');
181
178
  const isEmptyOverride = require('./isEmptyOverride');
179
+ const getMaxUsesPerCustomer = require('./getMaxUsesPerCustomer');
180
+ const getPromoCustomerIds = require('./getPromoCustomerIds');
181
+ const getCountPerCustomer = require('./getCountPerCustomer');
182
182
 
183
183
  const modifierActions = (deps = {}) => {
184
184
  const actions = {};
@@ -205,9 +205,6 @@ const modifierActions = (deps = {}) => {
205
205
  enableAutoPopup: enableAutoPopup(innerDeps),
206
206
  filterByRequiredModifiers: filterByRequiredModifiers(innerDeps),
207
207
  findById: findById(innerDeps),
208
- getAvailablePromotions: getAvailablePromotions(innerDeps),
209
- getAvailablePromotionsOrSubscriptions:
210
- getAvailablePromotionsOrSubscriptions(innerDeps),
211
208
  getAvailableSubscriptions: getAvailableSubscriptions(innerDeps),
212
209
  getByAttribute: getByAttribute(innerDeps),
213
210
  getCreditModifier: getCreditModifier(innerDeps),
@@ -220,7 +217,6 @@ const modifierActions = (deps = {}) => {
220
217
  getDefaultModifiers: getDefaultModifiers(innerDeps),
221
218
  getEntityModifiers: getEntityModifiers(innerDeps),
222
219
  getExtendedTags: getExtendedTags(innerDeps),
223
- getEntityPromotions: getEntityPromotions(innerDeps),
224
220
  getGroupRelatedModifiers: getGroupRelatedModifiers(innerDeps),
225
221
  getGroupModifiers: getGroupModifiers(innerDeps),
226
222
  getGroupOfItemsModifiers: getGroupOfItemsModifiers(innerDeps),
@@ -371,6 +367,9 @@ const modifierActions = (deps = {}) => {
371
367
  isModifierValid: isModifierValid(innerDeps),
372
368
  markModifierAsNotValid: markModifierAsNotValid(innerDeps),
373
369
  isEmptyOverride: isEmptyOverride(innerDeps),
370
+ getMaxUsesPerCustomer: getMaxUsesPerCustomer(innerDeps),
371
+ getPromoCustomerIds: getPromoCustomerIds(innerDeps),
372
+ getCountPerCustomer: getCountPerCustomer(innerDeps),
374
373
  });
375
374
 
376
375
  Object.keys(freezedActions).forEach(actionName => {
@@ -1,7 +1,7 @@
1
1
  module.exports = ({ utils, actions }) => {
2
2
  const { date, math } = utils;
3
3
 
4
- return function isAvailablePromotion(modifier) {
4
+ return function isAvailablePromotion({ modifier, customer }) {
5
5
  if (!actions.isPromotion(modifier)) return false;
6
6
 
7
7
  const { promotion } = modifier.properties || {};
@@ -15,6 +15,16 @@ module.exports = ({ utils, actions }) => {
15
15
  )
16
16
  return false;
17
17
 
18
+ const maxUsesPerCustomer = actions.getMaxUsesPerCustomer(modifier);
19
+
20
+ if (maxUsesPerCustomer && customer && customer._id) {
21
+ const customerCount = actions.getCountPerCustomer({
22
+ modifier,
23
+ customerId: customer._id,
24
+ });
25
+ if (math.gte(customerCount, maxUsesPerCustomer)) return false;
26
+ }
27
+
18
28
  if (promotion.dateLimit && !date.isBetween(promotion.dateLimit))
19
29
  return false;
20
30
 
@@ -1,8 +1,8 @@
1
1
  module.exports = ({ actions }) =>
2
- function isModifierValid(modifier) {
2
+ function isModifierValid({ modifier, customer }) {
3
3
  // Promotion modifiers
4
4
  if (actions.isPromotion(modifier)) {
5
- return actions.isAvailablePromotion(modifier);
5
+ return actions.isAvailablePromotion({ modifier, customer });
6
6
  }
7
7
 
8
8
  // Add more modifier checks here ...
@@ -23,7 +23,7 @@ module.exports = ({ actions, itemActions, modifierActions, utils, _ }) => {
23
23
  }
24
24
 
25
25
  // Check if Modifier is Valid/Available
26
- if (!modifierActions.isModifierValid(_modifier)) {
26
+ if (!modifierActions.isModifierValid({ modifier: _modifier, customer })) {
27
27
  if (onError) onError('modifier.has.reached.the.maximum.of.uses');
28
28
  return itemProp;
29
29
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darkpos/pricing",
3
- "version": "1.0.128",
3
+ "version": "1.0.129",
4
4
  "description": "Pricing calculator",
5
5
  "author": "Dark POS",
6
6
  "license": "ISC",
@@ -52,5 +52,5 @@
52
52
  "supertest": "^6.2.3",
53
53
  "supervisor": "^0.12.0"
54
54
  },
55
- "gitHead": "8246fe8ba99264f6428a8fa725fb951b49961c95"
55
+ "gitHead": "958c254c252446558919666dfd3c524e5ec3acb5"
56
56
  }
@@ -1,81 +0,0 @@
1
- const usePricing = require('../../index');
2
-
3
- const pricingService = usePricing();
4
-
5
- describe('GetAvailablePromotionsOrSubscriptions Function', () => {
6
- test('usecases', () => {
7
- const today = new Date();
8
- expect(
9
- pricingService.modifier.getAvailablePromotionsOrSubscriptions()
10
- ).toStrictEqual([]);
11
-
12
- const modifier = { attributes: ['promotion'] };
13
- expect(
14
- pricingService.modifier.getAvailablePromotionsOrSubscriptions([modifier])
15
- ).toStrictEqual([modifier]);
16
-
17
- modifier.properties = {
18
- promotion: { numberOfUsesLimit: 4, numberOfUses: 3 },
19
- };
20
- expect(
21
- pricingService.modifier.getAvailablePromotionsOrSubscriptions([modifier])
22
- ).toStrictEqual([modifier]);
23
-
24
- modifier.properties.promotion.numberOfUses = 4;
25
- expect(
26
- pricingService.modifier.getAvailablePromotionsOrSubscriptions([modifier])
27
- ).toStrictEqual([]);
28
-
29
- modifier.properties.promotion.numberOfUses = 5;
30
- expect(
31
- pricingService.modifier.getAvailablePromotionsOrSubscriptions([modifier])
32
- ).toStrictEqual([]);
33
-
34
- modifier.properties = {
35
- promotion: { dateLimit: { from: today.toISOString(), to: '' } },
36
- };
37
- expect(
38
- pricingService.modifier.getAvailablePromotionsOrSubscriptions([modifier])
39
- ).toStrictEqual([modifier]);
40
-
41
- const tomorrow = new Date(today);
42
- tomorrow.setDate(tomorrow.getDate() + 1);
43
- modifier.properties.promotion.dateLimit.from = tomorrow.toISOString();
44
- expect(
45
- pricingService.modifier.getAvailablePromotionsOrSubscriptions([modifier])
46
- ).toStrictEqual([]);
47
-
48
- const yesterday = new Date(today);
49
- yesterday.setDate(yesterday.getDate() - 1);
50
- modifier.properties.promotion.dateLimit.from = yesterday.toISOString();
51
- expect(
52
- pricingService.modifier.getAvailablePromotionsOrSubscriptions([modifier])
53
- ).toStrictEqual([modifier]);
54
-
55
- modifier.properties.promotion.dateLimit.to = yesterday.toISOString();
56
- expect(
57
- pricingService.modifier.getAvailablePromotionsOrSubscriptions([modifier])
58
- ).toStrictEqual([]);
59
-
60
- modifier.properties.promotion.dateLimit.to = today.toISOString();
61
- expect(
62
- pricingService.modifier.getAvailablePromotionsOrSubscriptions([modifier])
63
- ).toStrictEqual([modifier]);
64
-
65
- modifier.properties.promotion.dateLimit.to = tomorrow.toISOString();
66
- expect(
67
- pricingService.modifier.getAvailablePromotionsOrSubscriptions([modifier])
68
- ).toStrictEqual([modifier]);
69
-
70
- modifier.attributes = ['subscription'];
71
- modifier.properties.subscription = modifier.properties.promotion;
72
- expect(
73
- pricingService.modifier.getAvailablePromotionsOrSubscriptions([modifier])
74
- ).toStrictEqual([modifier]);
75
-
76
- delete modifier.properties;
77
- expect(
78
- pricingService.modifier.getAvailablePromotionsOrSubscriptions([modifier])
79
- ).toStrictEqual([]);
80
- });
81
- });
@@ -1,5 +0,0 @@
1
- module.exports = ({ actions }) =>
2
- function getAvailablePromotions(modifiers) {
3
- if (!Array.isArray(modifiers)) return [];
4
- return modifiers.filter(each => actions.isAvailablePromotion(each));
5
- };
@@ -1,15 +0,0 @@
1
- module.exports = ({ actions }) =>
2
- /*
3
- * This function will receive a list of promotion modifiers and filter them by the limits that we have for promotions
4
- * Filters are:
5
- * modifier.properties.promotion.dateLimit.{from, to} which compares today with these two dates
6
- * modifier.properties.promotion.numberOfUsesLimit which will be checked with modifier.properties.promotion.numberOfUses
7
- */
8
- function getAvailablePromotionsOrSubscriptions(modifiers) {
9
- if (!Array.isArray(modifiers)) return [];
10
- return modifiers.filter(
11
- each =>
12
- actions.isAvailableSubscription(each) ||
13
- actions.isAvailablePromotion(each)
14
- );
15
- };
@@ -1,11 +0,0 @@
1
- module.exports = ({ actions }) =>
2
- function getEntityPromotions({ modifiers, entity }) {
3
- if (!entity) return [];
4
- let entityModifiers = actions.getMatchTagsModifiers({
5
- modifiers,
6
- entity,
7
- });
8
- entityModifiers = actions.getUnhiddenModifiers(entityModifiers);
9
- const promotions = actions.getAvailablePromotions(entityModifiers);
10
- return promotions;
11
- };