@softwear/latestcollectioncore 1.0.170 → 1.0.172

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.
@@ -70,7 +70,9 @@ function addTransactionToAggregations(beginTimestamp, endTimestamp, aggregateKey
70
70
  aggregateVector[MAX_RECIEVE_TIMESTAMP] = transaction.time;
71
71
  if (transaction.time <= beginTimestamp) {
72
72
  addVectors(aggregateVector, v, BEGIN_STOCK_VECTOR_START, BEGIN_STOCK_VECTOR_END);
73
- // addVectors(aggregateVector, v, QTY_CONSIGNMENT, COSTPRICE_PICKLIST + 1)
73
+ // Keep pre-start outstanding picklists/consignments in state so endShelf remains stable
74
+ // when only the start date changes for a fixed end date.
75
+ addVectors(aggregateVector, v, QTY_CONSIGNMENT, COSTPRICE_PICKLIST + 1);
74
76
  return;
75
77
  }
76
78
  if (transaction.time > endTimestamp)
package/dist/hashBrand.js CHANGED
@@ -5,8 +5,8 @@ const DIACRITIC_REGEX = /[\u0300-\u036f]/g;
5
5
  // '~.<>!@#$%^&*():'"? /-\\'
6
6
  // Note: '-' is placed at the end of the class so it is treated literally,
7
7
  // and '\' is escaped.
8
- const REMOVE_CHARS_TEST_REGEX = /[~.<>!@#$%^&*()'"? \/\\-]/;
9
- const REMOVE_CHARS_REGEX = /[~.<>!@#$%^&*()'"? \/\\-]/g;
8
+ const REMOVE_CHARS_TEST_REGEX = /[~.<>!@#$%^&*():´`'"? \/\\-]/;
9
+ const REMOVE_CHARS_REGEX = /[~.<>!@#$%^&*():´`'"? \/\\-]/g;
10
10
  // Fast check: returns true if the string contains any non-ASCII character,
11
11
  // which we treat as a potential diacritic and normalize only in that case.
12
12
  function hasPotentialDiacritics(str) {
@@ -271,8 +271,7 @@ const buildTransaction = function (transaction) {
271
271
  dbTransaction.customer = transaction.customer;
272
272
  if (transaction.agent)
273
273
  dbTransaction.agent = transaction.agent;
274
- if (transaction.type == types_1.transactionTypeE.START_SHELF_STOCK)
275
- dbTransaction.type = types_1.transactionTypeE.START_STOCK;
274
+ // if (transaction.type == transactionTypeE.START_SHELF_STOCK) dbTransaction.type = transactionTypeE.START_STOCK
276
275
  return dbTransaction;
277
276
  };
278
277
  exports.default = { dbTransactionVector, buildTransaction, buildVector };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@softwear/latestcollectioncore",
3
- "version": "1.0.170",
3
+ "version": "1.0.172",
4
4
  "description": "Core functions for LatestCollections applications",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",
@@ -134,7 +134,9 @@ function addTransactionToAggregations(beginTimestamp: number, endTimestamp: numb
134
134
  if (transaction.type == transactionTypeE.RECEIVING && transaction.time > aggregateVector[MAX_RECIEVE_TIMESTAMP]) aggregateVector[MAX_RECIEVE_TIMESTAMP] = transaction.time
135
135
  if (transaction.time <= beginTimestamp) {
136
136
  addVectors(aggregateVector, v, BEGIN_STOCK_VECTOR_START, BEGIN_STOCK_VECTOR_END)
137
- // addVectors(aggregateVector, v, QTY_CONSIGNMENT, COSTPRICE_PICKLIST + 1)
137
+ // Keep pre-start outstanding picklists/consignments in state so endShelf remains stable
138
+ // when only the start date changes for a fixed end date.
139
+ addVectors(aggregateVector, v, QTY_CONSIGNMENT, COSTPRICE_PICKLIST + 1)
138
140
  return
139
141
  }
140
142
  if (transaction.time > endTimestamp) return
package/src/hashBrand.ts CHANGED
@@ -3,8 +3,8 @@ const DIACRITIC_REGEX = /[\u0300-\u036f]/g
3
3
  // '~.<>!@#$%^&*():'"? /-\\'
4
4
  // Note: '-' is placed at the end of the class so it is treated literally,
5
5
  // and '\' is escaped.
6
- const REMOVE_CHARS_TEST_REGEX = /[~.<>!@#$%^&*()'"? \/\\-]/
7
- const REMOVE_CHARS_REGEX = /[~.<>!@#$%^&*()'"? \/\\-]/g
6
+ const REMOVE_CHARS_TEST_REGEX = /[~.<>!@#$%^&*():´`'"? \/\\-]/
7
+ const REMOVE_CHARS_REGEX = /[~.<>!@#$%^&*():´`'"? \/\\-]/g
8
8
 
9
9
  // Fast check: returns true if the string contains any non-ASCII character,
10
10
  // which we treat as a potential diacritic and normalize only in that case.
@@ -284,7 +284,7 @@ const buildTransaction = function (transaction: TransactionI): dbTransactionI |
284
284
  if (transaction.vat !== undefined) dbTransaction.vat = transaction.vat
285
285
  if (transaction.customer) dbTransaction.customer = transaction.customer
286
286
  if (transaction.agent) dbTransaction.agent = transaction.agent
287
- if (transaction.type == transactionTypeE.START_SHELF_STOCK) dbTransaction.type = transactionTypeE.START_STOCK
287
+ // if (transaction.type == transactionTypeE.START_SHELF_STOCK) dbTransaction.type = transactionTypeE.START_STOCK
288
288
 
289
289
  return dbTransaction
290
290
  }
@@ -389,6 +389,71 @@ describe('articleStatus', () => {
389
389
  expect(testResult.vector[articleStatus.AMOUNT_END_SHELF_STOCK]).toBe(1085)
390
390
  })
391
391
 
392
+ it('should keep end shelfStock stable for fixed end date when start date changes', () => {
393
+ const stableShelfTransactions = [
394
+ {
395
+ time: Date.parse('2026-01-01T00:00:00.000Z'),
396
+ type: '0',
397
+ ean: 'TEST_STABLE',
398
+ wh: '50',
399
+ qty: 10,
400
+ buyprice: 10,
401
+ docnr: 'BEGINSTOCK',
402
+ },
403
+ {
404
+ // Will be in-period for early start and pre-start for later start
405
+ time: Date.parse('2026-01-05T00:00:00.000Z'),
406
+ type: '95',
407
+ ean: 'TEST_STABLE',
408
+ wh: '50',
409
+ qty: 2,
410
+ buyprice: 10,
411
+ sellprice: 15,
412
+ docnr: 'CONS-1',
413
+ },
414
+ {
415
+ time: Date.parse('2026-01-10T00:00:00.000Z'),
416
+ type: '95',
417
+ ean: 'TEST_STABLE',
418
+ wh: '50',
419
+ qty: -1,
420
+ buyprice: 10,
421
+ sellprice: 15,
422
+ docnr: 'CONS-1-RETURN',
423
+ },
424
+ ]
425
+
426
+ const run = (startIso) => {
427
+ const dateRange = articleStatus.getDateRangeFromDatePair([startIso, '2026-01-31T00:00:00.000Z'])
428
+ const rawAggregations = {}
429
+ articleStatus.runQuery(
430
+ dateRange,
431
+ rawAggregations,
432
+ true,
433
+ stableShelfTransactions,
434
+ ['transaction.ean'],
435
+ {},
436
+ {},
437
+ {},
438
+ false,
439
+ '',
440
+ false
441
+ )
442
+ const vector = [].slice.call(rawAggregations['TEST_STABLE'])
443
+ articleStatus.postAgg(vector, dateRange.timeFrame)
444
+ return vector
445
+ }
446
+
447
+ const earlyStart = run('2026-01-01T00:00:00.000Z')
448
+ const lateStart = run('2026-01-15T00:00:00.000Z')
449
+
450
+ // Net consignment outstanding is +1, so end shelf should be 10 - 1 = 9 regardless of start date.
451
+ expect(earlyStart[articleStatus.QTY_END_STOCK]).toBe(10)
452
+ expect(lateStart[articleStatus.QTY_END_STOCK]).toBe(10)
453
+ expect(earlyStart[articleStatus.QTY_END_SHELF_STOCK]).toBe(9)
454
+ expect(lateStart[articleStatus.QTY_END_SHELF_STOCK]).toBe(9)
455
+ })
456
+
392
457
  it('#getDateRangeFromPicker', () => {
393
458
  const dateRange = articleStatus.getDateRangeFromPicker(['2024-01-01', '2024-12-31'])
394
459
  expect(dateRange.beginTimeStamp).toBe(1704063600000)
@@ -46,31 +46,6 @@ describe('#Transactions', () => {
46
46
  })
47
47
  expect(transaction.vector).toBe(undefined)
48
48
  })
49
-
50
- it('should map type 10 to type 0 and still not generate vector', () => {
51
- const transaction = buildTransaction({
52
- type: '10',
53
- ean: '1234567890128',
54
- wh: '51',
55
- time: 314159265,
56
- qty: 123,
57
- buyprice: 9.95,
58
- vat: 21,
59
- docnr: '51-123',
60
- })
61
-
62
- expect(transaction).toEqual({
63
- type: '0',
64
- ean: '1234567890128',
65
- wh: '51',
66
- time: 314159265,
67
- qty: 123,
68
- buyprice: 9.95,
69
- vat: 21,
70
- docnr: '51-123',
71
- })
72
- expect(transaction.vector).toBe(undefined)
73
- })
74
49
  })
75
50
 
76
51
  describe('#buildVector', () => {
@@ -84,7 +59,51 @@ describe('#Transactions', () => {
84
59
  label: 'type 2 (=sale)',
85
60
  input: { type: '2', ean: '1234567890128', wh: '51', time: 314159265, qty: 123, sellprice: 19.95, buyprice: 9.95, vat: 21, docnr: '51-123' },
86
61
  expected: [
87
- 123, -123, -1223.85, -123, -1223.85, 0, 0, 0, 123, 2453.85, 2027.98, 123 * 9.95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
62
+ 123,
63
+ -123,
64
+ -1223.85,
65
+ -123,
66
+ -1223.85,
67
+ 0,
68
+ 0,
69
+ 0,
70
+ 123,
71
+ 2453.85,
72
+ 2027.98,
73
+ 123 * 9.95,
74
+ 0,
75
+ 0,
76
+ 0,
77
+ 0,
78
+ 0,
79
+ 0,
80
+ 0,
81
+ 0,
82
+ 0,
83
+ 0,
84
+ 0,
85
+ 0,
86
+ 0,
87
+ 0,
88
+ 0,
89
+ 0,
90
+ 0,
91
+ 0,
92
+ 0,
93
+ 0,
94
+ 0,
95
+ 0,
96
+ 0,
97
+ 0,
98
+ 0,
99
+ 0,
100
+ 0,
101
+ 0,
102
+ 0,
103
+ 0,
104
+ 0,
105
+ 0,
106
+ 0,
88
107
  ],
89
108
  },
90
109
  {
@@ -151,7 +170,46 @@ describe('#Transactions', () => {
151
170
  label: 'type 6 (=b2b return to customer)',
152
171
  input: { type: '6', ean: '1234567890128', wh: '51', time: 314159265, qty: 123, buyprice: 9.95, sellprice: 19.95, vat: 21, docnr: '51-123' },
153
172
  expected: [
154
- 123, 123, 123 * 9.95, 123, 123 * 9.95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 123, 123 * 19.95, 123 * 9.95,
173
+ 123,
174
+ 123,
175
+ 123 * 9.95,
176
+ 123,
177
+ 123 * 9.95,
178
+ 0,
179
+ 0,
180
+ 0,
181
+ 0,
182
+ 0,
183
+ 0,
184
+ 0,
185
+ 0,
186
+ 0,
187
+ 0,
188
+ 0,
189
+ 0,
190
+ 0,
191
+ 0,
192
+ 0,
193
+ 0,
194
+ 0,
195
+ 0,
196
+ 0,
197
+ 0,
198
+ 0,
199
+ 0,
200
+ 0,
201
+ 0,
202
+ 0,
203
+ 0,
204
+ 0,
205
+ 0,
206
+ 0,
207
+ 0,
208
+ 0,
209
+ 0,
210
+ 123,
211
+ 123 * 19.95,
212
+ 123 * 9.95,
155
213
  ],
156
214
  },
157
215
  {