@darkpos/pricing 1.0.136 → 1.0.138

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/lib/index.js CHANGED
@@ -9,6 +9,7 @@ const makeItemActions = require('./item');
9
9
  const makeOrderActions = require('./order');
10
10
  const makeModifierActions = require('./modifier');
11
11
  const makePaymentActions = require('./payment');
12
+ const makeInvoiceActions = require('./invoice');
12
13
 
13
14
  const constants = require('./constants');
14
15
 
@@ -50,12 +51,22 @@ module.exports = session => {
50
51
  storeActions,
51
52
  });
52
53
 
54
+ const invoiceActions = makeInvoiceActions({
55
+ ...deps,
56
+ itemActions,
57
+ modifierActions,
58
+ orderActions,
59
+ storeActions,
60
+ paymentActions,
61
+ });
62
+
53
63
  return {
54
64
  item: itemActions,
55
65
  order: orderActions,
56
66
  modifier: modifierActions,
57
67
  store: storeActions,
58
68
  payment: paymentActions,
69
+ invoice: invoiceActions,
59
70
  constants,
60
71
  };
61
72
  };
@@ -0,0 +1,22 @@
1
+ module.exports = ({ utils, _ }) =>
2
+ function getStatusByItems({ items }) {
3
+ const { math } = utils;
4
+ if (!Array.isArray(items) || items.length === 0) return 'pending';
5
+
6
+ const totalPaid = items.reduce(
7
+ (total, item) => math.add(total, item.totalPaid),
8
+ 0
9
+ );
10
+ const isInvoicePaid = items.every(
11
+ item => !!_.get(item, 'status.paid.value', false)
12
+ );
13
+ const isInvoicePartialPaid =
14
+ !isInvoicePaid &&
15
+ items.some(item => !!_.get(item, 'status.paid.value', false));
16
+
17
+ if (isInvoicePaid) return 'paid';
18
+ if (isInvoicePartialPaid || (!isInvoicePartialPaid && totalPaid > 0))
19
+ return 'partial';
20
+
21
+ return 'pending';
22
+ };
@@ -0,0 +1,12 @@
1
+ module.exports = ({ utils }) =>
2
+ function getTotalByItems({ items }) {
3
+ const { math } = utils;
4
+ if (!Array.isArray(items) || items.length === 0) return 0;
5
+
6
+ const total = items.reduce(
7
+ (itemsTotal, item) => math.add(itemsTotal, item.total),
8
+ 0
9
+ );
10
+
11
+ return total;
12
+ };
@@ -0,0 +1,24 @@
1
+ const getStatusByItems = require('./getStatusByItems');
2
+ const getTotalByItems = require('./getTotalByItems');
3
+
4
+ const invoiceActions = (deps = {}) => {
5
+ const actions = {};
6
+
7
+ const innerDeps = {
8
+ ...deps,
9
+ actions,
10
+ };
11
+
12
+ const freezedActions = Object.freeze({
13
+ getStatusByItems: getStatusByItems(innerDeps),
14
+ getTotalByItems: getTotalByItems(innerDeps),
15
+ });
16
+
17
+ Object.keys(freezedActions).forEach(actionName => {
18
+ actions[actionName] = freezedActions[actionName];
19
+ });
20
+
21
+ return freezedActions;
22
+ };
23
+
24
+ module.exports = invoiceActions;
@@ -0,0 +1,22 @@
1
+ module.exports = () =>
2
+ function applyPayment({ paymentOrderItems, orderItem }) {
3
+ const itemOption = paymentOrderItems.find(
4
+ ({ orderItemId }) => String(orderItemId) === String(orderItem._id)
5
+ );
6
+
7
+ if (!itemOption) return orderItem;
8
+
9
+ const item = orderItem;
10
+
11
+ const paid =
12
+ itemOption.status && itemOption.status.paid && itemOption.status.paid;
13
+
14
+ return {
15
+ ...item,
16
+ status: {
17
+ ...item.status,
18
+ ...itemOption.status,
19
+ paid,
20
+ },
21
+ };
22
+ };
@@ -8,8 +8,11 @@ module.exports = ({ _, utils, actions, modifierActions }) => {
8
8
  ...inputItem,
9
9
  quantity: math.max(0, Number(inputItem.quantity) || 0),
10
10
  });
11
- const amountToPay =
12
- typeof opts.amountToPay === 'number' ? opts.amountToPay : 0;
11
+ const amountToPay = actions.getAmountToPayById({
12
+ amountsToPay: opts.amountsToPay,
13
+ id: inputItem._id,
14
+ });
15
+
13
16
  const paymentMethod = opts.paymentMethod || null;
14
17
  const paymentType = opts.paymentType || null;
15
18
  const isPrepay = opts.isPrepay || false;
@@ -148,16 +151,19 @@ module.exports = ({ _, utils, actions, modifierActions }) => {
148
151
  let _modifier = modifier;
149
152
 
150
153
  if (modifierActions.isPaymentModifier(modifier)) {
154
+ const balance = actions.getBalanceForPaymentModifier({
155
+ item,
156
+ computedPrice,
157
+ modifier,
158
+ });
159
+
151
160
  _modifier = modifierActions.calculatePaymentModifier({
152
161
  paymentModifier: modifier,
153
162
  amountToPay:
154
163
  accumulatedAmount < 0 && amountToPay > 0
155
164
  ? math.add(amountToPay, math.abs(accumulatedAmount))
156
165
  : amountToPay,
157
- itemBalance:
158
- typeof item.totalPaid === 'number' && item.totalPaid > 0
159
- ? actions.getItemsBalance({ items: [item] })
160
- : math.sub(computedPrice, item.totalPaid),
166
+ itemBalance: math.max(0, balance),
161
167
  paymentId,
162
168
  });
163
169
  }
@@ -255,7 +261,7 @@ module.exports = ({ _, utils, actions, modifierActions }) => {
255
261
  modifiers: [...modifiersToNotCompute, ...modifiers],
256
262
  subTotals,
257
263
  total,
258
- status: actions.getUpdatedStatus({ status: item.status, total }),
264
+ ...(item.status || {}),
259
265
  };
260
266
  };
261
267
 
@@ -0,0 +1,6 @@
1
+ module.exports = () =>
2
+ function getAmountToPayById({ amountsToPay, id }) {
3
+ if (!amountsToPay) return 0;
4
+
5
+ return amountsToPay[id] || 0;
6
+ };
@@ -0,0 +1,30 @@
1
+ module.exports = ({ utils, actions, modifierActions }) => {
2
+ const { math } = utils;
3
+ return function getBalanceForPaymentModifier({
4
+ item,
5
+ computedPrice,
6
+ modifier,
7
+ }) {
8
+ let balance =
9
+ typeof item.totalPaid === 'number' && item.totalPaid > 0
10
+ ? actions.getItemsBalance({ items: [item] })
11
+ : math.sub(computedPrice, item.totalPaid);
12
+
13
+ const modifiersAmount = item.modifiers.reduce((amount, mod) => {
14
+ if (
15
+ modifierActions.isCalculatedPaymentModifier(mod) &&
16
+ mod.locked &&
17
+ modifier.modifierId === mod.modifierId
18
+ ) {
19
+ return math.add(amount, mod._computed.amount);
20
+ }
21
+ return amount;
22
+ }, 0);
23
+
24
+ if (modifiersAmount > 0) {
25
+ balance = math.sub(balance, modifiersAmount);
26
+ }
27
+
28
+ return balance;
29
+ };
30
+ };
@@ -0,0 +1,29 @@
1
+ module.exports = ({ actions, settings }) =>
2
+ function getPaidStatus({
3
+ status,
4
+ total: totalParam,
5
+ totalPaid: totalPaidParam,
6
+ }) {
7
+ const localStatus = status || {};
8
+
9
+ const total = totalParam || 0;
10
+ const totalPaid = totalPaidParam || 0;
11
+
12
+ if (
13
+ actions.isPaid({ item: { status: localStatus } }) &&
14
+ total !== 0 &&
15
+ total > totalPaid
16
+ ) {
17
+ return undefined;
18
+ }
19
+
20
+ if (!settings || !settings.order || !settings.order.autoMarkAsPaid) {
21
+ return localStatus.paid;
22
+ }
23
+
24
+ if (!actions.isPaid({ item: { status: localStatus } }) && total === 0) {
25
+ return { value: true, date: new Date() };
26
+ }
27
+
28
+ return localStatus.paid;
29
+ };
package/lib/item/index.js CHANGED
@@ -59,7 +59,7 @@ const getSubtotal = require('./getSubtotal');
59
59
  const isSomeTagsMatch = require('./isSomeTagsMatch');
60
60
  const getTotals = require('./getTotals');
61
61
  const patchItem = require('./patchItem');
62
- const getUpdatedStatus = require('./getUpdatedStatus');
62
+ const getPaidStatus = require('./getPaidStatus');
63
63
  const isOverwrittenPrice = require('./isOverwrittenPrice');
64
64
  const isOverwrittenQuantity = require('./isOverwrittenQuantity');
65
65
  const overrideNotes = require('./overrideNotes');
@@ -78,6 +78,9 @@ const hasRelatedItems = require('./hasRelatedItems');
78
78
  const getAddModifiers = require('./getAddModifiers');
79
79
  const hasAddModifiers = require('./hasAddModifiers');
80
80
  const getTaxes = require('./getTaxes');
81
+ const getAmountToPayById = require('./getAmountToPayById');
82
+ const applyPayment = require('./applyPayment');
83
+ const getBalanceForPaymentModifier = require('./getBalanceForPaymentModifier');
81
84
 
82
85
  const itemActions = (deps = {}) => {
83
86
  const actions = {};
@@ -150,7 +153,7 @@ const itemActions = (deps = {}) => {
150
153
  isSomeTagsMatch: isSomeTagsMatch(innerDeps),
151
154
  getTotals: getTotals(innerDeps),
152
155
  patchItem: patchItem(innerDeps),
153
- getUpdatedStatus: getUpdatedStatus(innerDeps),
156
+ getPaidStatus: getPaidStatus(innerDeps),
154
157
  isOverwrittenPrice: isOverwrittenPrice(innerDeps),
155
158
  isOverwrittenQuantity: isOverwrittenQuantity(innerDeps),
156
159
  overrideNotes: overrideNotes(innerDeps),
@@ -169,6 +172,9 @@ const itemActions = (deps = {}) => {
169
172
  getAddModifiers: getAddModifiers(innerDeps),
170
173
  hasAddModifiers: hasAddModifiers(innerDeps),
171
174
  getTaxes: getTaxes(innerDeps),
175
+ getAmountToPayById: getAmountToPayById(innerDeps),
176
+ applyPayment: applyPayment(innerDeps),
177
+ getBalanceForPaymentModifier: getBalanceForPaymentModifier(innerDeps),
172
178
  });
173
179
 
174
180
  Object.keys(freezedActions).forEach(actionName => {
@@ -5,7 +5,9 @@ module.exports = ({ actions, modifierActions }) =>
5
5
  const localItem = { ...item };
6
6
 
7
7
  const modifierIndex = item.modifiers.findIndex(
8
- mod => modifierActions.isPercentage(mod) || !modifierActions.isDirect(mod)
8
+ mod =>
9
+ modifierActions.isValid(mod) &&
10
+ (modifierActions.isPercentage(mod) || !modifierActions.isDirect(mod))
9
11
  );
10
12
 
11
13
  localItem.modifiers[modifierIndex] = modifierActions.patchModifier({
@@ -1,25 +1,8 @@
1
1
  module.exports = ({ actions }) =>
2
- /* checks if the customer can be matched with the entity or not,
3
- * This function will return true in these conditions:
4
- * Neither customer nor the entity has any tags
5
- * Customer has no tags and entity has the 'all' tag
6
- * customer has the 'all' tag and entity has no tags
7
- * customer and entity have at least one exact tag (case-sensitive)
8
- * In any other case the function should return false
9
- * */
10
2
  function hasMatchTags(modifier, entity) {
11
3
  const entityNoTags = actions.hasNoTags(entity);
12
4
  const modifierNoTags = actions.hasNoTags(modifier);
13
- if (
14
- (modifierNoTags && entityNoTags) ||
15
- (entityNoTags && actions.hasAllTag(modifier)) || // customer has no tags but modifier has the all tag
16
- (modifierNoTags && actions.hasAllTag(entity)) // modifier has no tags but customer has the all tag
17
- ) {
18
- return true;
19
- }
20
-
21
- if (!entity || !entity.tags) return false;
22
- if (!modifier || !modifier.tags) return false;
5
+ if (modifierNoTags || entityNoTags) return true;
23
6
 
24
7
  const sameTag = modifier.tags.find(tag => entity.tags.includes(tag));
25
8
 
@@ -9,6 +9,10 @@ module.exports = ({ utils, actions }) =>
9
9
  difference
10
10
  );
11
11
 
12
+ modifier.properties = {
13
+ ...(modifier.properties || {}),
14
+ };
15
+
12
16
  modifier._computed.description = actions.createDescription({
13
17
  modifier: {
14
18
  ...modifier,
@@ -126,8 +126,9 @@ module.exports = ({
126
126
  !itemActions.isPaid(item) &&
127
127
  item.modifiers.some(
128
128
  mod =>
129
- modifierActions.isPercentage(mod) ||
130
- !modifierActions.isDirect(mod)
129
+ modifierActions.isValid(mod) &&
130
+ (modifierActions.isPercentage(mod) ||
131
+ !modifierActions.isDirect(mod))
131
132
  )
132
133
  );
133
134
 
@@ -153,13 +154,56 @@ module.exports = ({
153
154
  const pieceCount = calculatedItems.length
154
155
  ? itemActions.getItemsTotalPieces(calculatedItems)
155
156
  : order.properties.pieceCount;
157
+
158
+ calculatedItems = calculatedItems.map(calcItem => {
159
+ let itemTotalPaid = calcItem.totalPaid;
160
+
161
+ const amountToPay = itemActions.getAmountToPayById({
162
+ amountsToPay: opts.amountsToPay,
163
+ id: calcItem._id,
164
+ });
165
+ if (amountToPay) {
166
+ itemTotalPaid = utils.math.add(itemTotalPaid, amountToPay);
167
+ }
168
+ return {
169
+ ...calcItem,
170
+ totalPaid: itemTotalPaid,
171
+ status: {
172
+ ...calcItem.status,
173
+ paid: itemActions.getPaidStatus({
174
+ status: calcItem.status,
175
+ total: calcItem.total,
176
+ totalPaid: itemTotalPaid,
177
+ }),
178
+ },
179
+ };
180
+ });
181
+
182
+ const totalPaid = itemActions.getItemsTotalPaid({
183
+ orderItems: calculatedItems,
184
+ });
185
+
186
+ const picked = actions.getPickedStatus({ items: calculatedItems });
187
+ const paid = actions.getPaidStatus({
188
+ items: calculatedItems,
189
+ status: order.status,
190
+ total,
191
+ totalPaid,
192
+ });
193
+
156
194
  return {
157
195
  ...order,
158
196
  subTotals,
159
197
  subTotal,
160
198
  total,
161
199
  items: calculatedItems,
162
- status: actions.getUpdatedStatus({ status: order.status, total }),
200
+ status: {
201
+ ...(order.status || {}),
202
+ picked,
203
+ paid,
204
+ order: picked && paid ? 'closed' : 'open',
205
+ },
206
+ totalPaid,
163
207
  properties: {
164
208
  ...(order.properties || {}),
165
209
  pieceCount,
@@ -0,0 +1,36 @@
1
+ module.exports = ({ actions, itemActions }) =>
2
+ function calculateWithPayment({
3
+ order,
4
+ paymentOrderItems,
5
+ paymentMethod,
6
+ paymentType,
7
+ isPrepay,
8
+ paymentId,
9
+ }) {
10
+ const amountsToPay = paymentOrderItems
11
+ .filter(each => order.items.find(item => each.orderItemId === item._id))
12
+ .reduce(
13
+ (prevVal, val) => ({
14
+ ...prevVal,
15
+ [val.orderItemId]: val.amount,
16
+ }),
17
+ {}
18
+ );
19
+
20
+ return actions.calculate(
21
+ {
22
+ ...order,
23
+ items: order.items.map(orderItem =>
24
+ itemActions.applyPayment({ paymentOrderItems, orderItem })
25
+ ),
26
+ },
27
+ {
28
+ paymentMethod,
29
+ paymentType,
30
+ isPrepay,
31
+ amountsToPay,
32
+ lockPaymentModifiers: true,
33
+ paymentId,
34
+ }
35
+ );
36
+ };
@@ -0,0 +1,35 @@
1
+ module.exports = ({ actions, settings, _ }) =>
2
+ function getPaidStatus({
3
+ items,
4
+ status,
5
+ total: totalParam,
6
+ totalPaid: totalPaidParam,
7
+ }) {
8
+ const localStatus = status || {};
9
+
10
+ const total = totalParam || 0;
11
+ const totalPaid = totalPaidParam || 0;
12
+
13
+ const areAllItemsPaid = items.every(
14
+ item => !!_.get(item, 'status.paid.value', false)
15
+ );
16
+
17
+ if (areAllItemsPaid) return true;
18
+
19
+ if (
20
+ actions.isPaid({ order: { status: localStatus } }) &&
21
+ total !== 0 &&
22
+ total > totalPaid
23
+ ) {
24
+ return false;
25
+ }
26
+
27
+ if (!settings || !settings.order || !settings.order.autoMarkAsPaid)
28
+ return !!localStatus.paid;
29
+
30
+ if (!actions.isPaid({ order: { status: localStatus } }) && total === 0) {
31
+ return true;
32
+ }
33
+
34
+ return !!localStatus.paid;
35
+ };
@@ -0,0 +1,4 @@
1
+ module.exports = ({ _ }) =>
2
+ function getPickedStatus({ items }) {
3
+ return items.every(item => !!_.get(item, 'status.picked.value', false));
4
+ };
@@ -90,13 +90,15 @@ const splitItems = require('./splitItems');
90
90
  const getNewItems = require('./getNewItems');
91
91
  const mapSubOrders = require('./mapSubOrders');
92
92
  const isPaid = require('./isPaid');
93
- const getUpdatedStatus = require('./getUpdatedStatus');
93
+ const getPaidStatus = require('./getPaidStatus');
94
94
  const setPieces = require('./setPieces');
95
95
  const copyItemToParents = require('./copyItemToParents');
96
96
  const getItemsWithParents = require('./getItemsWithParents');
97
97
  const addModifiersToParentItem = require('./addModifiersToParentItem');
98
98
  const removeEmptyNotes = require('./removeEmptyNotes');
99
99
  const getTaxes = require('./getTaxes');
100
+ const getPickedStatus = require('./getPickedStatus');
101
+ const calculateWithPayment = require('./calculateWithPayment');
100
102
 
101
103
  const orderActions = (deps = {}) => {
102
104
  const actions = {};
@@ -198,13 +200,15 @@ const orderActions = (deps = {}) => {
198
200
  getNewItems: getNewItems(innerDeps),
199
201
  mapSubOrders: mapSubOrders(innerDeps),
200
202
  isPaid: isPaid(innerDeps),
201
- getUpdatedStatus: getUpdatedStatus(innerDeps),
203
+ getPaidStatus: getPaidStatus(innerDeps),
202
204
  setPieces: setPieces(innerDeps),
203
205
  copyItemToParents: copyItemToParents(innerDeps),
204
206
  getItemsWithParents: getItemsWithParents(innerDeps),
205
207
  addModifiersToParentItem: addModifiersToParentItem(innerDeps),
206
208
  removeEmptyNotes: removeEmptyNotes(innerDeps),
207
209
  getTaxes: getTaxes(innerDeps),
210
+ getPickedStatus: getPickedStatus(innerDeps),
211
+ calculateWithPayment: calculateWithPayment(innerDeps),
208
212
  });
209
213
 
210
214
  Object.keys(freezedActions).forEach(actionName => {
File without changes
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@darkpos/pricing",
3
- "version": "1.0.136",
3
+ "version": "1.0.138",
4
4
  "description": "Pricing calculator",
5
5
  "author": "Dark POS",
6
6
  "license": "ISC",
@@ -31,13 +31,14 @@
31
31
  "test:overrideModifiers": "jest --runInBand --detectOpenHandles --logHeapUsage --forceExit ./__TEST__/modifier/overrideModifiers.test.js",
32
32
  "test:addItemModifier": "jest --runInBand --detectOpenHandles --logHeapUsage --forceExit ./__TEST__/modifier/addItemModifier.test.js",
33
33
  "test:payment": "jest --runInBand --detectOpenHandles --logHeapUsage --forceExit ./__TEST__/payment.test.js",
34
+ "test:orderPaymentModifier": "jest --runInBand --detectOpenHandles --logHeapUsage --forceExit ./__TEST__/order/order-payment-modifier.test.js",
34
35
  "lint": "eslint --quiet lib/"
35
36
  },
36
37
  "publishConfig": {
37
38
  "access": "public"
38
39
  },
39
40
  "dependencies": {
40
- "@darkpos/utils": "^1.0.13",
41
+ "@darkpos/utils": "^1.0.14",
41
42
  "crypto-js": "^4.2.0",
42
43
  "lodash": "^4.17.21",
43
44
  "moment-timezone": "^0.5.34"
@@ -52,5 +53,5 @@
52
53
  "supertest": "^6.2.3",
53
54
  "supervisor": "^0.12.0"
54
55
  },
55
- "gitHead": "9e4e2bf0729c8be75468d488d0199d2d74ec0139"
56
+ "gitHead": "95d90c9dccaf934d7d4a8adc8e46115e90b81664"
56
57
  }
@@ -1,17 +0,0 @@
1
- module.exports = ({ actions, settings }) =>
2
- function getUpdatedStatus({ status, total }) {
3
- if (!settings || !settings.order || !settings.order.autoMarkAsPaid)
4
- return status;
5
-
6
- const localStatus = status || {};
7
-
8
- if (actions.isPaid({ item: { status: localStatus } }) && total !== 0) {
9
- return { ...localStatus, paid: undefined };
10
- }
11
-
12
- if (!actions.isPaid({ item: { status: localStatus } }) && total === 0) {
13
- return { ...localStatus, paid: { value: true, date: new Date() } };
14
- }
15
-
16
- return localStatus;
17
- };
@@ -1,17 +0,0 @@
1
- module.exports = ({ actions, settings }) =>
2
- function getUpdatedStatus({ status, total }) {
3
- if (!settings || !settings.order || !settings.order.autoMarkAsPaid)
4
- return status;
5
-
6
- const localStatus = status || {};
7
-
8
- if (actions.isPaid({ order: { status: localStatus } }) && total !== 0) {
9
- return { ...localStatus, paid: false };
10
- }
11
-
12
- if (!actions.isPaid({ order: { status: localStatus } }) && total === 0) {
13
- return { ...localStatus, paid: true };
14
- }
15
-
16
- return localStatus;
17
- };