gemcap-be-common 1.2.90 → 1.2.92

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.
Files changed (35) hide show
  1. package/db/collaterals.db.d.ts +12 -1
  2. package/db/collaterals.db.js +101 -1
  3. package/db/collaterals.db.ts +110 -5
  4. package/db/groups.db.d.ts +45 -0
  5. package/db/groups.db.js +22 -0
  6. package/db/groups.db.ts +20 -0
  7. package/db/receivables.db.d.ts +10 -0
  8. package/db/receivables.db.ts +11 -0
  9. package/models/CustomerGroup.model.d.ts +29 -0
  10. package/models/CustomerGroup.model.js +25 -0
  11. package/models/CustomerGroup.model.ts +31 -0
  12. package/models/QueryResult.model.d.ts +3 -0
  13. package/models/QueryResult.model.js +13 -3
  14. package/models/QueryResult.model.ts +14 -3
  15. package/package.json +1 -1
  16. package/queries/inventory/extension.js +2 -2
  17. package/queries/inventory/extension.ts +1 -1
  18. package/queries/inventory/inconsistent-data.js +2 -2
  19. package/queries/inventory/inconsistent-data.ts +1 -1
  20. package/queries/inventory/movement.js +2 -2
  21. package/queries/inventory/movement.ts +1 -1
  22. package/queries/inventory/turn.js +2 -2
  23. package/queries/inventory/turn.ts +1 -1
  24. package/queries/inventory/unit-cost-difference.js +2 -2
  25. package/queries/inventory/unit-cost-difference.ts +1 -1
  26. package/queries/receivable/grouped-receivables.d.ts +5 -0
  27. package/queries/receivable/grouped-receivables.js +76 -0
  28. package/queries/receivable/grouped-receivables.ts +85 -0
  29. package/queries/receivable/partially-paid-restated.d.ts +12 -0
  30. package/queries/receivable/partially-paid-restated.js +131 -0
  31. package/queries/receivable/partially-paid-restated.ts +148 -0
  32. package/tsconfig.tsbuildinfo +1 -1
  33. /package/db/{inventories.d.ts → inventories.db.d.ts} +0 -0
  34. /package/db/{inventories.js → inventories.db.js} +0 -0
  35. /package/db/{inventories.ts → inventories.db.ts} +0 -0
@@ -6,7 +6,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
6
6
  exports.getInconsistentData = exports.getInconsistentDataFull = void 0;
7
7
  const decimal_js_1 = __importDefault(require("decimal.js"));
8
8
  const numbers_helper_1 = require("../../helpers/numbers.helper");
9
- const inventories_1 = require("../../db/inventories");
9
+ const inventories_db_1 = require("../../db/inventories.db");
10
10
  const excel_helper_1 = require("../../helpers/excel.helper");
11
11
  const getInconsistentDataFull = async (params) => {
12
12
  const data = await (0, exports.getInconsistentData)(params);
@@ -16,7 +16,7 @@ const getInconsistentDataFull = async (params) => {
16
16
  exports.getInconsistentDataFull = getInconsistentDataFull;
17
17
  const getInconsistentData = async (params) => {
18
18
  const { bbcDateId } = params;
19
- const data = await (0, inventories_1.getSKUQtyValueUnitCost)(bbcDateId.toString());
19
+ const data = await (0, inventories_db_1.getSKUQtyValueUnitCost)(bbcDateId.toString());
20
20
  const formattedData = data.map((i) => {
21
21
  const calculatedUnitCost = (0, numbers_helper_1.round)(i.value / i.qty);
22
22
  const difference = i.unitCost - calculatedUnitCost;
@@ -1,7 +1,7 @@
1
1
  import Decimal from 'decimal.js';
2
2
 
3
3
  import { round } from '../../helpers/numbers.helper';
4
- import { getSKUQtyValueUnitCost } from '../../db/inventories';
4
+ import { getSKUQtyValueUnitCost } from '../../db/inventories.db';
5
5
  import { TQueryParams } from '../../models/QueryResult.model';
6
6
  import { addHeaderToData } from '../../helpers/excel.helper';
7
7
 
@@ -4,7 +4,7 @@ exports.getUnitCostDifferenceHeader = exports.getInvoiceMovement = exports.getIn
4
4
  const excel_helper_1 = require("../../helpers/excel.helper");
5
5
  const BBCDate_model_1 = require("../../models/BBCDate.model");
6
6
  const collaterals_db_1 = require("../../db/collaterals.db");
7
- const inventories_1 = require("../../db/inventories");
7
+ const inventories_db_1 = require("../../db/inventories.db");
8
8
  const collaterals_enum_1 = require("../../enums/collaterals.enum");
9
9
  const getInvoiceMovementFull = async (params) => {
10
10
  const { reportAdditions, reportRemoved } = await (0, exports.getInvoiceMovement)(params);
@@ -21,7 +21,7 @@ const getInvoiceMovement = async (params) => {
21
21
  if (currentBbcDate) {
22
22
  const previousDocuments = await (0, collaterals_db_1.getPreviousCollateralDocument)(currentBbcDate.borrowerId.toString(), currentBbcDate.bbcDate, collaterals_enum_1.ECollaterals.INVENTORY, 1);
23
23
  if (previousDocuments.length > 0) {
24
- return (0, inventories_1.getInventoryMovement)(borrowerId.toString(), previousDocuments[0].bbcDate.toString(), currentBbcDate.bbcDate.toString());
24
+ return (0, inventories_db_1.getInventoryMovement)(borrowerId.toString(), previousDocuments[0].bbcDate.toString(), currentBbcDate.bbcDate.toString());
25
25
  }
26
26
  }
27
27
  return { reportAdditions: [], reportRemoved: [] };
@@ -2,7 +2,7 @@ import { TQueryParams } from '../../models/QueryResult.model';
2
2
  import { addHeaderToData } from '../../helpers/excel.helper';
3
3
  import { BBCDateModel } from '../../models/BBCDate.model';
4
4
  import { getPreviousCollateralDocument } from '../../db/collaterals.db';
5
- import { getInventoryMovement } from '../../db/inventories';
5
+ import { getInventoryMovement } from '../../db/inventories.db';
6
6
  import { ECollaterals } from '../../enums/collaterals.enum';
7
7
 
8
8
  export const getInvoiceMovementFull = async (params: TQueryParams) => {
@@ -10,8 +10,8 @@ const bbcDates_db_1 = require("../../db/bbcDates.db");
10
10
  const bbcSheets_db_1 = require("../../db/bbcSheets.db");
11
11
  const collaterals_enum_1 = require("../../enums/collaterals.enum");
12
12
  const collaterals_db_1 = require("../../db/collaterals.db");
13
- const inventories_1 = require("../../db/inventories");
14
13
  const excel_helper_1 = require("../../helpers/excel.helper");
14
+ const inventories_db_1 = require("../../db/inventories.db");
15
15
  const getInventoryTurnFull = async (params) => {
16
16
  const { tableByUnit, tableByValue } = await (0, exports.getInventoryTurn)(params);
17
17
  const headerByUnit = getInventoryTurnHeader('byUnit');
@@ -26,7 +26,7 @@ const getInventoryTurn = async (params) => {
26
26
  const bbcDates = await (0, bbcDates_db_1.getBBCDatesForPeriod)(borrowerId.toString(), new Date(startDate), new Date(endDate));
27
27
  const bbcIds = bbcDates.map((bbc) => bbc._id.toString());
28
28
  const bbcSheets = await (0, bbcSheets_db_1.getBBCSheetsByType)(bbcIds, collaterals_enum_1.ECollaterals.INVENTORY);
29
- const skuGroup = (await (0, inventories_1.getAllUniqSKUInRangeNew)(bbcSheets.map((bbcSheet) => bbcSheet._id.toString()))).pop();
29
+ const skuGroup = (await (0, inventories_db_1.getAllUniqSKUInRangeNew)(bbcSheets.map((bbcSheet) => bbcSheet._id.toString()))).pop();
30
30
  const BBCs = await (0, collaterals_db_1.getCollateralDocsByBBC)(bbcIds, collaterals_enum_1.ECollaterals.INVENTORY);
31
31
  return getDifference(skuGroup ? skuGroup.skus.sort() : [], BBCs);
32
32
  };
@@ -5,11 +5,11 @@ import { getBBCDatesForPeriod } from '../../db/bbcDates.db';
5
5
  import { getBBCSheetsByType } from '../../db/bbcSheets.db';
6
6
  import { ECollaterals } from '../../enums/collaterals.enum';
7
7
  import { getCollateralDocsByBBC } from '../../db/collaterals.db';
8
- import { getAllUniqSKUInRangeNew } from '../../db/inventories';
9
8
  import { IInventoryItem } from '../../models/InventoryItem.model';
10
9
  import { IBBCDateDoc } from '../../models/BBCDate.model';
11
10
  import { TQueryParams } from '../../models/QueryResult.model';
12
11
  import { addHeaderToData } from '../../helpers/excel.helper';
12
+ import { getAllUniqSKUInRangeNew } from '../../db/inventories.db';
13
13
 
14
14
  interface IGroupedCollaterals extends IBBCDateDoc {
15
15
  items: IInventoryItem[];
@@ -8,8 +8,8 @@ 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
- const inventories_1 = require("../../db/inventories");
12
11
  const excel_helper_1 = require("../../helpers/excel.helper");
12
+ const inventories_db_1 = require("../../db/inventories.db");
13
13
  const getUnitCostDifferenceFull = async (params) => {
14
14
  const data = await (0, exports.getUnitCostDifference)(params);
15
15
  const header = getUnitCostDifferenceHeader();
@@ -20,7 +20,7 @@ const getUnitCostDifference = async (params) => {
20
20
  const { borrowerId } = params;
21
21
  const bbcGroups = await (0, collaterals_db_1.findCollateralsWithSheets)(borrowerId.toString(), [collaterals_enum_1.ECollaterals.INVENTORY]);
22
22
  const sheetIds = bbcGroups.reduce((acc, bbcGroup) => [...acc, ...bbcGroup.sheets.map((sheet) => new mongoose_1.default.Types.ObjectId(sheet._id))], []);
23
- const data = await (0, inventories_1.getSKUUnitCostForAllDates)(sheetIds);
23
+ const data = await (0, inventories_db_1.getSKUUnitCostForAllDates)(sheetIds);
24
24
  const mappedData = data.map((i) => {
25
25
  const difference = new decimal_js_1.default(i.currentCost).sub(i.minCost.minCost).toDP(4).toNumber();
26
26
  return {
@@ -3,9 +3,9 @@ import Decimal from 'decimal.js';
3
3
 
4
4
  import { findCollateralsWithSheets } from '../../db/collaterals.db';
5
5
  import { ECollaterals } from '../../enums/collaterals.enum';
6
- import { getSKUUnitCostForAllDates } from '../../db/inventories';
7
6
  import { TQueryParams } from '../../models/QueryResult.model';
8
7
  import { addHeaderToData } from '../../helpers/excel.helper';
8
+ import { getSKUUnitCostForAllDates } from '../../db/inventories.db';
9
9
 
10
10
  export const getUnitCostDifferenceFull = async (params: TQueryParams) => {
11
11
  const data = await getUnitCostDifference(params);
@@ -0,0 +1,5 @@
1
+ import { TQueryParams } from '../../models/QueryResult.model';
2
+ export declare const getGroupedReceivablesFull: (params: TQueryParams) => Promise<{}[]>;
3
+ export declare const getGroupedReceivables: (params: TQueryParams) => Promise<{
4
+ [x: string]: any[];
5
+ }[]>;
@@ -0,0 +1,76 @@
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.getGroupedReceivables = exports.getGroupedReceivablesFull = void 0;
7
+ const dayjs_1 = __importDefault(require("dayjs"));
8
+ const excel_helper_1 = require("../../helpers/excel.helper");
9
+ const collaterals_db_1 = require("../../db/collaterals.db");
10
+ const collaterals_enum_1 = require("../../enums/collaterals.enum");
11
+ const mongoose_1 = __importDefault(require("mongoose"));
12
+ const column_desciptions_helper_1 = require("../../helpers/column-desciptions.helper");
13
+ const BBCDate_model_1 = require("../../models/BBCDate.model");
14
+ const partially_paid_restated_1 = require("./partially-paid-restated");
15
+ const getGroupedReceivablesFull = async (params) => {
16
+ const data = await (0, exports.getGroupedReceivables)(params);
17
+ const header = getGroupedReceivablesHeader();
18
+ return (0, excel_helper_1.addHeaderToData)(header, data);
19
+ };
20
+ exports.getGroupedReceivablesFull = getGroupedReceivablesFull;
21
+ const getGroupedReceivables = async (params) => {
22
+ const { borrowerId, bbcDateId, extraParams } = params;
23
+ console.log(extraParams.someParam);
24
+ const { calculateDueDate } = extraParams;
25
+ const sheets = await (0, collaterals_db_1.findCollateralSheets)(bbcDateId.toString(), collaterals_enum_1.ECollaterals.RECEIVABLE);
26
+ return await Promise.all(sheets.map(async (sheet) => {
27
+ const data = await (0, collaterals_db_1.findCollaterals)(sheet._id.toString(), false);
28
+ const customerTitleIndex = column_desciptions_helper_1.COLLATERALS[collaterals_enum_1.ECollaterals.RECEIVABLE].findIndex((column) => column.db_title === 'customerTitle');
29
+ const columnsShort = column_desciptions_helper_1.COLLATERALS[collaterals_enum_1.ECollaterals.RECEIVABLE]
30
+ .map((c) => ({ db_title: c.db_title, title: c.title }))
31
+ .filter((c) => c.db_title !== 'bbcDate');
32
+ columnsShort.splice(customerTitleIndex, 0, { db_title: 'customerGroup', title: 'Customer group' });
33
+ columnsShort.push({ db_title: 'partiallyPaid', title: 'Partially paid' });
34
+ const columnDB = columnsShort.map((c) => c.db_title);
35
+ const bbcDate = await BBCDate_model_1.BBCDateModel.findById(bbcDateId).lean();
36
+ const startDate = (0, dayjs_1.default)(new Date(bbcDate.bbcDate)).subtract(180, 'day').toDate();
37
+ const endDate = new Date(bbcDate.bbcDate);
38
+ const { partiallyPaidInvoices } = await (0, partially_paid_restated_1.getPartialPaid)({ borrowerId: new mongoose_1.default.Types.ObjectId(borrowerId), startDate, endDate });
39
+ const dataWithPartiallyPaid = data.map((invoice) => {
40
+ let partiallyPaid = false;
41
+ const foundInvoice = partiallyPaidInvoices.find((pInvoice) => {
42
+ return (pInvoice.invoiceNumber === invoice.invoiceNumber) && (pInvoice.customer === invoice.customerTitle);
43
+ });
44
+ if (foundInvoice) {
45
+ partiallyPaid = foundInvoice.difference > 0;
46
+ }
47
+ if ((invoice.originalAmount !== 0) && (invoice.originalAmount !== invoice.invoiceAmount)) {
48
+ partiallyPaid = true;
49
+ }
50
+ return {
51
+ ...invoice,
52
+ partiallyPaid,
53
+ dueDate: calculateDueDate ? (0, dayjs_1.default)(invoice.invoiceDate).utcOffset(0).add(90, 'days').toDate() : invoice.dueDate,
54
+ };
55
+ });
56
+ const shortData = (0, collaterals_db_1.excludeNoDataColumns)(dataWithPartiallyPaid, columnDB);
57
+ const dataWithGroups = await (0, collaterals_db_1.addCustomerGroups)(shortData, borrowerId.toString());
58
+ return { [sheet.sheetName]: dataWithGroups };
59
+ }));
60
+ };
61
+ exports.getGroupedReceivables = getGroupedReceivables;
62
+ const getGroupedReceivablesHeader = () => {
63
+ return {
64
+ sheetName: 'Sheet name',
65
+ invoiceNumber: 'Invoice number',
66
+ invoiceDate: 'Invoice date',
67
+ customerTitle: 'Customer title',
68
+ customerGroup: 'Customer group',
69
+ invoiceAmount: 'Invoice amount',
70
+ dueDate: 'Due date',
71
+ invoiceDetail1: 'Invoice detail 1',
72
+ invoiceDetail2: 'Invoice detail 2',
73
+ invoiceDetail3: 'Invoice detail 3',
74
+ partiallyPaid: 'Partially paid',
75
+ };
76
+ };
@@ -0,0 +1,85 @@
1
+ import dayjs from 'dayjs';
2
+
3
+ import { TQueryParams } from '../../models/QueryResult.model';
4
+ import { addHeaderToData } from '../../helpers/excel.helper';
5
+ import {
6
+ addCustomerGroups,
7
+ excludeNoDataColumns,
8
+ findCollaterals,
9
+ findCollateralSheets,
10
+ } from '../../db/collaterals.db';
11
+ import { ECollaterals } from '../../enums/collaterals.enum';
12
+ import mongoose from 'mongoose';
13
+ import { COLLATERALS } from '../../helpers/column-desciptions.helper';
14
+ import { BBCDateModel } from '../../models/BBCDate.model';
15
+ import { getPartialPaid } from './partially-paid-restated';
16
+
17
+ export const getGroupedReceivablesFull = async (params: TQueryParams) => {
18
+ const data = await getGroupedReceivables(params);
19
+ const header = getGroupedReceivablesHeader();
20
+ return addHeaderToData(header, data);
21
+ };
22
+
23
+ export const getGroupedReceivables = async (params: TQueryParams) => {
24
+ const { borrowerId, bbcDateId, extraParams } = params;
25
+ console.log(extraParams.someParam);
26
+ const { calculateDueDate } = <{ calculateDueDate: boolean }>extraParams;
27
+ const sheets = await findCollateralSheets(bbcDateId.toString(), ECollaterals.RECEIVABLE);
28
+
29
+ return await Promise.all(sheets.map(async (sheet) => {
30
+ const data: any[] = await findCollaterals(sheet._id.toString(), false);
31
+ const customerTitleIndex = COLLATERALS[ECollaterals.RECEIVABLE].findIndex((column) => column.db_title === 'customerTitle');
32
+
33
+ const columnsShort = COLLATERALS[ECollaterals.RECEIVABLE]
34
+ .map((c) => ({ db_title: c.db_title, title: c.title }))
35
+ .filter((c) => c.db_title !== 'bbcDate');
36
+ columnsShort.splice(customerTitleIndex, 0, { db_title: 'customerGroup', title: 'Customer group' });
37
+ columnsShort.push({ db_title: 'partiallyPaid', title: 'Partially paid' });
38
+
39
+ const columnDB = columnsShort.map((c) => c.db_title);
40
+
41
+ const bbcDate = await BBCDateModel.findById(bbcDateId).lean();
42
+ const startDate = dayjs(new Date(bbcDate.bbcDate)).subtract(180, 'day').toDate();
43
+ const endDate = new Date(bbcDate.bbcDate);
44
+
45
+ const { partiallyPaidInvoices } = await getPartialPaid({ borrowerId: new mongoose.Types.ObjectId(borrowerId), startDate, endDate });
46
+
47
+ const dataWithPartiallyPaid = data.map((invoice) => {
48
+ let partiallyPaid = false;
49
+ const foundInvoice = partiallyPaidInvoices.find((pInvoice) => {
50
+ return (pInvoice.invoiceNumber === invoice.invoiceNumber) && (pInvoice.customer === invoice.customerTitle);
51
+ });
52
+ if (foundInvoice) {
53
+ partiallyPaid = foundInvoice.difference > 0;
54
+ }
55
+ if ((invoice.originalAmount !== 0) && (invoice.originalAmount !== invoice.invoiceAmount)) {
56
+ partiallyPaid = true;
57
+ }
58
+ return {
59
+ ...invoice,
60
+ partiallyPaid,
61
+ dueDate: calculateDueDate ? dayjs(invoice.invoiceDate).utcOffset(0).add(90, 'days').toDate() : invoice.dueDate,
62
+ };
63
+ });
64
+
65
+ const shortData = excludeNoDataColumns(dataWithPartiallyPaid, columnDB);
66
+ const dataWithGroups = await addCustomerGroups(shortData, borrowerId.toString());
67
+ return { [sheet.sheetName]: dataWithGroups };
68
+ }));
69
+ };
70
+
71
+ const getGroupedReceivablesHeader = () => {
72
+ return {
73
+ sheetName: 'Sheet name',
74
+ invoiceNumber: 'Invoice number',
75
+ invoiceDate: 'Invoice date',
76
+ customerTitle: 'Customer title',
77
+ customerGroup: 'Customer group',
78
+ invoiceAmount: 'Invoice amount',
79
+ dueDate: 'Due date',
80
+ invoiceDetail1: 'Invoice detail 1',
81
+ invoiceDetail2: 'Invoice detail 2',
82
+ invoiceDetail3: 'Invoice detail 3',
83
+ partiallyPaid: 'Partially paid',
84
+ };
85
+ };
@@ -0,0 +1,12 @@
1
+ import { TQueryParams } from '../../models/QueryResult.model';
2
+ import { IPartiallyPaidInvoice } from '../../db/receivables.db';
3
+ export declare const getPartialPaidFull: (params: TQueryParams) => Promise<{
4
+ suspicious: {}[];
5
+ restated: {}[];
6
+ 'partially paid': {}[];
7
+ }>;
8
+ export declare const getPartialPaid: (params: TQueryParams) => Promise<{
9
+ suspiciousInvoices: IPartiallyPaidInvoice[];
10
+ restatedInvoices: IPartiallyPaidInvoice[];
11
+ partiallyPaidInvoices: IPartiallyPaidInvoice[];
12
+ }>;
@@ -0,0 +1,131 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getPartialPaid = exports.getPartialPaidFull = void 0;
4
+ const excel_helper_1 = require("../../helpers/excel.helper");
5
+ const bbcSheets_db_1 = require("../../db/bbcSheets.db");
6
+ const receivables_db_1 = require("../../db/receivables.db");
7
+ const collaterals_enum_1 = require("../../enums/collaterals.enum");
8
+ const getPartialPaidFull = async (params) => {
9
+ const { suspiciousInvoices, restatedInvoices, partiallyPaidInvoices } = await (0, exports.getPartialPaid)(params);
10
+ const header = getPartialPaidHeader();
11
+ const suspiciousInvoicesFull = (0, excel_helper_1.addHeaderToData)(header, suspiciousInvoices);
12
+ const restatedInvoicesFull = (0, excel_helper_1.addHeaderToData)(header, restatedInvoices);
13
+ const partiallyPaidInvoicesFull = (0, excel_helper_1.addHeaderToData)(header, partiallyPaidInvoices);
14
+ return {
15
+ 'suspicious': suspiciousInvoicesFull,
16
+ 'restated': restatedInvoicesFull,
17
+ 'partially paid': partiallyPaidInvoicesFull,
18
+ };
19
+ };
20
+ exports.getPartialPaidFull = getPartialPaidFull;
21
+ const getPartialPaid = async (params) => {
22
+ const { borrowerId, startDate, endDate } = params;
23
+ const allInventoryBbcDates = await (0, bbcSheets_db_1.getUniqueDatesForPeriod)(borrowerId.toString(), collaterals_enum_1.ECollaterals.RECEIVABLE, new Date(startDate), new Date(endDate));
24
+ const sheetIds = allInventoryBbcDates.reduce((acc, bbc) => [...acc, ...bbc.ids], []);
25
+ const allInvoices = await (0, receivables_db_1.getPartialPaidTable)(sheetIds);
26
+ const groupedInvoices = allInvoices.reduce((acc, i) => {
27
+ acc[i.invoiceNumber] = acc[i.invoiceNumber] || [];
28
+ acc[i.invoiceNumber].push(i);
29
+ return acc;
30
+ }, {});
31
+ const getInvoiceDifference = (invoices) => {
32
+ const invoice1 = invoices[0];
33
+ const invoice2 = invoices[invoices.length - 1];
34
+ return {
35
+ invoiceNumber: invoice1.invoiceNumber,
36
+ invoiceDate: invoice1.invoiceDate,
37
+ customer: invoice1.customerTitle,
38
+ originalAmount: invoice1.invoiceAmount,
39
+ restatedAmount: invoice2.invoiceAmount,
40
+ changeCounter: invoices.length - 1,
41
+ lastChangeDate: invoice2.bbc.bbcDate,
42
+ difference: +Math.abs(invoice1.invoiceAmount - invoice2.invoiceAmount).toFixed(3),
43
+ };
44
+ };
45
+ const getInvoiceChain = (invoices) => {
46
+ let firstInvoice = null;
47
+ let lastInvoice = null;
48
+ const invoiceChain = [];
49
+ let lastMatchIndex = 0;
50
+ let shouldSkip = false;
51
+ invoices.forEach((invoice, index) => {
52
+ if (shouldSkip) {
53
+ return;
54
+ }
55
+ if (firstInvoice === null) {
56
+ firstInvoice = { ...invoice };
57
+ invoiceChain.push(firstInvoice);
58
+ return;
59
+ }
60
+ lastInvoice = { ...invoice };
61
+ if (lastInvoice.invoiceAmount === firstInvoice.invoiceAmount ||
62
+ lastInvoice.invoiceAmount === invoices[index - 1].invoiceAmount) {
63
+ lastMatchIndex = index;
64
+ return;
65
+ }
66
+ if (lastInvoice.invoiceAmount > firstInvoice.invoiceAmount &&
67
+ lastInvoice.invoiceAmount > invoices[index - 1].invoiceAmount ||
68
+ lastInvoice.invoiceAmount < firstInvoice.invoiceAmount &&
69
+ lastInvoice.invoiceAmount < invoices[index - 1].invoiceAmount) {
70
+ invoiceChain.push(lastInvoice);
71
+ lastMatchIndex = index;
72
+ return;
73
+ }
74
+ if (lastInvoice.invoiceAmount > firstInvoice.invoiceAmount &&
75
+ lastInvoice.invoiceAmount < invoices[index - 1].invoiceAmount ||
76
+ lastInvoice.invoiceAmount < firstInvoice.invoiceAmount &&
77
+ lastInvoice.invoiceAmount > invoices[index - 1].invoiceAmount) {
78
+ shouldSkip = true;
79
+ return;
80
+ }
81
+ });
82
+ return { invoiceChain, lastMatchIndex };
83
+ };
84
+ const megaChain = [];
85
+ const suspiciousInvoices = [];
86
+ const restatedInvoices = [];
87
+ const partiallyPaidInvoices = [];
88
+ Object.keys(groupedInvoices).forEach((invoiceNumber) => {
89
+ const invoices = [...groupedInvoices[invoiceNumber]];
90
+ const invoiceChains = [];
91
+ let totalIndex = 0;
92
+ while (totalIndex !== invoices.length - 1) {
93
+ const { invoiceChain, lastMatchIndex } = getInvoiceChain([...invoices].slice(totalIndex));
94
+ invoiceChains.push(invoiceChain);
95
+ totalIndex = totalIndex + lastMatchIndex;
96
+ }
97
+ megaChain.push(invoiceChains);
98
+ });
99
+ megaChain.forEach((chains) => {
100
+ if (chains.length > 1) {
101
+ chains.forEach((chain) => {
102
+ const diff = getInvoiceDifference(chain);
103
+ suspiciousInvoices.push(diff);
104
+ });
105
+ }
106
+ else {
107
+ chains.forEach((chain) => {
108
+ const diff = getInvoiceDifference(chain);
109
+ if (diff.originalAmount - diff.restatedAmount > 0) {
110
+ partiallyPaidInvoices.push(diff);
111
+ }
112
+ else if (diff.originalAmount - diff.restatedAmount < 0) {
113
+ restatedInvoices.push(diff);
114
+ }
115
+ });
116
+ }
117
+ });
118
+ return { suspiciousInvoices, restatedInvoices, partiallyPaidInvoices };
119
+ };
120
+ exports.getPartialPaid = getPartialPaid;
121
+ const getPartialPaidHeader = () => {
122
+ return {
123
+ invoiceNumber: 'Invoice number',
124
+ customer: 'Customer',
125
+ originalAmount: 'Original amount',
126
+ restatedAmount: 'Last amount',
127
+ difference: 'Difference',
128
+ lastChangeDate: 'Last change date',
129
+ changeCounter: 'Changed',
130
+ };
131
+ };
@@ -0,0 +1,148 @@
1
+ import { TQueryParams } from '../../models/QueryResult.model';
2
+ import { addHeaderToData } from '../../helpers/excel.helper';
3
+ import { getUniqueDatesForPeriod } from '../../db/bbcSheets.db';
4
+ import { getPartialPaidTable, IPartiallyPaidInvoice } from '../../db/receivables.db';
5
+ import { ECollaterals } from '../../enums/collaterals.enum';
6
+ import { IReceivableItemDoc, IReceivableItemDocPopulated } from '../../models/ReceivableItem.model';
7
+
8
+ export const getPartialPaidFull = async (params: TQueryParams) => {
9
+ const { suspiciousInvoices, restatedInvoices, partiallyPaidInvoices } = await getPartialPaid(params);
10
+
11
+ const header = getPartialPaidHeader();
12
+
13
+ const suspiciousInvoicesFull = addHeaderToData(header, suspiciousInvoices);
14
+ const restatedInvoicesFull = addHeaderToData(header, restatedInvoices);
15
+ const partiallyPaidInvoicesFull = addHeaderToData(header, partiallyPaidInvoices);
16
+
17
+ return {
18
+ 'suspicious': suspiciousInvoicesFull,
19
+ 'restated': restatedInvoicesFull,
20
+ 'partially paid': partiallyPaidInvoicesFull,
21
+ };
22
+ };
23
+
24
+ export const getPartialPaid = async (params: TQueryParams) => {
25
+ const { borrowerId, startDate, endDate } = params;
26
+ const allInventoryBbcDates = await getUniqueDatesForPeriod(borrowerId.toString(), ECollaterals.RECEIVABLE, new Date(startDate), new Date(endDate));
27
+ const sheetIds = allInventoryBbcDates.reduce((acc, bbc) => [...acc, ...bbc.ids], []);
28
+ const allInvoices = await getPartialPaidTable(sheetIds);
29
+
30
+ const groupedInvoices = allInvoices.reduce((acc: { [invoiceNumber: string]: IReceivableItemDocPopulated[] }, i) => {
31
+ acc[i.invoiceNumber] = acc[i.invoiceNumber] || [];
32
+ acc[i.invoiceNumber].push(i);
33
+ return acc;
34
+ }, {});
35
+
36
+ const getInvoiceDifference = (invoices: Partial<IReceivableItemDocPopulated>[]): IPartiallyPaidInvoice => {
37
+ const invoice1 = invoices[0];
38
+ const invoice2 = invoices[invoices.length - 1];
39
+ return {
40
+ invoiceNumber: invoice1.invoiceNumber,
41
+ invoiceDate: invoice1.invoiceDate,
42
+ customer: invoice1.customerTitle,
43
+ originalAmount: invoice1.invoiceAmount,
44
+ restatedAmount: invoice2.invoiceAmount,
45
+ changeCounter: invoices.length - 1,
46
+ lastChangeDate: invoice2.bbc.bbcDate,
47
+ difference: +Math.abs(invoice1.invoiceAmount - invoice2.invoiceAmount).toFixed(3),
48
+ };
49
+ };
50
+
51
+ const getInvoiceChain = (invoices: Partial<IReceivableItemDoc>[]) => {
52
+ let firstInvoice: Partial<IReceivableItemDoc> = null;
53
+ let lastInvoice: Partial<IReceivableItemDoc> = null;
54
+ const invoiceChain = [];
55
+ let lastMatchIndex = 0;
56
+ let shouldSkip = false;
57
+ invoices.forEach((invoice, index) => {
58
+ if (shouldSkip) {
59
+ return;
60
+ }
61
+ if (firstInvoice === null) {
62
+ firstInvoice = { ...invoice };
63
+ invoiceChain.push(firstInvoice);
64
+ return;
65
+ }
66
+
67
+ lastInvoice = { ...invoice };
68
+
69
+ if (
70
+ lastInvoice.invoiceAmount === firstInvoice.invoiceAmount ||
71
+ lastInvoice.invoiceAmount === invoices[index - 1].invoiceAmount
72
+ ) {
73
+ lastMatchIndex = index;
74
+ return;
75
+ }
76
+
77
+ if (
78
+ lastInvoice.invoiceAmount > firstInvoice.invoiceAmount &&
79
+ lastInvoice.invoiceAmount > invoices[index - 1].invoiceAmount ||
80
+ lastInvoice.invoiceAmount < firstInvoice.invoiceAmount &&
81
+ lastInvoice.invoiceAmount < invoices[index - 1].invoiceAmount
82
+ ) {
83
+ invoiceChain.push(lastInvoice);
84
+ lastMatchIndex = index;
85
+ return;
86
+ }
87
+
88
+ if (
89
+ lastInvoice.invoiceAmount > firstInvoice.invoiceAmount &&
90
+ lastInvoice.invoiceAmount < invoices[index - 1].invoiceAmount ||
91
+ lastInvoice.invoiceAmount < firstInvoice.invoiceAmount &&
92
+ lastInvoice.invoiceAmount > invoices[index - 1].invoiceAmount
93
+ ) {
94
+ shouldSkip = true;
95
+ return;
96
+ }
97
+ });
98
+ return { invoiceChain, lastMatchIndex };
99
+ };
100
+
101
+ const megaChain = [];
102
+ const suspiciousInvoices: IPartiallyPaidInvoice[] = [];
103
+ const restatedInvoices: IPartiallyPaidInvoice[] = [];
104
+ const partiallyPaidInvoices: IPartiallyPaidInvoice[] = [];
105
+
106
+ Object.keys(groupedInvoices).forEach((invoiceNumber) => {
107
+ const invoices = [...groupedInvoices[invoiceNumber]];
108
+ const invoiceChains: Partial<IReceivableItemDoc>[][] = [];
109
+ let totalIndex = 0;
110
+ while (totalIndex !== invoices.length - 1) {
111
+ const { invoiceChain, lastMatchIndex } = getInvoiceChain([...invoices].slice(totalIndex));
112
+ invoiceChains.push(invoiceChain);
113
+ totalIndex = totalIndex + lastMatchIndex;
114
+ }
115
+ megaChain.push(invoiceChains);
116
+ });
117
+
118
+ megaChain.forEach((chains) => {
119
+ if (chains.length > 1) {
120
+ chains.forEach((chain) => {
121
+ const diff = getInvoiceDifference(chain);
122
+ suspiciousInvoices.push(diff);
123
+ });
124
+ } else {
125
+ chains.forEach((chain) => {
126
+ const diff = getInvoiceDifference(chain);
127
+ if (diff.originalAmount - diff.restatedAmount > 0) {
128
+ partiallyPaidInvoices.push(diff);
129
+ } else if (diff.originalAmount - diff.restatedAmount < 0) {
130
+ restatedInvoices.push(diff);
131
+ }
132
+ });
133
+ }
134
+ });
135
+ return { suspiciousInvoices, restatedInvoices, partiallyPaidInvoices };
136
+ };
137
+
138
+ const getPartialPaidHeader = () => {
139
+ return {
140
+ invoiceNumber: 'Invoice number',
141
+ customer: 'Customer',
142
+ originalAmount: 'Original amount',
143
+ restatedAmount: 'Last amount',
144
+ difference: 'Difference',
145
+ lastChangeDate: 'Last change date',
146
+ changeCounter: 'Changed',
147
+ };
148
+ };