Skip to content

Commit 41954ad

Browse files
committed
advanced parsing for inventory import errors
1 parent d8018a2 commit 41954ad

13 files changed

+229
-8
lines changed

README.md

+10
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,16 @@ _This project is completely unofficial and is in no way affiliated with or endor
2828
| W603 | Message Logger | ✔️ | |
2929
| W604 | Integration Log Viewer | | ✔️ |
3030

31+
## Advanced Parsers
32+
33+
More than just parsing files into objects. 🧙‍♂️
34+
35+
`extractInventoryImportErrors(messageLoggerData)`
36+
37+
- Takes data from a parsed CSV "W603 - Message Logger" report,
38+
attempts to identify errors related to the Inventory Import Utility (IIU) integration,
39+
and provide context of where the errors occurred.
40+
3141
## Important Notes
3242

3343
⚠️ When parsing reports, use the files **as exported** from FASTER Web.<br />

advanced.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { extractInventoryImportErrors } from './advanced/w603.messageLogger.iiu.js';

advanced.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { extractInventoryImportErrors } from './advanced/w603.messageLogger.iiu.js';

advanced.ts

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export { extractInventoryImportErrors } from './advanced/w603.messageLogger.iiu.js'

advanced/w603.messageLogger.iiu.d.ts

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import type { W603ReportRow } from '../csvReports.js';
2+
interface InventoryImportError {
3+
messageId: number;
4+
messageDateTime: string;
5+
message: string;
6+
fileName?: string;
7+
}
8+
/**
9+
* Filters out the errors that occurred during the Inventory Import process from the W603 CSV report.
10+
*
11+
* The data must include at minimum the following filters:
12+
* - Message Type = 'Information', 'Error'
13+
* - Application Type = 'Integration'
14+
*
15+
* Other data will be ignored.
16+
* @param messageLoggerData - Data parsed from the W603 CSV report
17+
* @returns - A list of errors that occurred during the Inventory Import process,
18+
* along with the file associated with each error.
19+
*/
20+
export declare function extractInventoryImportErrors(messageLoggerData: W603ReportRow[]): InventoryImportError[];
21+
export {};

advanced/w603.messageLogger.iiu.js

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
const inventoryImportBlockStartMessagePrefix = 'Inventory Import process started';
2+
const inventoryImportBlockEndMessagePrefix = 'Inventory Import process completed';
3+
/**
4+
* Filters out the errors that occurred during the Inventory Import process from the W603 CSV report.
5+
*
6+
* The data must include at minimum the following filters:
7+
* - Message Type = 'Information', 'Error'
8+
* - Application Type = 'Integration'
9+
*
10+
* Other data will be ignored.
11+
* @param messageLoggerData - Data parsed from the W603 CSV report
12+
* @returns - A list of errors that occurred during the Inventory Import process,
13+
* along with the file associated with each error.
14+
*/
15+
export function extractInventoryImportErrors(messageLoggerData) {
16+
/*
17+
* Ensure the data is sorted by the "messageId" column
18+
*/
19+
messageLoggerData.sort((a, b) => {
20+
const messageIdA = Number.parseInt(a.messageId === '' ? '0' : a.messageId);
21+
const messageIdB = Number.parseInt(b.messageId === '' ? '0' : b.messageId);
22+
return messageIdA - messageIdB;
23+
});
24+
/*
25+
* Build error list
26+
*/
27+
const errorData = [];
28+
let inventoryImportBlockStartMessageId;
29+
for (const row of messageLoggerData) {
30+
if (row.messageId === '') {
31+
continue;
32+
}
33+
if (row.message.trim().startsWith(inventoryImportBlockStartMessagePrefix)) {
34+
inventoryImportBlockStartMessageId = Number.parseInt(row.messageId);
35+
}
36+
if (row.message.trim().startsWith(inventoryImportBlockEndMessagePrefix)) {
37+
inventoryImportBlockStartMessageId = undefined;
38+
}
39+
if (inventoryImportBlockStartMessageId !== undefined) {
40+
if (row.messageType === 'Error') {
41+
errorData.push({
42+
messageId: Number.parseInt(row.messageId),
43+
messageDateTime: row.messageDateTime,
44+
message: row.message
45+
});
46+
}
47+
else if (row.messageType === 'Information' &&
48+
(row.message.includes(' file copied ') ||
49+
row.message.includes(' file deleted '))) {
50+
const fileName = row.message
51+
.slice(0, Math.max(0, row.message.indexOf(' file ')))
52+
.trim();
53+
for (let index = errorData.length - 1; index >= 0; index--) {
54+
if (errorData[index].fileName === undefined &&
55+
errorData[index].messageId > inventoryImportBlockStartMessageId) {
56+
errorData[index].fileName = fileName;
57+
}
58+
else {
59+
break;
60+
}
61+
}
62+
}
63+
}
64+
}
65+
/*
66+
* Return error list
67+
*/
68+
return errorData;
69+
}

advanced/w603.messageLogger.iiu.ts

+96
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,96 @@
1+
import type { W603ReportRow } from '../csvReports.js'
2+
3+
const inventoryImportBlockStartMessagePrefix =
4+
'Inventory Import process started'
5+
const inventoryImportBlockEndMessagePrefix =
6+
'Inventory Import process completed'
7+
8+
interface InventoryImportError {
9+
messageId: number
10+
messageDateTime: string
11+
message: string
12+
fileName?: string
13+
}
14+
15+
/**
16+
* Filters out the errors that occurred during the Inventory Import process from the W603 CSV report.
17+
*
18+
* The data must include at minimum the following filters:
19+
* - Message Type = 'Information', 'Error'
20+
* - Application Type = 'Integration'
21+
*
22+
* Other data will be ignored.
23+
* @param messageLoggerData - Data parsed from the W603 CSV report
24+
* @returns - A list of errors that occurred during the Inventory Import process,
25+
* along with the file associated with each error.
26+
*/
27+
export function extractInventoryImportErrors(
28+
messageLoggerData: W603ReportRow[]
29+
): InventoryImportError[] {
30+
/*
31+
* Ensure the data is sorted by the "messageId" column
32+
*/
33+
34+
messageLoggerData.sort((a, b) => {
35+
const messageIdA = Number.parseInt(a.messageId === '' ? '0' : a.messageId)
36+
const messageIdB = Number.parseInt(b.messageId === '' ? '0' : b.messageId)
37+
return messageIdA - messageIdB
38+
})
39+
40+
/*
41+
* Build error list
42+
*/
43+
44+
const errorData: InventoryImportError[] = []
45+
46+
let inventoryImportBlockStartMessageId: number | undefined
47+
48+
for (const row of messageLoggerData) {
49+
if (row.messageId === '') {
50+
continue
51+
}
52+
53+
if (row.message.trim().startsWith(inventoryImportBlockStartMessagePrefix)) {
54+
inventoryImportBlockStartMessageId = Number.parseInt(row.messageId)
55+
}
56+
57+
if (row.message.trim().startsWith(inventoryImportBlockEndMessagePrefix)) {
58+
inventoryImportBlockStartMessageId = undefined
59+
}
60+
61+
if (inventoryImportBlockStartMessageId !== undefined) {
62+
if (row.messageType === 'Error') {
63+
errorData.push({
64+
messageId: Number.parseInt(row.messageId),
65+
messageDateTime: row.messageDateTime,
66+
message: row.message
67+
})
68+
} else if (
69+
row.messageType === 'Information' &&
70+
(row.message.includes(' file copied ') ||
71+
row.message.includes(' file deleted '))
72+
) {
73+
const fileName = row.message
74+
.slice(0, Math.max(0, row.message.indexOf(' file ')))
75+
.trim()
76+
77+
for (let index = errorData.length - 1; index >= 0; index--) {
78+
if (
79+
errorData[index].fileName === undefined &&
80+
errorData[index].messageId > inventoryImportBlockStartMessageId
81+
) {
82+
errorData[index].fileName = fileName
83+
} else {
84+
break
85+
}
86+
}
87+
}
88+
}
89+
}
90+
91+
/*
92+
* Return error list
93+
*/
94+
95+
return errorData
96+
}

index.d.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
export * as advanced from './advanced.js';
12
export * as csvReports from './csvReports.js';
23
export * as xlsxReports from './xlsxReports.js';

index.js

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
export * as advanced from './advanced.js';
12
export * as csvReports from './csvReports.js';
23
export * as xlsxReports from './xlsxReports.js';

index.ts

+1
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1+
export * as advanced from './advanced.js'
12
export * as csvReports from './csvReports.js'
23
export * as xlsxReports from './xlsxReports.js'

package.json

+2
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
"./xlsx": "./xlsxReports.js",
1717
"./xlsxReports": "./xlsxReports.js",
1818
"./xlsxReports.js": "./xlsxReports.js",
19+
"./advanced": "./advanced.js",
20+
"./advanced.js": "./advanced.js",
1921
"./debug": "./debug.config.js"
2022
},
2123
"scripts": {

test/csvReports.js

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,32 +1,35 @@
1+
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
2+
/* eslint-disable no-console */
13
import assert from 'node:assert';
24
import { describe, it } from 'node:test';
35
import Debug from 'debug';
6+
import { extractInventoryImportErrors } from '../advanced.js';
47
import { fasterCsvReportOptions, parseFasterCsvReport } from '../csvReports.js';
58
import { DEBUG_ENABLE_NAMESPACES } from '../debug.config.js';
69
Debug.enable(DEBUG_ENABLE_NAMESPACES);
710
await describe('node-faster-report-parser/csv', async () => {
8-
await it('Parses "W200S - Inventory Summary Report"', async () => {
11+
await it.skip('Parses "W200S - Inventory Summary Report"', async () => {
912
const results = await parseFasterCsvReport('./samples/w200s.csv', fasterCsvReportOptions.w200s);
1013
console.log(results.data[0]);
1114
assert(results.data.length > 0);
1215
console.log(results.parameters);
1316
console.log(results.version);
1417
});
15-
await it('Parses "W223 - Inventory Transaction Details Report"', async () => {
18+
await it.skip('Parses "W223 - Inventory Transaction Details Report"', async () => {
1619
const results = await parseFasterCsvReport('./samples/w223.csv', fasterCsvReportOptions.w223);
1720
console.log(results.data[0]);
1821
assert(results.data.length > 0);
1922
console.log(results.parameters);
2023
console.log(results.version);
2124
});
22-
await it('Parses "W235 - Inventory Snapshot"', async () => {
25+
await it.skip('Parses "W235 - Inventory Snapshot"', async () => {
2326
const results = await parseFasterCsvReport('./samples/w235.csv', fasterCsvReportOptions.w235);
2427
console.log(results.data[0]);
2528
assert(results.data.length > 0);
2629
console.log(results.parameters);
2730
console.log(results.version);
2831
});
29-
await it('Parses "W600 - Pick List Values Report"', async () => {
32+
await it.skip('Parses "W600 - Pick List Values Report"', async () => {
3033
const results = await parseFasterCsvReport('./samples/w600.csv', fasterCsvReportOptions.w600);
3134
console.log(results.data[0]);
3235
assert(results.data.length > 0);
@@ -39,5 +42,8 @@ await describe('node-faster-report-parser/csv', async () => {
3942
assert(results.data.length > 0);
4043
console.log(results.parameters);
4144
console.log(results.version);
45+
const iiuErrors = extractInventoryImportErrors(results.data);
46+
console.log(iiuErrors);
47+
assert(iiuErrors.length > 0);
4248
});
4349
});

test/csvReports.ts

+15-4
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,19 @@
1+
// eslint-disable-next-line @eslint-community/eslint-comments/disable-enable-pair
2+
/* eslint-disable no-console */
3+
14
import assert from 'node:assert'
25
import { describe, it } from 'node:test'
36

47
import Debug from 'debug'
58

9+
import { extractInventoryImportErrors } from '../advanced.js'
610
import { fasterCsvReportOptions, parseFasterCsvReport } from '../csvReports.js'
711
import { DEBUG_ENABLE_NAMESPACES } from '../debug.config.js'
812

913
Debug.enable(DEBUG_ENABLE_NAMESPACES)
1014

1115
await describe('node-faster-report-parser/csv', async () => {
12-
await it('Parses "W200S - Inventory Summary Report"', async () => {
16+
await it.skip('Parses "W200S - Inventory Summary Report"', async () => {
1317
const results = await parseFasterCsvReport(
1418
'./samples/w200s.csv',
1519
fasterCsvReportOptions.w200s
@@ -22,7 +26,7 @@ await describe('node-faster-report-parser/csv', async () => {
2226
console.log(results.version)
2327
})
2428

25-
await it('Parses "W223 - Inventory Transaction Details Report"', async () => {
29+
await it.skip('Parses "W223 - Inventory Transaction Details Report"', async () => {
2630
const results = await parseFasterCsvReport(
2731
'./samples/w223.csv',
2832
fasterCsvReportOptions.w223
@@ -35,7 +39,7 @@ await describe('node-faster-report-parser/csv', async () => {
3539
console.log(results.version)
3640
})
3741

38-
await it('Parses "W235 - Inventory Snapshot"', async () => {
42+
await it.skip('Parses "W235 - Inventory Snapshot"', async () => {
3943
const results = await parseFasterCsvReport(
4044
'./samples/w235.csv',
4145
fasterCsvReportOptions.w235
@@ -48,7 +52,7 @@ await describe('node-faster-report-parser/csv', async () => {
4852
console.log(results.version)
4953
})
5054

51-
await it('Parses "W600 - Pick List Values Report"', async () => {
55+
await it.skip('Parses "W600 - Pick List Values Report"', async () => {
5256
const results = await parseFasterCsvReport(
5357
'./samples/w600.csv',
5458
fasterCsvReportOptions.w600
@@ -68,9 +72,16 @@ await describe('node-faster-report-parser/csv', async () => {
6872
)
6973

7074
console.log(results.data[0])
75+
7176
assert(results.data.length > 0)
7277

7378
console.log(results.parameters)
7479
console.log(results.version)
80+
81+
const iiuErrors = extractInventoryImportErrors(results.data)
82+
83+
console.log(iiuErrors)
84+
85+
assert(iiuErrors.length > 0)
7586
})
7687
})

0 commit comments

Comments
 (0)