Add watcher status and additional typing.
This commit is contained in:
@@ -6,7 +6,7 @@ import errorTypeCheck from "../../util/errorTypeCheck";
|
||||
import { DecodedStl, DecodedStlLine } from "./decode-stl.interface";
|
||||
|
||||
const DecodeStl = async (
|
||||
extensionlessFilePath: string
|
||||
extensionlessFilePath: string,
|
||||
): Promise<DecodedStl> => {
|
||||
let dbf: DBFFile | null = null;
|
||||
try {
|
||||
@@ -47,7 +47,7 @@ const DecodeStl = async (
|
||||
"TTL_TYPAMT",
|
||||
"TTL_HRS",
|
||||
"TTL_AMT",
|
||||
])
|
||||
]),
|
||||
);
|
||||
//Apply line by line adjustments.
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ export interface DecodedVeh {
|
||||
impact2?: string;
|
||||
};
|
||||
// Complete vehicle data object
|
||||
vehicle: { data: VehicleRecordInterface };
|
||||
vehicle?: { data: VehicleRecordInterface };
|
||||
}
|
||||
|
||||
export interface VehicleRecordInterface {
|
||||
|
||||
@@ -1,10 +1,22 @@
|
||||
import { UUID } from "crypto";
|
||||
import log from "electron-log/main";
|
||||
import fs from "fs";
|
||||
import path from "path";
|
||||
import errorTypeCheck from "../../util/errorTypeCheck";
|
||||
import client from "../graphql/graphql-client";
|
||||
import {
|
||||
QUERY_JOB_BY_CLM_NO_TYPED,
|
||||
QUERY_VEHICLE_BY_VIN_TYPED,
|
||||
QueryJobByClmNoResult,
|
||||
VehicleQueryResult,
|
||||
} from "../graphql/queries";
|
||||
import store from "../store/store";
|
||||
import DecodeAD1 from "./decode-ad1";
|
||||
import { DecodedAd1 } from "./decode-ad1.interface";
|
||||
import DecodeAD2 from "./decode-ad2";
|
||||
import { DecodedAD2 } from "./decode-ad2.interface";
|
||||
import DecodeEnv from "./decode-env";
|
||||
import { DecodedEnv } from "./decode-env.interface";
|
||||
import DecodeLin from "./decode-lin";
|
||||
import { DecodedLin } from "./decode-lin.interface";
|
||||
import DecodePfh from "./decode-pfh";
|
||||
@@ -25,17 +37,12 @@ import DecodeTtl from "./decode-ttl";
|
||||
import { DecodedTtl } from "./decode-ttl.interface";
|
||||
import DecodeVeh from "./decode-veh";
|
||||
import { DecodedVeh } from "./decode-veh.interface";
|
||||
import { DecodedEnv } from "./decode-env.interface";
|
||||
import DecodeEnv from "./decode-env";
|
||||
import fs from "fs";
|
||||
import store from "../store/store";
|
||||
import client from "../graphql/graphql-client";
|
||||
|
||||
async function ImportJob(filepath: string): Promise<void> {
|
||||
const parsedFilePath = path.parse(filepath);
|
||||
const extensionlessFilePath = path.join(
|
||||
parsedFilePath.dir,
|
||||
parsedFilePath.name
|
||||
parsedFilePath.name,
|
||||
);
|
||||
log.debug("Importing Job", extensionlessFilePath);
|
||||
|
||||
@@ -56,7 +63,7 @@ async function ImportJob(filepath: string): Promise<void> {
|
||||
const ttl: DecodedTtl = await DecodeTtl(extensionlessFilePath);
|
||||
const pfp: DecodedPfp = await DecodePfp(extensionlessFilePath);
|
||||
|
||||
const jobObject = {
|
||||
const jobObject: RawJobDataObject = {
|
||||
...env,
|
||||
...ad1,
|
||||
...ad2,
|
||||
@@ -96,17 +103,7 @@ async function ImportJob(filepath: string): Promise<void> {
|
||||
//Build the request object
|
||||
|
||||
//Insert it
|
||||
const newAvailableJob = {
|
||||
// newJob.uploaded_by = Auth.authlink.User.Email;
|
||||
// newJob.bodyshopid = AppMetaData.ActiveShopId;
|
||||
// newJob.cieca_id = item.Job.ciecaid;
|
||||
// newJob.est_data = item.Job;
|
||||
// newJob.ownr_name = item.Job.ownr_fn?.Value + " " + item.Job.ownr_ln?.Value + " " + item.Job.ownr_co_nm?.Value;
|
||||
// newJob.ins_co_nm = item.Job.ins_co_nm?.Value;
|
||||
// newJob.vehicle_info = item.Job.vehicle.data.v_model_yr?.Value + " " + item.Job.vehicle.data.v_make_desc?.Value + " " + item.Job.vehicle.data.v_model_desc?.Value;
|
||||
// newJob.clm_no = item.Job.clm_no?.Value;
|
||||
// newJob.clm_amt = item.Job.clm_total?.Value;
|
||||
// newJob.source_system = item.Job.source_system?.Value;
|
||||
const newAvailableJob: AvailableJobSchema = {
|
||||
uploaded_by: store.get("app.user.email"),
|
||||
bodyshopid: store.get("app.bodyshop.id"),
|
||||
cieca_id: jobObject.ciecaid,
|
||||
@@ -117,30 +114,68 @@ async function ImportJob(filepath: string): Promise<void> {
|
||||
clm_no: jobObject.clm_no,
|
||||
clm_amt: jobObject.clm_total,
|
||||
// source_system: jobObject.source_system, //TODO: Add back source system if needed.
|
||||
issupplement: false,
|
||||
jobid: null,
|
||||
};
|
||||
|
||||
const existingVehicleId: uuid = await client.query ()
|
||||
// var vehuuid = await Utils.Queries.VehicleQueries.GetVehicleUuidByVin(item?.Job?.vehicle?.data?.v_vin?.Value ?? "");
|
||||
// if (!string.IsNullOrEmpty(vehuuid))
|
||||
// {
|
||||
// newJob.est_data.vehicle = null;
|
||||
// newJob.est_data.vehicleid = vehuuid;
|
||||
// }
|
||||
const existingVehicleRecord: VehicleQueryResult = await client.request(
|
||||
QUERY_VEHICLE_BY_VIN_TYPED,
|
||||
{
|
||||
vin: jobObject.v_vin,
|
||||
},
|
||||
);
|
||||
|
||||
if (existingVehicleRecord.vehicles.length > 0) {
|
||||
delete newAvailableJob.est_data.vehicle;
|
||||
newAvailableJob.est_data.vehicleid = existingVehicleRecord.vehicles[0].id;
|
||||
}
|
||||
|
||||
// string jobId = await Utils.Queries.JobsQueries.CheckSupplementByClaimNo(item.Job.clm_no?.Value ?? "");
|
||||
console.log(newAvailableJob);
|
||||
|
||||
// if (!string.IsNullOrEmpty(jobId))
|
||||
// {
|
||||
// newJob.issupplement = true;
|
||||
// newJob.jobid = jobId;
|
||||
// };
|
||||
|
||||
//Check if the vehicle exists, if it does, use that UUID, if not, keep it to insert it.
|
||||
const existingJobRecord: QueryJobByClmNoResult = await client.request(
|
||||
QUERY_JOB_BY_CLM_NO_TYPED,
|
||||
{ clm_no: jobObject.clm_no },
|
||||
);
|
||||
|
||||
if (existingJobRecord.jobs.length > 0) {
|
||||
newAvailableJob.issupplement = true;
|
||||
newAvailableJob.jobid = existingJobRecord.jobs[0].id;
|
||||
}
|
||||
} catch (error) {
|
||||
log.error("Error encountered while decoding job. ", errorTypeCheck(error));
|
||||
}
|
||||
}
|
||||
|
||||
export default ImportJob;
|
||||
|
||||
export interface RawJobDataObject
|
||||
extends DecodedEnv,
|
||||
DecodedAd1,
|
||||
DecodedAD2,
|
||||
DecodedVeh,
|
||||
DecodedLin,
|
||||
DecodedPfh,
|
||||
DecodedPfl,
|
||||
DecodedPft,
|
||||
DecodedPfm,
|
||||
DecodedPfo,
|
||||
DecodedStl,
|
||||
DecodedTtl,
|
||||
DecodedPfp {
|
||||
vehicleid?: UUID;
|
||||
}
|
||||
|
||||
export interface AvailableJobSchema {
|
||||
uploaded_by: string;
|
||||
bodyshopid: UUID;
|
||||
cieca_id?: string;
|
||||
est_data: RawJobDataObject;
|
||||
ownr_name: string;
|
||||
ins_co_nm?: string;
|
||||
vehicle_info: string;
|
||||
clm_no?: string;
|
||||
clm_amt: number;
|
||||
source_system?: string | null;
|
||||
issupplement: boolean;
|
||||
jobid: UUID | null;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { UUID } from "crypto";
|
||||
import { parse, TypedQueryDocumentNode } from "graphql";
|
||||
import { gql } from "graphql-request";
|
||||
|
||||
import { AvailableJobSchema } from "../decoder/decoder";
|
||||
// Define types for the query result and variables
|
||||
export interface ActiveBodyshopQueryResult {
|
||||
bodyshops: Array<{
|
||||
@@ -9,10 +10,8 @@ export interface ActiveBodyshopQueryResult {
|
||||
region_config: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
// No variables needed for this query
|
||||
interface ActiveBodyshopQueryVariables {}
|
||||
|
||||
// Transform the string query into a TypedQueryDocumentNode
|
||||
export const QUERY_ACTIVE_BODYSHOP_TYPED: TypedQueryDocumentNode<
|
||||
ActiveBodyshopQueryResult,
|
||||
@@ -25,7 +24,10 @@ export const QUERY_ACTIVE_BODYSHOP_TYPED: TypedQueryDocumentNode<
|
||||
region_config
|
||||
}
|
||||
}
|
||||
`);
|
||||
`) as TypedQueryDocumentNode<
|
||||
ActiveBodyshopQueryResult,
|
||||
ActiveBodyshopQueryVariables
|
||||
>;
|
||||
|
||||
export interface MasterdataQueryResult {
|
||||
masterdata: Array<{
|
||||
@@ -33,11 +35,9 @@ export interface MasterdataQueryResult {
|
||||
key: string;
|
||||
}>;
|
||||
}
|
||||
|
||||
interface MasterdataQueryVariables {
|
||||
key: string;
|
||||
}
|
||||
|
||||
export const QUERY_MASTERDATA_TYPED: TypedQueryDocumentNode<
|
||||
MasterdataQueryResult,
|
||||
MasterdataQueryVariables
|
||||
@@ -48,19 +48,16 @@ export const QUERY_MASTERDATA_TYPED: TypedQueryDocumentNode<
|
||||
key
|
||||
}
|
||||
}
|
||||
`);
|
||||
`) as TypedQueryDocumentNode<MasterdataQueryResult, MasterdataQueryVariables>;
|
||||
|
||||
export interface VehicleQueryResult {
|
||||
masterdata: Array<{
|
||||
value: string;
|
||||
key: string;
|
||||
vehicles: Array<{
|
||||
id: UUID;
|
||||
}>;
|
||||
}
|
||||
|
||||
interface VehicleQueryVariables {
|
||||
vin: string;
|
||||
}
|
||||
|
||||
export const QUERY_VEHICLE_BY_VIN_TYPED: TypedQueryDocumentNode<
|
||||
VehicleQueryResult,
|
||||
VehicleQueryVariables
|
||||
@@ -70,4 +67,62 @@ export const QUERY_VEHICLE_BY_VIN_TYPED: TypedQueryDocumentNode<
|
||||
id
|
||||
}
|
||||
}
|
||||
`);
|
||||
`) as TypedQueryDocumentNode<VehicleQueryResult, VehicleQueryVariables>;
|
||||
|
||||
export interface QueryJobByClmNoResult {
|
||||
jobs: Array<{
|
||||
id: UUID;
|
||||
}>;
|
||||
}
|
||||
export interface QueryJobByClmNoVariables {
|
||||
clm_no: string;
|
||||
}
|
||||
export const QUERY_JOB_BY_CLM_NO_TYPED: TypedQueryDocumentNode<
|
||||
QueryJobByClmNoResult,
|
||||
QueryJobByClmNoVariables
|
||||
> = parse(gql`
|
||||
query QUERY_JOB_BY_CLM_NO($clm_no: String!) {
|
||||
jobs(where: { clm_no: { _eq: $clm_no } }) {
|
||||
id
|
||||
}
|
||||
}
|
||||
`) as TypedQueryDocumentNode<QueryJobByClmNoResult, QueryJobByClmNoVariables>;
|
||||
|
||||
export interface InsertAvailableJobResult {
|
||||
returning: Array<{
|
||||
id: UUID;
|
||||
}>;
|
||||
}
|
||||
export interface InsertAvailableJobVariables {
|
||||
jobInput: Array<AvailableJobSchema>;
|
||||
}
|
||||
export const INSERT_AVAILABLE_JOB_TYPED: TypedQueryDocumentNode<
|
||||
InsertAvailableJobResult,
|
||||
InsertAvailableJobVariables
|
||||
> = parse(gql`
|
||||
mutation INSERT_AVAILABLE_JOB($jobInput: [available_jobs_insert_input!]!) {
|
||||
insert_available_jobs(
|
||||
objects: $jobInput
|
||||
on_conflict: {
|
||||
constraint: available_jobs_clm_no_bodyshopid_key
|
||||
update_columns: [
|
||||
clm_amt
|
||||
cieca_id
|
||||
est_data
|
||||
issupplement
|
||||
ownr_name
|
||||
source_system
|
||||
supplement_number
|
||||
vehicle_info
|
||||
]
|
||||
}
|
||||
) {
|
||||
returning {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
`) as TypedQueryDocumentNode<
|
||||
InsertAvailableJobResult,
|
||||
InsertAvailableJobVariables
|
||||
>;
|
||||
|
||||
@@ -3,7 +3,7 @@ import log from "electron-log/main";
|
||||
import path from "path";
|
||||
import ipcTypes from "../../util/ipcTypes.json";
|
||||
import ImportJob from "../decoder/decoder";
|
||||
import { StartWatcher } from "../watcher/watcher";
|
||||
import { StartWatcher, StopWatcher } from "../watcher/watcher";
|
||||
import {
|
||||
SettingsWatchedFilePathsAdd,
|
||||
SettingsWatchedFilePathsGet,
|
||||
@@ -83,4 +83,8 @@ ipcMain.on(ipcTypes.toMain.watcher.start, () => {
|
||||
StartWatcher();
|
||||
});
|
||||
|
||||
ipcMain.on(ipcTypes.toMain.watcher.stop, () => {
|
||||
StopWatcher();
|
||||
});
|
||||
|
||||
logIpcMessages();
|
||||
|
||||
@@ -2,6 +2,7 @@ import { BrowserWindow, dialog, IpcMainInvokeEvent } from "electron";
|
||||
import log from "electron-log/main";
|
||||
import _ from "lodash";
|
||||
import Store from "../store/store";
|
||||
import { addWatcherPath, removeWatcherPath, watcher } from "../watcher/watcher";
|
||||
|
||||
const SettingsWatchedFilePathsAdd = async (): Promise<string[]> => {
|
||||
const mainWindow = BrowserWindow.getAllWindows()[0]; //TODO: Filter to only main window once a proper key has been set.
|
||||
@@ -18,6 +19,7 @@ const SettingsWatchedFilePathsAdd = async (): Promise<string[]> => {
|
||||
"settings.filepaths",
|
||||
_.union(result.filePaths, Store.get("settings.filepaths"))
|
||||
);
|
||||
addWatcherPath(result.filePaths);
|
||||
}
|
||||
|
||||
return Store.get("settings.filepaths");
|
||||
@@ -30,7 +32,7 @@ const SettingsWatchedFilePathsRemove = async (
|
||||
"settings.filepaths",
|
||||
_.without(Store.get("settings.filepaths"), path)
|
||||
);
|
||||
|
||||
removeWatcherPath(path);
|
||||
return Store.get("settings.filepaths");
|
||||
};
|
||||
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
import chokidar, { FSWatcher } from "chokidar";
|
||||
import { Notification } from "electron";
|
||||
import { BrowserWindow, Notification } from "electron";
|
||||
import log from "electron-log/main";
|
||||
import path from "path";
|
||||
import errorTypeCheck from "../../util/errorTypeCheck";
|
||||
import store from "../store/store";
|
||||
import ipcTypes from "../../util/ipcTypes.json";
|
||||
import ImportJob from "../decoder/decoder";
|
||||
import store from "../store/store";
|
||||
|
||||
let watcher: FSWatcher;
|
||||
|
||||
@@ -67,6 +68,10 @@ async function StartWatcher(): Promise<boolean> {
|
||||
// })
|
||||
.on("error", function (error) {
|
||||
log.error("Error in Watcher", errorTypeCheck(error));
|
||||
// mainWindow.webContents.send(
|
||||
// ipcTypes.toRenderer.watcher.error,
|
||||
// errorTypeCheck(error)
|
||||
// );
|
||||
})
|
||||
.on("ready", onWatcherReady)
|
||||
.on("raw", function (event, path, details) {
|
||||
@@ -77,24 +82,37 @@ async function StartWatcher(): Promise<boolean> {
|
||||
return true;
|
||||
}
|
||||
|
||||
function removeWatcherPath(path: string): void {
|
||||
watcher.unwatch(path);
|
||||
log.debug(`Stopped watching path: ${path}`);
|
||||
}
|
||||
|
||||
function addWatcherPath(path: string | string[]): void {
|
||||
watcher.add(path);
|
||||
log.debug(`Started watching path: ${path}`);
|
||||
}
|
||||
|
||||
function onWatcherReady(): void {
|
||||
log.info("Watcher ready!");
|
||||
// const b = BrowserWindow.getAllWindows()[0];
|
||||
// b.webContents.send(ipcTypes.default.fileWatcher.toRenderer.startSuccess);
|
||||
const mainWindow = BrowserWindow.getAllWindows()[0]; //TODO: Filter to only main window once a proper key has been set.
|
||||
|
||||
new Notification({
|
||||
title: "Watcher Started",
|
||||
body: "Newly exported estimates will be automatically uploaded.",
|
||||
}).show();
|
||||
log.info("Confirmed watched paths:", watcher.getWatched());
|
||||
mainWindow.webContents.send(ipcTypes.toRenderer.watcher.started);
|
||||
}
|
||||
|
||||
async function StopWatcher(): Promise<boolean> {
|
||||
const mainWindow = BrowserWindow.getAllWindows()[0]; //TODO: Filter to only main window once a proper key has been set.
|
||||
|
||||
if (watcher) {
|
||||
await watcher.close();
|
||||
log.info("Watcher stopped.");
|
||||
mainWindow.webContents.send(ipcTypes.toRenderer.watcher.stopped);
|
||||
|
||||
new Notification({
|
||||
title: "RPS Watcher Stopped",
|
||||
title: "Watcher Stopped",
|
||||
body: "Estimates will not be automatically uploaded.",
|
||||
}).show();
|
||||
return true;
|
||||
@@ -107,4 +125,10 @@ async function HandleNewFile(path): Promise<void> {
|
||||
log.log("Received a new file", path);
|
||||
}
|
||||
|
||||
export { StartWatcher, StopWatcher, watcher };
|
||||
export {
|
||||
StartWatcher,
|
||||
StopWatcher,
|
||||
watcher,
|
||||
removeWatcherPath,
|
||||
addWatcherPath,
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user