gemcap-be-common 1.2.73 → 1.2.75

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.
@@ -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
+ };
@@ -0,0 +1,176 @@
1
+ import Decimal from 'decimal.js';
2
+ import dayjs from 'dayjs';
3
+
4
+ import { getBBCDatesForPeriod } from '../../db/bbcDates.db';
5
+ import { getBBCSheetsByType } from '../../db/bbcSheets.db';
6
+ import { ECollaterals } from '../../enums/collaterals.enum';
7
+ import { getCollateralDocsByBBC } from '../../db/collaterals.db';
8
+ import { getAllUniqSKUInRangeNew } from '../../db/inventories';
9
+ import { IInventoryItem } from '../../models/InventoryItem.model';
10
+ import { IBBCDateDoc } from '../../models/BBCDate.model';
11
+ import { TQueryParams } from '../../models/QueryResult.model';
12
+ import { addHeaderToData } from '../../helpers/excel.helper';
13
+
14
+ interface IGroupedCollaterals extends IBBCDateDoc {
15
+ items: IInventoryItem[];
16
+ }
17
+
18
+ export const getInventoryTurnFull = async (params: TQueryParams) => {
19
+ const { borrowerId, startDate, endDate } = params;
20
+ const {
21
+ tableByUnit,
22
+ tableByValue,
23
+ } = await getInventoryTurn(borrowerId.toString(), startDate.toISOString(), endDate.toISOString());
24
+ const headerByUnit = getInventoryTurnHeader('byUnit');
25
+ const headerByValue = getInventoryTurnHeader('byValue');
26
+
27
+ const tableByUnitFull = addHeaderToData(headerByUnit, tableByUnit);
28
+ const tableByValueFull = addHeaderToData(headerByValue, tableByValue);
29
+
30
+ return {
31
+ 'by unit': tableByUnitFull, 'by value': tableByValueFull,
32
+ };
33
+ };
34
+
35
+ export const getInventoryTurn = async (borrowerId: string, startDate: string, endDate: string) => {
36
+ const bbcDates = await getBBCDatesForPeriod(borrowerId, new Date(startDate), new Date(endDate));
37
+ const bbcIds = bbcDates.map((bbc) => bbc._id.toString());
38
+ const bbcSheets = await getBBCSheetsByType(bbcIds, ECollaterals.INVENTORY);
39
+ const skuGroup = (await getAllUniqSKUInRangeNew(bbcSheets.map((bbcSheet) => bbcSheet._id.toString()))).pop();
40
+ const BBCs: IGroupedCollaterals[] = await getCollateralDocsByBBC(bbcIds, ECollaterals.INVENTORY);
41
+ return getDifference(skuGroup ? skuGroup.skus.sort() : [], BBCs);
42
+ };
43
+
44
+ const getDifference = (uniqSKUs: string[], BBCs: IGroupedCollaterals[]) => {
45
+ if (uniqSKUs) {
46
+ const groupedBbc = uniqSKUs.map((sku) => {
47
+ let minUnitCost = 0;
48
+ const totalSum = BBCs.map((bbc) => {
49
+ const skuItems = bbc.items.filter((item) => item.sku === sku);
50
+ const unitCosts = skuItems.map((item) => item.qty === 0 ? 0 : new Decimal(item.value).div(item.qty).toNumber());
51
+ if (unitCosts.length) {
52
+ minUnitCost = Math.min(...unitCosts);
53
+ }
54
+ const sum = skuItems.reduce((acc, item) => new Decimal(acc).add(item.qty).toNumber(), 0);
55
+ return { bbc: bbc.bbcDate, sum };
56
+ });
57
+ return { sku, totalSum, minUnitCost };
58
+ });
59
+ const groupedBbcWithDifferences = groupedBbc.map((group) => {
60
+ const differences = [];
61
+ group.totalSum.forEach((sumGroup, index) => {
62
+ if (index > 0) {
63
+ const firstDate = dayjs(group.totalSum[index - 1].bbc);
64
+ const lastDate = dayjs(sumGroup.bbc);
65
+ const diffDays = lastDate.diff(firstDate, 'day');
66
+ const diff = new Decimal(group.totalSum[index - 1].sum).sub(sumGroup.sum).toNumber();
67
+ const diffPerDay = diffDays > 0 ? new Decimal(diff).div(diffDays).toNumber() : 0;
68
+ differences.push({
69
+ bbc: sumGroup.bbc,
70
+ diff,
71
+ diffDays,
72
+ decreasePerDay: diffPerDay > 0 ? diffPerDay : 0,
73
+ increasePerDay: diffPerDay < 0 ? diffPerDay : 0,
74
+ });
75
+ }
76
+ });
77
+ return { ...group, differences };
78
+ });
79
+ const tableByUnit = [];
80
+ groupedBbcWithDifferences.forEach((group) => {
81
+ const totalDifference = group.differences.reduce((acc, group) => {
82
+ if (group.diff < 0) {
83
+ const diff = new Decimal(acc.increasesOverPeriod).add(group.diff).toNumber();
84
+ return { ...acc, increasesOverPeriod: diff };
85
+ } else {
86
+ const diff = new Decimal(acc.decreasesOverPeriod).add(Math.abs(group.diff)).toNumber();
87
+ return { ...acc, decreasesOverPeriod: diff };
88
+ }
89
+ }, { increasesOverPeriod: 0, decreasesOverPeriod: 0 });
90
+ const { increasesOverPeriod, decreasesOverPeriod } = totalDifference;
91
+ const current = group.totalSum[group.totalSum.length - 1].sum;
92
+ const firstDate = dayjs(group.totalSum[0].bbc);
93
+ const lastDate = dayjs(group.totalSum[group.totalSum.length - 1].bbc);
94
+ const dayInRange = lastDate.diff(firstDate, 'day');
95
+ const averageIncreasesPerDay = new Decimal(increasesOverPeriod).div(dayInRange).toNumber();
96
+ const averageDecreasesPerDay = new Decimal(decreasesOverPeriod).div(dayInRange).toNumber();
97
+ // const increaseDiffs = group.differences.filter((diff) => diff.increasePerDay < 0);
98
+ // const decreaseDiffs = group.differences.filter((diff) => diff.decreasePerDay > 0);
99
+ // const averageIncreasePerDay_test = increaseDiffs.length > 0
100
+ // ? new Decimal(increaseDiffs.reduce((acc, diff) => new Decimal(diff.increasePerDay).add(acc).toNumber(), 0)).div(decreaseDiffs.length).toNumber()
101
+ // : 0;
102
+ // const averageDecreasesPerDay_test = decreaseDiffs.length > 0
103
+ // ? new Decimal(decreaseDiffs.reduce((acc, diff) => new Decimal(diff.decreasePerDay).add(acc).toNumber(), 0)).div(decreaseDiffs.length).toNumber()
104
+ // : 0;
105
+ const daysToClear = averageDecreasesPerDay === 0
106
+ ? 0
107
+ : new Decimal(current).div(averageDecreasesPerDay).toDP().toNumber();
108
+ const ranking = averageDecreasesPerDay === 0
109
+ ? Math.round(averageIncreasesPerDay)
110
+ : new Decimal(averageIncreasesPerDay).div(averageDecreasesPerDay).toDP().toNumber();
111
+ tableByUnit.push({
112
+ sku: group.sku,
113
+ current,
114
+ minUnitCost: group.minUnitCost,
115
+ increasesOverPeriod,
116
+ decreasesOverPeriod,
117
+ averageIncreasesPerDay,
118
+ averageDecreasesPerDay,
119
+ daysToClear,
120
+ ranking,
121
+ });
122
+ });
123
+ tableByUnit.sort((a, b) => a.ranking > b.ranking ? -1 : 0);
124
+ const tableByValue = [];
125
+ tableByUnit.forEach((unit) => {
126
+ const minUnitCost = unit.minUnitCost;
127
+ const current = new Decimal(unit.current).mul(minUnitCost).toNumber();
128
+ const increasesOverPeriod = new Decimal(unit.increasesOverPeriod).mul(minUnitCost).toNumber();
129
+ const decreasesOverPeriod = new Decimal(unit.decreasesOverPeriod).mul(minUnitCost).toNumber();
130
+ const averageIncreasesPerDay = new Decimal(unit.averageIncreasesPerDay).mul(minUnitCost).toNumber();
131
+ const averageDecreasesPerDay = new Decimal(unit.averageDecreasesPerDay).mul(minUnitCost).toNumber();
132
+ const daysToClear = Math.round(new Decimal(unit.daysToClear).mul(minUnitCost).toNumber());
133
+ const ranking = Math.round(new Decimal(unit.ranking).mul(minUnitCost).toNumber());
134
+ tableByValue.push({
135
+ sku: unit.sku,
136
+ minUnitCost,
137
+ current,
138
+ increasesOverPeriod,
139
+ decreasesOverPeriod,
140
+ averageIncreasesPerDay,
141
+ averageDecreasesPerDay,
142
+ daysToClear,
143
+ ranking,
144
+ });
145
+ });
146
+ return { tableByUnit, tableByValue };
147
+ }
148
+ return { tableByUnit: [], tableByValue: [] };
149
+ };
150
+
151
+ const getInventoryTurnHeader = (type: 'byUnit' | 'byValue') => {
152
+ const headerMap = {
153
+ 'byUnit': {
154
+ sku: 'SKU',
155
+ current: 'Current number of units',
156
+ increasesOverPeriod: 'Increases in units over period',
157
+ decreasesOverPeriod: 'Decreases in units over period',
158
+ averageIncreasesPerDay: 'Average increases in units per day',
159
+ averageDecreasesPerDay: 'Average decreases in units per day',
160
+ daysToClear: 'Days to clear',
161
+ ranking: 'Ranking',
162
+ },
163
+ 'byValue': {
164
+ sku: 'SKU',
165
+ current: 'Current value',
166
+ minUnitCost: 'Min unit cost',
167
+ increasesOverPeriod: 'Increases over in value period',
168
+ decreasesOverPeriod: 'Decreases over in value period',
169
+ averageIncreasesPerDay: 'Average value increases per day',
170
+ averageDecreasesPerDay: 'Average value decreases per day',
171
+ daysToClear: 'Days to clear',
172
+ ranking: 'Ranking',
173
+ },
174
+ };
175
+ return headerMap[type];
176
+ };
@@ -1,4 +1,5 @@
1
1
  import { TQueryParams } from '../../models/QueryResult.model';
2
+ export declare const getUnitCostDifferenceFull: (params: TQueryParams) => Promise<{}[]>;
2
3
  export declare const getUnitCostDifference: (params: TQueryParams) => Promise<{
3
4
  SKU: string;
4
5
  CURRENT_UNIT_COST: number;
@@ -8,12 +9,3 @@ export declare const getUnitCostDifference: (params: TQueryParams) => Promise<{
8
9
  CURRENT_QTY: number;
9
10
  VALUE_CHANGE: number;
10
11
  }[]>;
11
- export declare const getUnitCostDifferenceHeader: () => {
12
- SKU: string;
13
- CURRENT_QTY: string;
14
- CURRENT_UNIT_COST: string;
15
- LOWEST_UNIT_COST: string;
16
- LOWEST_UNIT_COST_DATE: string;
17
- DIFFERENCE: string;
18
- VALUE_CHANGE: string;
19
- };
@@ -3,12 +3,19 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
3
3
  return (mod && mod.__esModule) ? mod : { "default": mod };
4
4
  };
5
5
  Object.defineProperty(exports, "__esModule", { value: true });
6
- exports.getUnitCostDifferenceHeader = exports.getUnitCostDifference = void 0;
6
+ exports.getUnitCostDifference = exports.getUnitCostDifferenceFull = void 0;
7
7
  const mongoose_1 = __importDefault(require("mongoose"));
8
8
  const decimal_js_1 = __importDefault(require("decimal.js"));
9
9
  const collaterals_db_1 = require("../../db/collaterals.db");
10
10
  const collaterals_enum_1 = require("../../enums/collaterals.enum");
11
11
  const inventories_1 = require("../../db/inventories");
12
+ const excel_helper_1 = require("../../helpers/excel.helper");
13
+ const getUnitCostDifferenceFull = async (params) => {
14
+ const data = await (0, exports.getUnitCostDifference)(params);
15
+ const header = getUnitCostDifferenceHeader();
16
+ return (0, excel_helper_1.addHeaderToData)(header, data);
17
+ };
18
+ exports.getUnitCostDifferenceFull = getUnitCostDifferenceFull;
12
19
  const getUnitCostDifference = async (params) => {
13
20
  const { borrowerId } = params;
14
21
  const bbcGroups = await (0, collaterals_db_1.findCollateralsWithSheets)(borrowerId.toString(), [collaterals_enum_1.ECollaterals.INVENTORY]);
@@ -42,4 +49,3 @@ const getUnitCostDifferenceHeader = () => {
42
49
  VALUE_CHANGE: 'Value change',
43
50
  };
44
51
  };
45
- exports.getUnitCostDifferenceHeader = getUnitCostDifferenceHeader;
@@ -5,6 +5,13 @@ import { findCollateralsWithSheets } from '../../db/collaterals.db';
5
5
  import { ECollaterals } from '../../enums/collaterals.enum';
6
6
  import { getSKUUnitCostForAllDates } from '../../db/inventories';
7
7
  import { TQueryParams } from '../../models/QueryResult.model';
8
+ import { addHeaderToData } from '../../helpers/excel.helper';
9
+
10
+ export const getUnitCostDifferenceFull = async (params: TQueryParams) => {
11
+ const data = await getUnitCostDifference(params);
12
+ const header = getUnitCostDifferenceHeader();
13
+ return addHeaderToData(header, data);
14
+ };
8
15
 
9
16
  export const getUnitCostDifference = async (params: TQueryParams) => {
10
17
  const { borrowerId } = params;
@@ -28,7 +35,7 @@ export const getUnitCostDifference = async (params: TQueryParams) => {
28
35
  .sort((a, b) => a.VALUE_CHANGE > b.VALUE_CHANGE ? -1 : 0);
29
36
  };
30
37
 
31
- export const getUnitCostDifferenceHeader = () => {
38
+ const getUnitCostDifferenceHeader = () => {
32
39
  return {
33
40
  SKU: 'SKU',
34
41
  CURRENT_QTY: 'qty',