gemcap-be-common 1.2.73 → 1.2.74
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/db/inventories.d.ts +4 -0
- package/db/inventories.js +55 -1
- package/db/inventories.ts +50 -0
- package/helpers/excel.helper.d.ts +3 -0
- package/helpers/excel.helper.js +15 -1
- package/helpers/excel.helper.ts +14 -0
- package/models/BorrowerSettings.model.d.ts +1 -0
- package/models/BorrowerSettings.model.ts +1 -1
- package/models/QueryResult.model.d.ts +1 -4
- package/models/QueryResult.model.js +33 -27
- package/models/QueryResult.model.ts +35 -30
- package/package.json +1 -1
- package/queries/inventory/turn.d.ts +9 -0
- package/queries/inventory/turn.js +168 -0
- package/queries/inventory/turn.ts +176 -0
- package/queries/inventory/unit-cost-difference.d.ts +1 -9
- package/queries/inventory/unit-cost-difference.js +8 -2
- package/queries/inventory/unit-cost-difference.ts +8 -1
- package/tsconfig.tsbuildinfo +1 -1
package/db/inventories.d.ts
CHANGED
package/db/inventories.js
CHANGED
|
@@ -1,6 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getSKUUnitCostForAllDates = void 0;
|
|
6
|
+
exports.getAllUniqSKUInRangeNew = exports.getSKUUnitCostForAllDates = void 0;
|
|
7
|
+
const mongoose_1 = __importDefault(require("mongoose"));
|
|
4
8
|
const InventoryItem_model_1 = require("../models/InventoryItem.model");
|
|
5
9
|
const collaterals_db_1 = require("./collaterals.db");
|
|
6
10
|
const getSKUUnitCostForAllDates = async (sheetsIds) => {
|
|
@@ -38,3 +42,53 @@ const getSKUUnitCostForAllDates = async (sheetsIds) => {
|
|
|
38
42
|
]);
|
|
39
43
|
};
|
|
40
44
|
exports.getSKUUnitCostForAllDates = getSKUUnitCostForAllDates;
|
|
45
|
+
const getAllUniqSKUInRangeNew = async (bbcSheetIds) => {
|
|
46
|
+
return InventoryItem_model_1.InventoryItemModel.aggregate([
|
|
47
|
+
{
|
|
48
|
+
$match: {
|
|
49
|
+
'bbcSheetId': {
|
|
50
|
+
$in: bbcSheetIds.map((bbcSheetId) => new mongoose_1.default.Types.ObjectId(bbcSheetId))
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
$lookup: {
|
|
56
|
+
from: 'bbcsheets',
|
|
57
|
+
localField: 'bbcSheetId',
|
|
58
|
+
foreignField: '_id',
|
|
59
|
+
as: 'bbcSheet'
|
|
60
|
+
}
|
|
61
|
+
},
|
|
62
|
+
{
|
|
63
|
+
$unwind: {
|
|
64
|
+
path: '$bbcSheet'
|
|
65
|
+
}
|
|
66
|
+
}, {
|
|
67
|
+
$lookup: {
|
|
68
|
+
from: 'bbcdates',
|
|
69
|
+
localField: 'bbcSheet.bbcDateId',
|
|
70
|
+
foreignField: '_id',
|
|
71
|
+
as: 'bbc'
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
$unwind: {
|
|
76
|
+
path: '$bbc'
|
|
77
|
+
}
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
$sort: {
|
|
81
|
+
'bbc.bbcDate': 1
|
|
82
|
+
}
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
$group: {
|
|
86
|
+
'_id': '$bbc.borrowerId',
|
|
87
|
+
'skus': {
|
|
88
|
+
$addToSet: '$sku'
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
]);
|
|
93
|
+
};
|
|
94
|
+
exports.getAllUniqSKUInRangeNew = getAllUniqSKUInRangeNew;
|
package/db/inventories.ts
CHANGED
|
@@ -42,3 +42,53 @@ export const getSKUUnitCostForAllDates = async (sheetsIds: mongoose.Types.Object
|
|
|
42
42
|
},
|
|
43
43
|
]);
|
|
44
44
|
};
|
|
45
|
+
|
|
46
|
+
export const getAllUniqSKUInRangeNew = async (bbcSheetIds: string[]): Promise<{ _id: string, skus: string[] }[]> => {
|
|
47
|
+
return InventoryItemModel.aggregate([
|
|
48
|
+
{
|
|
49
|
+
$match: {
|
|
50
|
+
'bbcSheetId': {
|
|
51
|
+
$in: bbcSheetIds.map((bbcSheetId) => new mongoose.Types.ObjectId(bbcSheetId))
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
$lookup: {
|
|
57
|
+
from: 'bbcsheets',
|
|
58
|
+
localField: 'bbcSheetId',
|
|
59
|
+
foreignField: '_id',
|
|
60
|
+
as: 'bbcSheet'
|
|
61
|
+
}
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
$unwind: {
|
|
65
|
+
path: '$bbcSheet'
|
|
66
|
+
}
|
|
67
|
+
}, {
|
|
68
|
+
$lookup: {
|
|
69
|
+
from: 'bbcdates',
|
|
70
|
+
localField: 'bbcSheet.bbcDateId',
|
|
71
|
+
foreignField: '_id',
|
|
72
|
+
as: 'bbc'
|
|
73
|
+
}
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
$unwind: {
|
|
77
|
+
path: '$bbc'
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
$sort: {
|
|
82
|
+
'bbc.bbcDate': 1
|
|
83
|
+
}
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
$group: {
|
|
87
|
+
'_id': '$bbc.borrowerId',
|
|
88
|
+
'skus': {
|
|
89
|
+
$addToSet: '$sku'
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
]);
|
|
94
|
+
}
|
package/helpers/excel.helper.js
CHANGED
|
@@ -23,7 +23,7 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
23
23
|
return result;
|
|
24
24
|
};
|
|
25
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
|
-
exports.convertDataToFileWithStyle = exports.convertDataToFile = void 0;
|
|
26
|
+
exports.addHeaderToData = exports.convertDataToFileWithStyle = exports.convertDataToFile = void 0;
|
|
27
27
|
const XLSX = __importStar(require("xlsx"));
|
|
28
28
|
const XLSXStyle = __importStar(require("xlsx-js-style"));
|
|
29
29
|
const defaultColumnWidth = 20;
|
|
@@ -86,3 +86,17 @@ const convertDataToFileWithStyle = async (dataToConvert, options) => {
|
|
|
86
86
|
return XLSXStyle.write(wb, { bookType: 'xlsx', type: 'buffer' });
|
|
87
87
|
};
|
|
88
88
|
exports.convertDataToFileWithStyle = convertDataToFileWithStyle;
|
|
89
|
+
const addHeaderToData = (header, data) => {
|
|
90
|
+
const filterAndReorder = (item) => {
|
|
91
|
+
const newItem = {};
|
|
92
|
+
Object.keys(header).forEach(key => {
|
|
93
|
+
if (item.hasOwnProperty(key)) {
|
|
94
|
+
newItem[key] = item[key];
|
|
95
|
+
}
|
|
96
|
+
});
|
|
97
|
+
return newItem;
|
|
98
|
+
};
|
|
99
|
+
const processedItems = data.map(filterAndReorder);
|
|
100
|
+
return [header, ...processedItems];
|
|
101
|
+
};
|
|
102
|
+
exports.addHeaderToData = addHeaderToData;
|
package/helpers/excel.helper.ts
CHANGED
|
@@ -72,3 +72,17 @@ export const convertDataToFileWithStyle = async (
|
|
|
72
72
|
});
|
|
73
73
|
return XLSXStyle.write(wb, { bookType: 'xlsx', type: 'buffer' });
|
|
74
74
|
};
|
|
75
|
+
|
|
76
|
+
export const addHeaderToData = (header: { [key: string]: string }, data: object[]) => {
|
|
77
|
+
const filterAndReorder = (item: object) => {
|
|
78
|
+
const newItem = {};
|
|
79
|
+
Object.keys(header).forEach(key => {
|
|
80
|
+
if (item.hasOwnProperty(key)) {
|
|
81
|
+
newItem[key] = item[key];
|
|
82
|
+
}
|
|
83
|
+
});
|
|
84
|
+
return newItem;
|
|
85
|
+
};
|
|
86
|
+
const processedItems = data.map(filterAndReorder);
|
|
87
|
+
return [header, ...processedItems];
|
|
88
|
+
}
|
|
@@ -14,7 +14,7 @@ import { MODEL_NAMES } from './_models';
|
|
|
14
14
|
|
|
15
15
|
export interface IBorrowerSettings {
|
|
16
16
|
borrower: mongoose.Types.ObjectId;
|
|
17
|
-
queries: { [group: string]: { [queryName: string]: { isCalculateOnUpload: boolean } } };
|
|
17
|
+
queries: { [group: string]: { [queryName: string]: { isCalculateOnUpload: boolean, queryParams: object } } };
|
|
18
18
|
dataTypes: { [group: string]: string[] };
|
|
19
19
|
dataAvailability: {
|
|
20
20
|
[key in 'receivables' | 'inventories']: boolean;
|
|
@@ -75,13 +75,10 @@ export declare enum EFilterParams {
|
|
|
75
75
|
}
|
|
76
76
|
interface IQueryDetail {
|
|
77
77
|
scheduled: boolean;
|
|
78
|
-
|
|
78
|
+
queryAPI: string;
|
|
79
79
|
queryFunction: ((params: TQueryParams) => unknown) | null;
|
|
80
80
|
filterParams?: EFilterParams;
|
|
81
81
|
sheetTitle?: string;
|
|
82
|
-
header?: {
|
|
83
|
-
[headerKey: string]: string;
|
|
84
|
-
};
|
|
85
82
|
}
|
|
86
83
|
type TQueryGroups = {
|
|
87
84
|
[EQueriesGroups.INVENTORY]: {
|
|
@@ -6,6 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.QueryResult = exports.QUERY_GROUPS = exports.EFilterParams = exports.EChartsCash = exports.EChartsMisc = exports.EChartsReceivable = exports.EChartsInventory = exports.EQueriesGroups = void 0;
|
|
7
7
|
const mongoose_1 = __importDefault(require("mongoose"));
|
|
8
8
|
const unit_cost_difference_1 = require("../queries/inventory/unit-cost-difference");
|
|
9
|
+
const turn_1 = require("../queries/inventory/turn");
|
|
9
10
|
var EQueriesGroups;
|
|
10
11
|
(function (EQueriesGroups) {
|
|
11
12
|
EQueriesGroups["INVENTORY"] = "INVENTORY";
|
|
@@ -58,48 +59,53 @@ var EFilterParams;
|
|
|
58
59
|
})(EFilterParams || (exports.EFilterParams = EFilterParams = {}));
|
|
59
60
|
exports.QUERY_GROUPS = {
|
|
60
61
|
[EQueriesGroups.INVENTORY]: {
|
|
61
|
-
[EChartsInventory.BENFORD]: { scheduled: false,
|
|
62
|
-
[EChartsInventory.INVOICE_DIFFERENCE]: { scheduled: false,
|
|
63
|
-
[EChartsInventory.EXPOSURES]: { scheduled: false,
|
|
64
|
-
[EChartsInventory.EXPOSURES_CATEGORIES]: { scheduled: false,
|
|
65
|
-
[EChartsInventory.AVERAGE_SKU_VALUES]: { scheduled: false,
|
|
66
|
-
[EChartsInventory.AGING_PLOT]: { scheduled: false,
|
|
62
|
+
[EChartsInventory.BENFORD]: { scheduled: false, queryAPI: 'benford', queryFunction: null },
|
|
63
|
+
[EChartsInventory.INVOICE_DIFFERENCE]: { scheduled: false, queryAPI: 'invoice-difference', queryFunction: null },
|
|
64
|
+
[EChartsInventory.EXPOSURES]: { scheduled: false, queryAPI: 'exposures', queryFunction: null },
|
|
65
|
+
[EChartsInventory.EXPOSURES_CATEGORIES]: { scheduled: false, queryAPI: 'exposures-categories', queryFunction: null },
|
|
66
|
+
[EChartsInventory.AVERAGE_SKU_VALUES]: { scheduled: false, queryAPI: 'average-sku-values', queryFunction: null },
|
|
67
|
+
[EChartsInventory.AGING_PLOT]: { scheduled: false, queryAPI: 'aging-plot', queryFunction: null },
|
|
67
68
|
[EChartsInventory.UNIT_COST_DIFFERENCE]: {
|
|
68
69
|
scheduled: true,
|
|
69
|
-
|
|
70
|
-
queryFunction: unit_cost_difference_1.
|
|
70
|
+
queryAPI: 'unit-cost-difference',
|
|
71
|
+
queryFunction: unit_cost_difference_1.getUnitCostDifferenceFull,
|
|
71
72
|
filterParams: EFilterParams.NONE,
|
|
72
73
|
sheetTitle: 'INV.Change in unit cost',
|
|
73
|
-
header: (0, unit_cost_difference_1.getUnitCostDifferenceHeader)(),
|
|
74
74
|
},
|
|
75
|
-
[EChartsInventory.INCONSISTENT_DATA]: { scheduled: false,
|
|
76
|
-
[EChartsInventory.INVENTORY_TURN]: {
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
[EChartsInventory.INCONSISTENT_DATA]: { scheduled: false, queryAPI: 'inconsistent-data', queryFunction: null },
|
|
76
|
+
[EChartsInventory.INVENTORY_TURN]: {
|
|
77
|
+
scheduled: true,
|
|
78
|
+
queryAPI: 'turn',
|
|
79
|
+
queryFunction: turn_1.getInventoryTurnFull,
|
|
80
|
+
filterParams: EFilterParams.PERIOD,
|
|
81
|
+
sheetTitle: 'INV.Inventory turn',
|
|
82
|
+
},
|
|
83
|
+
[EChartsInventory.MOVEMENT]: { scheduled: false, queryAPI: 'movement', queryFunction: null },
|
|
84
|
+
[EChartsInventory.EXTENSION]: { scheduled: false, queryAPI: 'extension', queryFunction: null },
|
|
79
85
|
},
|
|
80
86
|
[EQueriesGroups.RECEIVABLE]: {
|
|
81
|
-
[EChartsReceivable.BENFORD]: { scheduled: false,
|
|
82
|
-
[EChartsReceivable.EXPOSURES]: { scheduled: false,
|
|
83
|
-
[EChartsReceivable.EXPOSURES_CUSTOMERS]: { scheduled: false,
|
|
84
|
-
[EChartsReceivable.DUPLICATES]: { scheduled: false,
|
|
85
|
-
[EChartsReceivable.AVERAGE_INVOICE]: { scheduled: false,
|
|
86
|
-
[EChartsReceivable.INVOICE_VALUE_PLOT]: { scheduled: false,
|
|
87
|
-
[EChartsReceivable.AGING_PLOT]: { scheduled: false,
|
|
88
|
-
[EChartsReceivable.INVOICE_DIFFERENCE]: { scheduled: false,
|
|
87
|
+
[EChartsReceivable.BENFORD]: { scheduled: false, queryAPI: 'benford', queryFunction: null },
|
|
88
|
+
[EChartsReceivable.EXPOSURES]: { scheduled: false, queryAPI: 'exposures', queryFunction: null },
|
|
89
|
+
[EChartsReceivable.EXPOSURES_CUSTOMERS]: { scheduled: false, queryAPI: 'exposures-customers', queryFunction: null },
|
|
90
|
+
[EChartsReceivable.DUPLICATES]: { scheduled: false, queryAPI: 'duplicates', queryFunction: null },
|
|
91
|
+
[EChartsReceivable.AVERAGE_INVOICE]: { scheduled: false, queryAPI: 'average-invoice', queryFunction: null },
|
|
92
|
+
[EChartsReceivable.INVOICE_VALUE_PLOT]: { scheduled: false, queryAPI: 'average-sku-values', queryFunction: null },
|
|
93
|
+
[EChartsReceivable.AGING_PLOT]: { scheduled: false, queryAPI: 'aging-plot', queryFunction: null },
|
|
94
|
+
[EChartsReceivable.INVOICE_DIFFERENCE]: { scheduled: false, queryAPI: 'invoice-difference', queryFunction: null },
|
|
89
95
|
[EChartsReceivable.PARTIALLY_PAID_RESTATED]: {
|
|
90
96
|
scheduled: false,
|
|
91
|
-
|
|
97
|
+
queryAPI: 'partially-paid-restated',
|
|
92
98
|
queryFunction: null,
|
|
93
99
|
},
|
|
94
|
-
[EChartsReceivable.AR_TURN]: { scheduled: false,
|
|
95
|
-
[EChartsReceivable.GROUP_CUSTOMERS]: { scheduled: false,
|
|
100
|
+
[EChartsReceivable.AR_TURN]: { scheduled: false, queryAPI: 'ar-turn', queryFunction: null },
|
|
101
|
+
[EChartsReceivable.GROUP_CUSTOMERS]: { scheduled: false, queryAPI: 'grouped-receivables', queryFunction: null },
|
|
96
102
|
},
|
|
97
103
|
[EQueriesGroups.OTHER]: {
|
|
98
|
-
[EChartsMisc.CONTRAS]: { scheduled: false,
|
|
104
|
+
[EChartsMisc.CONTRAS]: { scheduled: false, queryAPI: 'contras', queryFunction: null },
|
|
99
105
|
},
|
|
100
106
|
[EQueriesGroups.CASH]: {
|
|
101
|
-
[EChartsCash.TRANSACTIONS]: { scheduled: false,
|
|
102
|
-
[EChartsCash.DELUTION]: { scheduled: false,
|
|
107
|
+
[EChartsCash.TRANSACTIONS]: { scheduled: false, queryAPI: 'transactions', queryFunction: null },
|
|
108
|
+
[EChartsCash.DELUTION]: { scheduled: false, queryAPI: 'delution', queryFunction: null },
|
|
103
109
|
},
|
|
104
110
|
};
|
|
105
111
|
const QueryResultSchema = new mongoose_1.default.Schema({
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import mongoose, { Document, Model } from 'mongoose';
|
|
2
2
|
|
|
3
|
-
import {
|
|
3
|
+
import { getUnitCostDifferenceFull } from '../queries/inventory/unit-cost-difference';
|
|
4
|
+
import { getInventoryTurnFull } from '../queries/inventory/turn';
|
|
4
5
|
|
|
5
6
|
export type TQueryParams = {
|
|
6
7
|
borrowerId: mongoose.Types.ObjectId;
|
|
@@ -61,11 +62,10 @@ export enum EFilterParams {
|
|
|
61
62
|
|
|
62
63
|
interface IQueryDetail {
|
|
63
64
|
scheduled: boolean;
|
|
64
|
-
|
|
65
|
+
queryAPI: string;
|
|
65
66
|
queryFunction: ((params: TQueryParams) => unknown) | null;
|
|
66
67
|
filterParams?: EFilterParams;
|
|
67
68
|
sheetTitle?: string;
|
|
68
|
-
header?: { [headerKey: string]: string };
|
|
69
69
|
}
|
|
70
70
|
|
|
71
71
|
type TQueryGroups = {
|
|
@@ -85,51 +85,56 @@ type TQueryGroups = {
|
|
|
85
85
|
|
|
86
86
|
export const QUERY_GROUPS: TQueryGroups = {
|
|
87
87
|
[EQueriesGroups.INVENTORY]: {
|
|
88
|
-
[EChartsInventory.BENFORD]: { scheduled: false,
|
|
89
|
-
[EChartsInventory.INVOICE_DIFFERENCE]: { scheduled: false,
|
|
90
|
-
[EChartsInventory.EXPOSURES]: { scheduled: false,
|
|
91
|
-
[EChartsInventory.EXPOSURES_CATEGORIES]: { scheduled: false,
|
|
92
|
-
[EChartsInventory.AVERAGE_SKU_VALUES]: { scheduled: false,
|
|
93
|
-
[EChartsInventory.AGING_PLOT]: { scheduled: false,
|
|
88
|
+
[EChartsInventory.BENFORD]: { scheduled: false, queryAPI: 'benford', queryFunction: null },
|
|
89
|
+
[EChartsInventory.INVOICE_DIFFERENCE]: { scheduled: false, queryAPI: 'invoice-difference', queryFunction: null },
|
|
90
|
+
[EChartsInventory.EXPOSURES]: { scheduled: false, queryAPI: 'exposures', queryFunction: null },
|
|
91
|
+
[EChartsInventory.EXPOSURES_CATEGORIES]: { scheduled: false, queryAPI: 'exposures-categories', queryFunction: null },
|
|
92
|
+
[EChartsInventory.AVERAGE_SKU_VALUES]: { scheduled: false, queryAPI: 'average-sku-values', queryFunction: null },
|
|
93
|
+
[EChartsInventory.AGING_PLOT]: { scheduled: false, queryAPI: 'aging-plot', queryFunction: null },
|
|
94
94
|
[EChartsInventory.UNIT_COST_DIFFERENCE]: {
|
|
95
95
|
scheduled: true,
|
|
96
|
-
|
|
97
|
-
queryFunction:
|
|
96
|
+
queryAPI: 'unit-cost-difference',
|
|
97
|
+
queryFunction: getUnitCostDifferenceFull,
|
|
98
98
|
filterParams: EFilterParams.NONE,
|
|
99
99
|
sheetTitle: 'INV.Change in unit cost',
|
|
100
|
-
header: getUnitCostDifferenceHeader(),
|
|
101
100
|
},
|
|
102
|
-
[EChartsInventory.INCONSISTENT_DATA]: { scheduled: false,
|
|
103
|
-
[EChartsInventory.INVENTORY_TURN]: {
|
|
104
|
-
|
|
105
|
-
|
|
101
|
+
[EChartsInventory.INCONSISTENT_DATA]: { scheduled: false, queryAPI: 'inconsistent-data', queryFunction: null },
|
|
102
|
+
[EChartsInventory.INVENTORY_TURN]: {
|
|
103
|
+
scheduled: true,
|
|
104
|
+
queryAPI: 'turn',
|
|
105
|
+
queryFunction: getInventoryTurnFull,
|
|
106
|
+
filterParams: EFilterParams.PERIOD,
|
|
107
|
+
sheetTitle: 'INV.Inventory turn',
|
|
108
|
+
},
|
|
109
|
+
[EChartsInventory.MOVEMENT]: { scheduled: false, queryAPI: 'movement', queryFunction: null },
|
|
110
|
+
[EChartsInventory.EXTENSION]: { scheduled: false, queryAPI: 'extension', queryFunction: null },
|
|
106
111
|
},
|
|
107
112
|
|
|
108
113
|
[EQueriesGroups.RECEIVABLE]: {
|
|
109
|
-
[EChartsReceivable.BENFORD]: { scheduled: false,
|
|
110
|
-
[EChartsReceivable.EXPOSURES]: { scheduled: false,
|
|
111
|
-
[EChartsReceivable.EXPOSURES_CUSTOMERS]: { scheduled: false,
|
|
112
|
-
[EChartsReceivable.DUPLICATES]: { scheduled: false,
|
|
113
|
-
[EChartsReceivable.AVERAGE_INVOICE]: { scheduled: false,
|
|
114
|
-
[EChartsReceivable.INVOICE_VALUE_PLOT]: { scheduled: false,
|
|
115
|
-
[EChartsReceivable.AGING_PLOT]: { scheduled: false,
|
|
116
|
-
[EChartsReceivable.INVOICE_DIFFERENCE]: { scheduled: false,
|
|
114
|
+
[EChartsReceivable.BENFORD]: { scheduled: false, queryAPI: 'benford', queryFunction: null },
|
|
115
|
+
[EChartsReceivable.EXPOSURES]: { scheduled: false, queryAPI: 'exposures', queryFunction: null },
|
|
116
|
+
[EChartsReceivable.EXPOSURES_CUSTOMERS]: { scheduled: false, queryAPI: 'exposures-customers', queryFunction: null },
|
|
117
|
+
[EChartsReceivable.DUPLICATES]: { scheduled: false, queryAPI: 'duplicates', queryFunction: null },
|
|
118
|
+
[EChartsReceivable.AVERAGE_INVOICE]: { scheduled: false, queryAPI: 'average-invoice', queryFunction: null },
|
|
119
|
+
[EChartsReceivable.INVOICE_VALUE_PLOT]: { scheduled: false, queryAPI: 'average-sku-values', queryFunction: null },
|
|
120
|
+
[EChartsReceivable.AGING_PLOT]: { scheduled: false, queryAPI: 'aging-plot', queryFunction: null },
|
|
121
|
+
[EChartsReceivable.INVOICE_DIFFERENCE]: { scheduled: false, queryAPI: 'invoice-difference', queryFunction: null },
|
|
117
122
|
[EChartsReceivable.PARTIALLY_PAID_RESTATED]: {
|
|
118
123
|
scheduled: false,
|
|
119
|
-
|
|
124
|
+
queryAPI: 'partially-paid-restated',
|
|
120
125
|
queryFunction: null,
|
|
121
126
|
},
|
|
122
|
-
[EChartsReceivable.AR_TURN]: { scheduled: false,
|
|
123
|
-
[EChartsReceivable.GROUP_CUSTOMERS]: { scheduled: false,
|
|
127
|
+
[EChartsReceivable.AR_TURN]: { scheduled: false, queryAPI: 'ar-turn', queryFunction: null },
|
|
128
|
+
[EChartsReceivable.GROUP_CUSTOMERS]: { scheduled: false, queryAPI: 'grouped-receivables', queryFunction: null },
|
|
124
129
|
},
|
|
125
130
|
|
|
126
131
|
[EQueriesGroups.OTHER]: {
|
|
127
|
-
[EChartsMisc.CONTRAS]: { scheduled: false,
|
|
132
|
+
[EChartsMisc.CONTRAS]: { scheduled: false, queryAPI: 'contras', queryFunction: null },
|
|
128
133
|
},
|
|
129
134
|
|
|
130
135
|
[EQueriesGroups.CASH]: {
|
|
131
|
-
[EChartsCash.TRANSACTIONS]: { scheduled: false,
|
|
132
|
-
[EChartsCash.DELUTION]: { scheduled: false,
|
|
136
|
+
[EChartsCash.TRANSACTIONS]: { scheduled: false, queryAPI: 'transactions', queryFunction: null },
|
|
137
|
+
[EChartsCash.DELUTION]: { scheduled: false, queryAPI: 'delution', queryFunction: null },
|
|
133
138
|
},
|
|
134
139
|
};
|
|
135
140
|
|
package/package.json
CHANGED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { TQueryParams } from '../../models/QueryResult.model';
|
|
2
|
+
export declare const getInventoryTurnFull: (params: TQueryParams) => Promise<{
|
|
3
|
+
'by unit': {}[];
|
|
4
|
+
'by value': {}[];
|
|
5
|
+
}>;
|
|
6
|
+
export declare const getInventoryTurn: (borrowerId: string, startDate: string, endDate: string) => Promise<{
|
|
7
|
+
tableByUnit: any[];
|
|
8
|
+
tableByValue: any[];
|
|
9
|
+
}>;
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.getInventoryTurn = exports.getInventoryTurnFull = void 0;
|
|
7
|
+
const decimal_js_1 = __importDefault(require("decimal.js"));
|
|
8
|
+
const dayjs_1 = __importDefault(require("dayjs"));
|
|
9
|
+
const bbcDates_db_1 = require("../../db/bbcDates.db");
|
|
10
|
+
const bbcSheets_db_1 = require("../../db/bbcSheets.db");
|
|
11
|
+
const collaterals_enum_1 = require("../../enums/collaterals.enum");
|
|
12
|
+
const collaterals_db_1 = require("../../db/collaterals.db");
|
|
13
|
+
const inventories_1 = require("../../db/inventories");
|
|
14
|
+
const excel_helper_1 = require("../../helpers/excel.helper");
|
|
15
|
+
const getInventoryTurnFull = async (params) => {
|
|
16
|
+
const { borrowerId, startDate, endDate } = params;
|
|
17
|
+
const { tableByUnit, tableByValue, } = await (0, exports.getInventoryTurn)(borrowerId.toString(), startDate.toISOString(), endDate.toISOString());
|
|
18
|
+
const headerByUnit = getInventoryTurnHeader('byUnit');
|
|
19
|
+
const headerByValue = getInventoryTurnHeader('byValue');
|
|
20
|
+
const tableByUnitFull = (0, excel_helper_1.addHeaderToData)(headerByUnit, tableByUnit);
|
|
21
|
+
const tableByValueFull = (0, excel_helper_1.addHeaderToData)(headerByValue, tableByValue);
|
|
22
|
+
return {
|
|
23
|
+
'by unit': tableByUnitFull, 'by value': tableByValueFull,
|
|
24
|
+
};
|
|
25
|
+
};
|
|
26
|
+
exports.getInventoryTurnFull = getInventoryTurnFull;
|
|
27
|
+
const getInventoryTurn = async (borrowerId, startDate, endDate) => {
|
|
28
|
+
const bbcDates = await (0, bbcDates_db_1.getBBCDatesForPeriod)(borrowerId, new Date(startDate), new Date(endDate));
|
|
29
|
+
const bbcIds = bbcDates.map((bbc) => bbc._id.toString());
|
|
30
|
+
const bbcSheets = await (0, bbcSheets_db_1.getBBCSheetsByType)(bbcIds, collaterals_enum_1.ECollaterals.INVENTORY);
|
|
31
|
+
const skuGroup = (await (0, inventories_1.getAllUniqSKUInRangeNew)(bbcSheets.map((bbcSheet) => bbcSheet._id.toString()))).pop();
|
|
32
|
+
const BBCs = await (0, collaterals_db_1.getCollateralDocsByBBC)(bbcIds, collaterals_enum_1.ECollaterals.INVENTORY);
|
|
33
|
+
return getDifference(skuGroup ? skuGroup.skus.sort() : [], BBCs);
|
|
34
|
+
};
|
|
35
|
+
exports.getInventoryTurn = getInventoryTurn;
|
|
36
|
+
const getDifference = (uniqSKUs, BBCs) => {
|
|
37
|
+
if (uniqSKUs) {
|
|
38
|
+
const groupedBbc = uniqSKUs.map((sku) => {
|
|
39
|
+
let minUnitCost = 0;
|
|
40
|
+
const totalSum = BBCs.map((bbc) => {
|
|
41
|
+
const skuItems = bbc.items.filter((item) => item.sku === sku);
|
|
42
|
+
const unitCosts = skuItems.map((item) => item.qty === 0 ? 0 : new decimal_js_1.default(item.value).div(item.qty).toNumber());
|
|
43
|
+
if (unitCosts.length) {
|
|
44
|
+
minUnitCost = Math.min(...unitCosts);
|
|
45
|
+
}
|
|
46
|
+
const sum = skuItems.reduce((acc, item) => new decimal_js_1.default(acc).add(item.qty).toNumber(), 0);
|
|
47
|
+
return { bbc: bbc.bbcDate, sum };
|
|
48
|
+
});
|
|
49
|
+
return { sku, totalSum, minUnitCost };
|
|
50
|
+
});
|
|
51
|
+
const groupedBbcWithDifferences = groupedBbc.map((group) => {
|
|
52
|
+
const differences = [];
|
|
53
|
+
group.totalSum.forEach((sumGroup, index) => {
|
|
54
|
+
if (index > 0) {
|
|
55
|
+
const firstDate = (0, dayjs_1.default)(group.totalSum[index - 1].bbc);
|
|
56
|
+
const lastDate = (0, dayjs_1.default)(sumGroup.bbc);
|
|
57
|
+
const diffDays = lastDate.diff(firstDate, 'day');
|
|
58
|
+
const diff = new decimal_js_1.default(group.totalSum[index - 1].sum).sub(sumGroup.sum).toNumber();
|
|
59
|
+
const diffPerDay = diffDays > 0 ? new decimal_js_1.default(diff).div(diffDays).toNumber() : 0;
|
|
60
|
+
differences.push({
|
|
61
|
+
bbc: sumGroup.bbc,
|
|
62
|
+
diff,
|
|
63
|
+
diffDays,
|
|
64
|
+
decreasePerDay: diffPerDay > 0 ? diffPerDay : 0,
|
|
65
|
+
increasePerDay: diffPerDay < 0 ? diffPerDay : 0,
|
|
66
|
+
});
|
|
67
|
+
}
|
|
68
|
+
});
|
|
69
|
+
return { ...group, differences };
|
|
70
|
+
});
|
|
71
|
+
const tableByUnit = [];
|
|
72
|
+
groupedBbcWithDifferences.forEach((group) => {
|
|
73
|
+
const totalDifference = group.differences.reduce((acc, group) => {
|
|
74
|
+
if (group.diff < 0) {
|
|
75
|
+
const diff = new decimal_js_1.default(acc.increasesOverPeriod).add(group.diff).toNumber();
|
|
76
|
+
return { ...acc, increasesOverPeriod: diff };
|
|
77
|
+
}
|
|
78
|
+
else {
|
|
79
|
+
const diff = new decimal_js_1.default(acc.decreasesOverPeriod).add(Math.abs(group.diff)).toNumber();
|
|
80
|
+
return { ...acc, decreasesOverPeriod: diff };
|
|
81
|
+
}
|
|
82
|
+
}, { increasesOverPeriod: 0, decreasesOverPeriod: 0 });
|
|
83
|
+
const { increasesOverPeriod, decreasesOverPeriod } = totalDifference;
|
|
84
|
+
const current = group.totalSum[group.totalSum.length - 1].sum;
|
|
85
|
+
const firstDate = (0, dayjs_1.default)(group.totalSum[0].bbc);
|
|
86
|
+
const lastDate = (0, dayjs_1.default)(group.totalSum[group.totalSum.length - 1].bbc);
|
|
87
|
+
const dayInRange = lastDate.diff(firstDate, 'day');
|
|
88
|
+
const averageIncreasesPerDay = new decimal_js_1.default(increasesOverPeriod).div(dayInRange).toNumber();
|
|
89
|
+
const averageDecreasesPerDay = new decimal_js_1.default(decreasesOverPeriod).div(dayInRange).toNumber();
|
|
90
|
+
// const increaseDiffs = group.differences.filter((diff) => diff.increasePerDay < 0);
|
|
91
|
+
// const decreaseDiffs = group.differences.filter((diff) => diff.decreasePerDay > 0);
|
|
92
|
+
// const averageIncreasePerDay_test = increaseDiffs.length > 0
|
|
93
|
+
// ? new Decimal(increaseDiffs.reduce((acc, diff) => new Decimal(diff.increasePerDay).add(acc).toNumber(), 0)).div(decreaseDiffs.length).toNumber()
|
|
94
|
+
// : 0;
|
|
95
|
+
// const averageDecreasesPerDay_test = decreaseDiffs.length > 0
|
|
96
|
+
// ? new Decimal(decreaseDiffs.reduce((acc, diff) => new Decimal(diff.decreasePerDay).add(acc).toNumber(), 0)).div(decreaseDiffs.length).toNumber()
|
|
97
|
+
// : 0;
|
|
98
|
+
const daysToClear = averageDecreasesPerDay === 0
|
|
99
|
+
? 0
|
|
100
|
+
: new decimal_js_1.default(current).div(averageDecreasesPerDay).toDP().toNumber();
|
|
101
|
+
const ranking = averageDecreasesPerDay === 0
|
|
102
|
+
? Math.round(averageIncreasesPerDay)
|
|
103
|
+
: new decimal_js_1.default(averageIncreasesPerDay).div(averageDecreasesPerDay).toDP().toNumber();
|
|
104
|
+
tableByUnit.push({
|
|
105
|
+
sku: group.sku,
|
|
106
|
+
current,
|
|
107
|
+
minUnitCost: group.minUnitCost,
|
|
108
|
+
increasesOverPeriod,
|
|
109
|
+
decreasesOverPeriod,
|
|
110
|
+
averageIncreasesPerDay,
|
|
111
|
+
averageDecreasesPerDay,
|
|
112
|
+
daysToClear,
|
|
113
|
+
ranking,
|
|
114
|
+
});
|
|
115
|
+
});
|
|
116
|
+
tableByUnit.sort((a, b) => a.ranking > b.ranking ? -1 : 0);
|
|
117
|
+
const tableByValue = [];
|
|
118
|
+
tableByUnit.forEach((unit) => {
|
|
119
|
+
const minUnitCost = unit.minUnitCost;
|
|
120
|
+
const current = new decimal_js_1.default(unit.current).mul(minUnitCost).toNumber();
|
|
121
|
+
const increasesOverPeriod = new decimal_js_1.default(unit.increasesOverPeriod).mul(minUnitCost).toNumber();
|
|
122
|
+
const decreasesOverPeriod = new decimal_js_1.default(unit.decreasesOverPeriod).mul(minUnitCost).toNumber();
|
|
123
|
+
const averageIncreasesPerDay = new decimal_js_1.default(unit.averageIncreasesPerDay).mul(minUnitCost).toNumber();
|
|
124
|
+
const averageDecreasesPerDay = new decimal_js_1.default(unit.averageDecreasesPerDay).mul(minUnitCost).toNumber();
|
|
125
|
+
const daysToClear = Math.round(new decimal_js_1.default(unit.daysToClear).mul(minUnitCost).toNumber());
|
|
126
|
+
const ranking = Math.round(new decimal_js_1.default(unit.ranking).mul(minUnitCost).toNumber());
|
|
127
|
+
tableByValue.push({
|
|
128
|
+
sku: unit.sku,
|
|
129
|
+
minUnitCost,
|
|
130
|
+
current,
|
|
131
|
+
increasesOverPeriod,
|
|
132
|
+
decreasesOverPeriod,
|
|
133
|
+
averageIncreasesPerDay,
|
|
134
|
+
averageDecreasesPerDay,
|
|
135
|
+
daysToClear,
|
|
136
|
+
ranking,
|
|
137
|
+
});
|
|
138
|
+
});
|
|
139
|
+
return { tableByUnit, tableByValue };
|
|
140
|
+
}
|
|
141
|
+
return { tableByUnit: [], tableByValue: [] };
|
|
142
|
+
};
|
|
143
|
+
const getInventoryTurnHeader = (type) => {
|
|
144
|
+
const headerMap = {
|
|
145
|
+
'byUnit': {
|
|
146
|
+
sku: 'SKU',
|
|
147
|
+
current: 'Current number of units',
|
|
148
|
+
increasesOverPeriod: 'Increases in units over period',
|
|
149
|
+
decreasesOverPeriod: 'Decreases in units over period',
|
|
150
|
+
averageIncreasesPerDay: 'Average increases in units per day',
|
|
151
|
+
averageDecreasesPerDay: 'Average decreases in units per day',
|
|
152
|
+
daysToClear: 'Days to clear',
|
|
153
|
+
ranking: 'Ranking',
|
|
154
|
+
},
|
|
155
|
+
'byValue': {
|
|
156
|
+
sku: 'SKU',
|
|
157
|
+
current: 'Current value',
|
|
158
|
+
minUnitCost: 'Min unit cost',
|
|
159
|
+
increasesOverPeriod: 'Increases over in value period',
|
|
160
|
+
decreasesOverPeriod: 'Decreases over in value period',
|
|
161
|
+
averageIncreasesPerDay: 'Average value increases per day',
|
|
162
|
+
averageDecreasesPerDay: 'Average value decreases per day',
|
|
163
|
+
daysToClear: 'Days to clear',
|
|
164
|
+
ranking: 'Ranking',
|
|
165
|
+
},
|
|
166
|
+
};
|
|
167
|
+
return headerMap[type];
|
|
168
|
+
};
|