@softwear/latestcollectioncore 1.0.198 → 1.0.199
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/dist/articleStatus.js +17 -10
- package/package.json +1 -1
- package/src/articleStatus.ts +18 -10
- package/test/articleStatus.spec.js +23 -0
package/dist/articleStatus.js
CHANGED
|
@@ -159,10 +159,14 @@ function aggregator({ beginTimestamp, endTimestamp, filterExpression, aggregatio
|
|
|
159
159
|
.filter((join) => filterExpression.includes(join[0] + '.'))
|
|
160
160
|
.map((join) => join[1]);
|
|
161
161
|
}
|
|
162
|
-
|
|
163
|
-
const
|
|
164
|
-
|
|
165
|
-
|
|
162
|
+
// Empty aggregation expression = no groupers → only the totals row
|
|
163
|
+
const totalsOnly = !aggregationExpression;
|
|
164
|
+
const aggregationEvaluator = totalsOnly ? undefined : buildAggregationEvaluator(aggregationExpression);
|
|
165
|
+
const aggregationGranularity = totalsOnly
|
|
166
|
+
? []
|
|
167
|
+
: Object.entries(globalJoinableTables)
|
|
168
|
+
.filter((join) => aggregationExpression.includes(join[0] + '.'))
|
|
169
|
+
.map((join) => join[1]);
|
|
166
170
|
const aggregationTrieRoot = {};
|
|
167
171
|
return function (transaction) {
|
|
168
172
|
if (filter) {
|
|
@@ -175,11 +179,6 @@ function aggregator({ beginTimestamp, endTimestamp, filterExpression, aggregatio
|
|
|
175
179
|
return;
|
|
176
180
|
}
|
|
177
181
|
}
|
|
178
|
-
const aggregateKeyLeaf = getTrieLeaf(aggregationTrieRoot, transaction, aggregationGranularity);
|
|
179
|
-
if (!aggregateKeyLeaf.aggregateKey) {
|
|
180
|
-
aggregateKeyLeaf.aggregateKey = aggregationEvaluator(transaction);
|
|
181
|
-
}
|
|
182
|
-
const aggregateKey = aggregateKeyLeaf.aggregateKey;
|
|
183
182
|
// Prepare joined values for derived fields
|
|
184
183
|
if (transaction.type == types_1.transactionTypeE.SALE) {
|
|
185
184
|
const sku = globalRelations['sku'][transaction.ean];
|
|
@@ -194,8 +193,16 @@ function aggregator({ beginTimestamp, endTimestamp, filterExpression, aggregatio
|
|
|
194
193
|
v[AMOUNT_SOLD_MAX] = (0, index_1.round2)((((sku === null || sku === void 0 ? void 0 : sku.price) || 0) / ((100 + (transaction.vat || (sku === null || sku === void 0 ? void 0 : sku.vat) || 21)) / 100)) * v[QTY_SOLD]);
|
|
195
194
|
v[AMOUNT_SOLD_DISCOUNT] = (0, index_1.round2)(v[AMOUNT_SOLD_MAX] - v[AMOUNT_SOLD_EXCL]);
|
|
196
195
|
}
|
|
197
|
-
if (totals)
|
|
196
|
+
if (totals || totalsOnly)
|
|
198
197
|
addTransactionToAggregations(beginTimestamp, endTimestamp, '** TOTAL **', rawAggregations, transaction, maxRows);
|
|
198
|
+
// No detail/subtotal rows when there are no groupers
|
|
199
|
+
if (totalsOnly)
|
|
200
|
+
return;
|
|
201
|
+
const aggregateKeyLeaf = getTrieLeaf(aggregationTrieRoot, transaction, aggregationGranularity);
|
|
202
|
+
if (!aggregateKeyLeaf.aggregateKey) {
|
|
203
|
+
aggregateKeyLeaf.aggregateKey = aggregationEvaluator(transaction);
|
|
204
|
+
}
|
|
205
|
+
const aggregateKey = aggregateKeyLeaf.aggregateKey;
|
|
199
206
|
// Single subtotals are subtotals for first grouper level
|
|
200
207
|
// Example: for 4 groupers we have rows like
|
|
201
208
|
// g0 g1 g2 g3 <- normal row with no subtotal
|
package/package.json
CHANGED
package/src/articleStatus.ts
CHANGED
|
@@ -242,10 +242,14 @@ function aggregator({
|
|
|
242
242
|
.filter((join) => filterExpression.includes(join[0] + '.'))
|
|
243
243
|
.map((join) => join[1])
|
|
244
244
|
}
|
|
245
|
-
|
|
246
|
-
const
|
|
247
|
-
|
|
248
|
-
|
|
245
|
+
// Empty aggregation expression = no groupers → only the totals row
|
|
246
|
+
const totalsOnly = !aggregationExpression
|
|
247
|
+
const aggregationEvaluator = totalsOnly ? undefined : buildAggregationEvaluator(aggregationExpression)
|
|
248
|
+
const aggregationGranularity = totalsOnly
|
|
249
|
+
? []
|
|
250
|
+
: Object.entries(globalJoinableTables)
|
|
251
|
+
.filter((join) => aggregationExpression.includes(join[0] + '.'))
|
|
252
|
+
.map((join) => join[1])
|
|
249
253
|
const aggregationTrieRoot: AggregateKeyTrieNode = {}
|
|
250
254
|
|
|
251
255
|
return function (transaction: TransactionI): void {
|
|
@@ -257,11 +261,6 @@ function aggregator({
|
|
|
257
261
|
if (filterLeaf.filterResult === -1) return
|
|
258
262
|
}
|
|
259
263
|
}
|
|
260
|
-
const aggregateKeyLeaf = getTrieLeaf<AggregateKeyTrieNode>(aggregationTrieRoot, transaction, aggregationGranularity)
|
|
261
|
-
if (!aggregateKeyLeaf.aggregateKey) {
|
|
262
|
-
aggregateKeyLeaf.aggregateKey = aggregationEvaluator(transaction) as string
|
|
263
|
-
}
|
|
264
|
-
const aggregateKey = aggregateKeyLeaf.aggregateKey as string
|
|
265
264
|
// Prepare joined values for derived fields
|
|
266
265
|
if (transaction.type == transactionTypeE.SALE) {
|
|
267
266
|
const sku = globalRelations['sku'][transaction.ean]
|
|
@@ -276,7 +275,16 @@ function aggregator({
|
|
|
276
275
|
v[AMOUNT_SOLD_DISCOUNT] = round2(v[AMOUNT_SOLD_MAX] - v[AMOUNT_SOLD_EXCL])
|
|
277
276
|
}
|
|
278
277
|
|
|
279
|
-
if (totals) addTransactionToAggregations(beginTimestamp, endTimestamp, '** TOTAL **', rawAggregations, transaction, maxRows)
|
|
278
|
+
if (totals || totalsOnly) addTransactionToAggregations(beginTimestamp, endTimestamp, '** TOTAL **', rawAggregations, transaction, maxRows)
|
|
279
|
+
|
|
280
|
+
// No detail/subtotal rows when there are no groupers
|
|
281
|
+
if (totalsOnly) return
|
|
282
|
+
|
|
283
|
+
const aggregateKeyLeaf = getTrieLeaf<AggregateKeyTrieNode>(aggregationTrieRoot, transaction, aggregationGranularity)
|
|
284
|
+
if (!aggregateKeyLeaf.aggregateKey) {
|
|
285
|
+
aggregateKeyLeaf.aggregateKey = aggregationEvaluator!(transaction) as string
|
|
286
|
+
}
|
|
287
|
+
const aggregateKey = aggregateKeyLeaf.aggregateKey as string
|
|
280
288
|
|
|
281
289
|
// Single subtotals are subtotals for first grouper level
|
|
282
290
|
// Example: for 4 groupers we have rows like
|
|
@@ -178,6 +178,29 @@ describe('articleStatus', () => {
|
|
|
178
178
|
expect(result[2].vector[articleStatus.VALUE_AVG_STOCK]).toBe(84.15000000000002)
|
|
179
179
|
})
|
|
180
180
|
|
|
181
|
+
it('should calculate only the totals row when no groupers are selected', () => {
|
|
182
|
+
const rawAggregations = {}
|
|
183
|
+
articleStatus.runQuery(
|
|
184
|
+
{ beginTimeStamp: 1569316408000, endTimeStamp: 1569316409000 + msYear },
|
|
185
|
+
rawAggregations,
|
|
186
|
+
true,
|
|
187
|
+
TRANSACTIONS,
|
|
188
|
+
[],
|
|
189
|
+
SKUS,
|
|
190
|
+
{},
|
|
191
|
+
{},
|
|
192
|
+
false,
|
|
193
|
+
'transaction.ean=="000558000143"',
|
|
194
|
+
false
|
|
195
|
+
)
|
|
196
|
+
|
|
197
|
+
expect(Object.keys(rawAggregations)).toEqual(['** TOTAL **'])
|
|
198
|
+
const vector = [].slice.call(rawAggregations['** TOTAL **'])
|
|
199
|
+
articleStatus.postAgg(vector, msYear)
|
|
200
|
+
expect(vector[articleStatus.QTY_STOCK]).toBe(18)
|
|
201
|
+
expect(vector[articleStatus.QTY_END_STOCK]).toBe(17)
|
|
202
|
+
})
|
|
203
|
+
|
|
181
204
|
it('should calculate aggregations', () => {
|
|
182
205
|
const rawAggregations = {}
|
|
183
206
|
articleStatus.runQuery(
|