Skip to content

Commit

Permalink
inventory scanner development #2
Browse files Browse the repository at this point in the history
- get current inventory from dynamics gp for validation
  • Loading branch information
dangowans committed Nov 14, 2024
1 parent 639772b commit e24bb09
Show file tree
Hide file tree
Showing 45 changed files with 771 additions and 229 deletions.
2 changes: 1 addition & 1 deletion app.js
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ app.use((error, request, response) => {
* Initialize server
*/
const httpPort = configFunctions.getConfigProperty('webServer.httpPort');
// eslint-disable-next-line @typescript-eslint/no-misused-promises, sonarjs/no-misused-promises
// eslint-disable-next-line @typescript-eslint/no-misused-promises
const httpServer = http.createServer(app);
httpServer.listen(httpPort);
debug(`HTTP listening on ${httpPort.toString()}`);
Expand Down
2 changes: 1 addition & 1 deletion app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ app.use(

const httpPort = configFunctions.getConfigProperty('webServer.httpPort')

// eslint-disable-next-line @typescript-eslint/no-misused-promises, sonarjs/no-misused-promises
// eslint-disable-next-line @typescript-eslint/no-misused-promises
const httpServer = http.createServer(app)

httpServer.listen(httpPort)
Expand Down
9 changes: 6 additions & 3 deletions data/config.defaultValues.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@ import type { ADWebAuthAuthenticatorConfiguration, ActiveDirectoryAuthenticatorC
import type { AccessOptions } from 'basic-ftp';
import type { config as MSSQLConfig } from 'mssql';
import type { Spec } from 'node-schedule';
import type { ConfigFileSuffixXlsx, ConfigScheduledFtpReport } from '../types/configTypes.js';
import type { ConfigItemValidationDynamicsGP, ConfigItemValidationFaster } from '../modules/inventoryScanner/configTypes.js';
import type { ConfigFileSuffixXlsx, ConfigScheduledFtpReport } from '../types/configHelperTypes.js';
export declare const configDefaultValues: {
ftp: AccessOptions;
'webServer.httpPort': number;
Expand All @@ -18,7 +19,8 @@ export declare const configDefaultValues: {
type: "adWebAuth";
config: ADWebAuthAuthenticatorConfiguration;
} | undefined;
worktech: MSSQLConfig;
worktech: MSSQLConfig | undefined;
dynamicsGP: MSSQLConfig | undefined;
'modules.autocomplete.isEnabled': boolean;
'modules.autocomplete.runOnStartup': boolean;
'modules.autocomplete.reports.w114': ConfigScheduledFtpReport<ConfigFileSuffixXlsx> | undefined;
Expand All @@ -31,9 +33,10 @@ export declare const configDefaultValues: {
'modules.inventoryScanner.workOrders.acceptWorkTech': boolean;
'modules.inventoryScanner.workOrders.workTechRegex': RegExp;
'modules.inventoryScanner.items.acceptNotValidated': boolean;
'modules.inventoryScanner.items.itemNumberRegex': RegExp | undefined;
'modules.inventoryScanner.items.validation': ConfigItemValidationDynamicsGP | ConfigItemValidationFaster | undefined;
'modules.inventoryScanner.quantities.acceptOverages': boolean;
'modules.inventoryScanner.quantities.acceptNegatives': boolean;
'modules.inventoryScanner.reports.w200': ConfigScheduledFtpReport<ConfigFileSuffixXlsx> | undefined;
'modules.inventoryScanner.reports.w311': ConfigScheduledFtpReport<ConfigFileSuffixXlsx> | undefined;
'modules.inventoryScanner.reports.w604': ConfigScheduledFtpReport<ConfigFileSuffixXlsx> | undefined;
'modules.worktechUpdate.isEnabled': boolean;
Expand Down
4 changes: 3 additions & 1 deletion data/config.defaultValues.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ export const configDefaultValues = {
'login.domain': '',
'login.authentication': undefined,
worktech: undefined,
dynamicsGP: undefined,
/*
* Autocomplete
*/
Expand All @@ -29,9 +30,10 @@ export const configDefaultValues = {
// eslint-disable-next-line no-secrets/no-secrets
'modules.inventoryScanner.workOrders.workTechRegex': /^[A-Z]{2}.\d{2}.\d{5}$/,
'modules.inventoryScanner.items.acceptNotValidated': true,
'modules.inventoryScanner.items.itemNumberRegex': undefined,
'modules.inventoryScanner.items.validation': undefined,
'modules.inventoryScanner.quantities.acceptOverages': true,
'modules.inventoryScanner.quantities.acceptNegatives': true,
'modules.inventoryScanner.reports.w200': undefined,
'modules.inventoryScanner.reports.w311': undefined,
'modules.inventoryScanner.reports.w604': undefined,
/*
Expand Down
18 changes: 12 additions & 6 deletions data/config.defaultValues.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,14 @@ import type { AccessOptions } from 'basic-ftp'
import type { config as MSSQLConfig } from 'mssql'
import type { Spec } from 'node-schedule'

import type {
ConfigItemValidationDynamicsGP,
ConfigItemValidationFaster
} from '../modules/inventoryScanner/configTypes.js'
import type {
ConfigFileSuffixXlsx,
ConfigScheduledFtpReport
} from '../types/configTypes.js'
} from '../types/configHelperTypes.js'

export const configDefaultValues = {
ftp: undefined as unknown as AccessOptions,
Expand All @@ -34,7 +38,8 @@ export const configDefaultValues = {
}
| undefined,

worktech: undefined as unknown as MSSQLConfig,
worktech: undefined as unknown as MSSQLConfig | undefined,
dynamicsGP: undefined as unknown as MSSQLConfig | undefined,

/*
* Autocomplete
Expand Down Expand Up @@ -70,14 +75,15 @@ export const configDefaultValues = {
'modules.inventoryScanner.workOrders.workTechRegex': /^[A-Z]{2}.\d{2}.\d{5}$/,

'modules.inventoryScanner.items.acceptNotValidated': true,
'modules.inventoryScanner.items.itemNumberRegex': undefined as unknown as RegExp | undefined,
'modules.inventoryScanner.items.validation': undefined as unknown as
| ConfigItemValidationDynamicsGP
| ConfigItemValidationFaster
| undefined,

'modules.inventoryScanner.quantities.acceptOverages': true,
'modules.inventoryScanner.quantities.acceptNegatives': true,

'modules.inventoryScanner.reports.w200': undefined as unknown as
| ConfigScheduledFtpReport<ConfigFileSuffixXlsx>
| undefined,

'modules.inventoryScanner.reports.w311': undefined as unknown as
| ConfigScheduledFtpReport<ConfigFileSuffixXlsx>
| undefined,
Expand Down
2 changes: 1 addition & 1 deletion helpers/functions.sftp.d.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import type { ConfigFtpPath } from '../types/configTypes.js';
import type { ConfigFtpPath } from '../types/configHelperTypes.js';
export declare const tempFolderPath: string;
export declare function ensureTempFolderExists(): Promise<void>;
export declare function downloadFilesToTemp<S extends string>(ftpPath: ConfigFtpPath<S>): Promise<Array<`${string}${S}`>>;
2 changes: 1 addition & 1 deletion helpers/functions.sftp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import path from 'node:path'
import { Client } from 'basic-ftp'
import Debug from 'debug'

import type { ConfigFtpPath } from '../types/configTypes.js'
import type { ConfigFtpPath } from '../types/configHelperTypes.js'

import { getConfigProperty } from './functions.config.js'

Expand Down
2 changes: 1 addition & 1 deletion modules/autocomplete/tasks/updateAssetNumbersTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { downloadFilesToTemp } from '../../../helpers/functions.sftp.js'
import type {
ConfigFileSuffixXlsx,
ConfigScheduledFtpReport
} from '../../../types/configTypes.js'
} from '../../../types/configHelperTypes.js'
import { moduleName } from '../helpers/moduleHelpers.js'

export const taskName = 'Update Asset Numbers Task'
Expand Down
2 changes: 1 addition & 1 deletion modules/autocomplete/tasks/updateItemNumbersTask.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import { downloadFilesToTemp } from '../../../helpers/functions.sftp.js'
import type {
ConfigFileSuffixXlsx,
ConfigScheduledFtpReport
} from '../../../types/configTypes.js'
} from '../../../types/configHelperTypes.js'
import { moduleName } from '../helpers/moduleHelpers.js'

export const taskName = 'Update Item Numbers Task'
Expand Down
42 changes: 42 additions & 0 deletions modules/inventoryScanner/configTypes.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
import type { GPItemWithQuantity } from '@cityssm/dynamics-gp';
import type { Spec } from 'node-schedule';
import type { ConfigFileSuffixXlsx, ConfigScheduledFtpReport } from '../../types/configHelperTypes.js';
export interface ConfigItemValidationDynamicsGP {
source: 'dynamicsGP';
schedule?: Spec;
gpLocationCodesToFasterStorerooms: Record<string, string>;
gpItemFilter?: (item: GPItemWithQuantity) => boolean;
}
export interface ConfigItemValidationFaster {
source: 'faster';
/** W200 - Inventory Report */
w200?: ConfigScheduledFtpReport<ConfigFileSuffixXlsx>;
}
export interface ConfigModuleInventoryScanner {
scannerIpAddressRegex?: RegExp;
workOrders?: {
acceptNotValidated?: boolean;
fasterRegex?: RegExp;
acceptWorkTech?: boolean;
workTechRegex?: RegExp;
};
items?: {
acceptNotValidated?: boolean;
itemNumberRegex?: RegExp;
validation?: ConfigItemValidationDynamicsGP | ConfigItemValidationFaster;
};
quantities?: {
acceptOverages?: boolean;
acceptNegatives?: boolean;
};
reports?: {
/**
* W311 - Active Work Orders by Shop
*/
w311?: ConfigScheduledFtpReport<ConfigFileSuffixXlsx>;
/**
* W604 - Integration Log Viewer
*/
w604?: ConfigScheduledFtpReport<ConfigFileSuffixXlsx>;
};
}
1 change: 1 addition & 0 deletions modules/inventoryScanner/configTypes.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export {};
55 changes: 55 additions & 0 deletions modules/inventoryScanner/configTypes.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
import type { GPItemWithQuantity } from '@cityssm/dynamics-gp'
import type { Spec } from 'node-schedule'

import type {
ConfigFileSuffixXlsx,
ConfigScheduledFtpReport
} from '../../types/configHelperTypes.js'

export interface ConfigItemValidationDynamicsGP {
source: 'dynamicsGP'
schedule?: Spec
gpLocationCodesToFasterStorerooms: Record<string, string>
gpItemFilter?: (item: GPItemWithQuantity) => boolean
}

export interface ConfigItemValidationFaster {
source: 'faster'

/** W200 - Inventory Report */
w200?: ConfigScheduledFtpReport<ConfigFileSuffixXlsx>
}

export interface ConfigModuleInventoryScanner {
scannerIpAddressRegex?: RegExp

workOrders?: {
acceptNotValidated?: boolean
fasterRegex?: RegExp
acceptWorkTech?: boolean
workTechRegex?: RegExp
}

items?: {
acceptNotValidated?: boolean
itemNumberRegex?: RegExp
validation?: ConfigItemValidationDynamicsGP | ConfigItemValidationFaster
}

quantities?: {
acceptOverages?: boolean
acceptNegatives?: boolean
}

reports?: {
/**
* W311 - Active Work Orders by Shop
*/
w311?: ConfigScheduledFtpReport<ConfigFileSuffixXlsx>

/**
* W604 - Integration Log Viewer
*/
w604?: ConfigScheduledFtpReport<ConfigFileSuffixXlsx>
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
import type { ItemValidationRecord } from '../types.js';
export default function createOrUpdateItemValidation(validationRecord: ItemValidationRecord, timeMillis: number): void;
28 changes: 28 additions & 0 deletions modules/inventoryScanner/database/createOrUpdateItemValidation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import sqlite from 'better-sqlite3';
import getItemValidation from './getItemValidation.js';
import { databasePath } from './helpers.database.js';
export default function createOrUpdateItemValidation(validationRecord, timeMillis) {
const database = sqlite(databasePath);
const databaseRecord = getItemValidation(validationRecord.itemStoreroom, validationRecord.itemNumber, true, database);
if (databaseRecord === undefined) {
database
.prepare(`insert into ItemValidationRecords (
itemStoreroom, itemNumber, itemDescription, availableQuantity, unitPrice,
recordCreate_timeMillis, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?)`)
.run(validationRecord.itemStoreroom, validationRecord.itemNumber, validationRecord.itemDescription, validationRecord.availableQuantity, validationRecord.unitPrice, timeMillis, timeMillis);
}
else {
database
.prepare(`update ItemValidationRecords
set itemDescription = ?,
availableQuantity = ?,
unitPrice = ?,
recordUpdate_timeMillis = ?,
recordDelete_timeMillis = null
where itemStoreroom = ?
and itemNumber = ?`)
.run(validationRecord.itemDescription, validationRecord.availableQuantity, validationRecord.unitPrice, timeMillis, validationRecord.itemStoreroom, validationRecord.itemNumber);
}
database.close();
}
61 changes: 61 additions & 0 deletions modules/inventoryScanner/database/createOrUpdateItemValidation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import sqlite from 'better-sqlite3'

import type { ItemValidationRecord } from '../types.js'

import getItemValidation from './getItemValidation.js'
import { databasePath } from './helpers.database.js'

export default function createOrUpdateItemValidation(
validationRecord: ItemValidationRecord,
timeMillis: number
): void {
const database = sqlite(databasePath)

const databaseRecord = getItemValidation(
validationRecord.itemStoreroom,
validationRecord.itemNumber,
true,
database
)

if (databaseRecord === undefined) {
database
.prepare(
`insert into ItemValidationRecords (
itemStoreroom, itemNumber, itemDescription, availableQuantity, unitPrice,
recordCreate_timeMillis, recordUpdate_timeMillis)
values (?, ?, ?, ?, ?, ?, ?)`
)
.run(
validationRecord.itemStoreroom,
validationRecord.itemNumber,
validationRecord.itemDescription,
validationRecord.availableQuantity,
validationRecord.unitPrice,
timeMillis,
timeMillis
)
} else {
database
.prepare(
`update ItemValidationRecords
set itemDescription = ?,
availableQuantity = ?,
unitPrice = ?,
recordUpdate_timeMillis = ?,
recordDelete_timeMillis = null
where itemStoreroom = ?
and itemNumber = ?`
)
.run(
validationRecord.itemDescription,
validationRecord.availableQuantity,
validationRecord.unitPrice,
timeMillis,
validationRecord.itemStoreroom,
validationRecord.itemNumber
)
}

database.close()
}
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export default function deleteItemValidation(minUpdateTimeMillis: number): void;
16 changes: 16 additions & 0 deletions modules/inventoryScanner/database/deleteItemValidation.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import sqlite from 'better-sqlite3';
import { databasePath } from './helpers.database.js';
export default function deleteItemValidation(minUpdateTimeMillis) {
const database = sqlite(databasePath);
database
.prepare(`update ItemValidationRecords
set recordDelete_timeMillis = ?
where recordUpdate_timeMillis < ?`)
.run(Date.now(), minUpdateTimeMillis);
database
.prepare(`delete from ItemValidationRecords
where recordDelete_timeMillis is not null
and itemNumber not in (select itemNumber from InventoryScannerRecords)`)
.run();
database.close();
}
27 changes: 27 additions & 0 deletions modules/inventoryScanner/database/deleteItemValidation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import sqlite from 'better-sqlite3'

import { databasePath } from './helpers.database.js'

export default function deleteItemValidation(
minUpdateTimeMillis: number
): void {
const database = sqlite(databasePath)

database
.prepare(
`update ItemValidationRecords
set recordDelete_timeMillis = ?
where recordUpdate_timeMillis < ?`
)
.run(Date.now(), minUpdateTimeMillis)

database
.prepare(
`delete from ItemValidationRecords
where recordDelete_timeMillis is not null
and itemNumber not in (select itemNumber from InventoryScannerRecords)`
)
.run()

database.close()
}
3 changes: 3 additions & 0 deletions modules/inventoryScanner/database/getItemValidation.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import sqlite from 'better-sqlite3';
import type { ItemValidationRecord } from '../types.js';
export default function getItemValidation(itemStoreroom: string, itemNumber: string, includeDeleted: boolean, connectedDatabase?: sqlite.Database): ItemValidationRecord | undefined;
Loading

0 comments on commit e24bb09

Please sign in to comment.