Almost matching export.
This commit is contained in:
105
package-lock.json
generated
105
package-lock.json
generated
@@ -1,16 +1,17 @@
|
|||||||
{
|
{
|
||||||
"name": "bodyshop-desktop",
|
"name": "bodyshop-desktop",
|
||||||
"version": "1.0.0",
|
"version": "0.0.1-alpha.1",
|
||||||
"lockfileVersion": 3,
|
"lockfileVersion": 3,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "bodyshop-desktop",
|
"name": "bodyshop-desktop",
|
||||||
"version": "1.0.0",
|
"version": "0.0.1-alpha.1",
|
||||||
"hasInstallScript": true,
|
"hasInstallScript": true,
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@electron-toolkit/preload": "^3.0.1",
|
"@electron-toolkit/preload": "^3.0.1",
|
||||||
"@electron-toolkit/utils": "^4.0.0",
|
"@electron-toolkit/utils": "^4.0.0",
|
||||||
|
"@reduxjs/toolkit": "^2.6.1",
|
||||||
"chokidar": "^4.0.3",
|
"chokidar": "^4.0.3",
|
||||||
"dbffile": "^1.12.0",
|
"dbffile": "^1.12.0",
|
||||||
"electron-log": "^5.3.2",
|
"electron-log": "^5.3.2",
|
||||||
@@ -20,7 +21,8 @@
|
|||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"playwright": "^1.51.0",
|
"playwright": "^1.51.0",
|
||||||
"react-error-boundary": "^5.0.0",
|
"react-error-boundary": "^5.0.0",
|
||||||
"react-i18next": "^15.4.1"
|
"react-i18next": "^15.4.1",
|
||||||
|
"react-redux": "^9.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ant-design/v5-patch-for-react-19": "^1.0.3",
|
"@ant-design/v5-patch-for-react-19": "^1.0.3",
|
||||||
@@ -2900,6 +2902,30 @@
|
|||||||
"react-dom": ">=16.9.0"
|
"react-dom": ">=16.9.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@reduxjs/toolkit": {
|
||||||
|
"version": "2.6.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.6.1.tgz",
|
||||||
|
"integrity": "sha512-SSlIqZNYhqm/oMkXbtofwZSt9lrncblzo6YcZ9zoX+zLngRBrCOjK4lNLdkNucJF58RHOWrD9txT3bT3piH7Zw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"immer": "^10.0.3",
|
||||||
|
"redux": "^5.0.1",
|
||||||
|
"redux-thunk": "^3.1.0",
|
||||||
|
"reselect": "^5.1.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.9.0 || ^17.0.0 || ^18 || ^19",
|
||||||
|
"react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"react-redux": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||||
"version": "4.35.0",
|
"version": "4.35.0",
|
||||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.35.0.tgz",
|
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.35.0.tgz",
|
||||||
@@ -3352,7 +3378,7 @@
|
|||||||
"version": "19.0.10",
|
"version": "19.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.0.10.tgz",
|
||||||
"integrity": "sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==",
|
"integrity": "sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"csstype": "^3.0.2"
|
"csstype": "^3.0.2"
|
||||||
@@ -3377,6 +3403,12 @@
|
|||||||
"@types/node": "*"
|
"@types/node": "*"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/@types/use-sync-external-store": {
|
||||||
|
"version": "0.0.6",
|
||||||
|
"resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
|
||||||
|
"integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/@types/verror": {
|
"node_modules/@types/verror": {
|
||||||
"version": "1.10.11",
|
"version": "1.10.11",
|
||||||
"resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.11.tgz",
|
"resolved": "https://registry.npmjs.org/@types/verror/-/verror-1.10.11.tgz",
|
||||||
@@ -5217,7 +5249,7 @@
|
|||||||
"version": "3.1.3",
|
"version": "3.1.3",
|
||||||
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
|
||||||
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
"integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
|
||||||
"dev": true,
|
"devOptional": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/data-view-buffer": {
|
"node_modules/data-view-buffer": {
|
||||||
@@ -7616,6 +7648,16 @@
|
|||||||
"node": ">= 4"
|
"node": ">= 4"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/immer": {
|
||||||
|
"version": "10.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz",
|
||||||
|
"integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"funding": {
|
||||||
|
"type": "opencollective",
|
||||||
|
"url": "https://opencollective.com/immer"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/import-fresh": {
|
"node_modules/import-fresh": {
|
||||||
"version": "3.3.1",
|
"version": "3.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
|
"resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.3.1.tgz",
|
||||||
@@ -10583,6 +10625,29 @@
|
|||||||
"dev": true,
|
"dev": true,
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
|
"node_modules/react-redux": {
|
||||||
|
"version": "9.2.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
|
||||||
|
"integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
|
||||||
|
"license": "MIT",
|
||||||
|
"dependencies": {
|
||||||
|
"@types/use-sync-external-store": "^0.0.6",
|
||||||
|
"use-sync-external-store": "^1.4.0"
|
||||||
|
},
|
||||||
|
"peerDependencies": {
|
||||||
|
"@types/react": "^18.2.25 || ^19",
|
||||||
|
"react": "^18.0 || ^19",
|
||||||
|
"redux": "^5.0.0"
|
||||||
|
},
|
||||||
|
"peerDependenciesMeta": {
|
||||||
|
"@types/react": {
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"redux": {
|
||||||
|
"optional": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/react-refresh": {
|
"node_modules/react-refresh": {
|
||||||
"version": "0.14.2",
|
"version": "0.14.2",
|
||||||
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
|
"resolved": "https://registry.npmjs.org/react-refresh/-/react-refresh-0.14.2.tgz",
|
||||||
@@ -10684,6 +10749,21 @@
|
|||||||
"url": "https://paulmillr.com/funding/"
|
"url": "https://paulmillr.com/funding/"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/redux": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
|
"node_modules/redux-thunk": {
|
||||||
|
"version": "3.1.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz",
|
||||||
|
"integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"redux": "^5.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/reflect.getprototypeof": {
|
"node_modules/reflect.getprototypeof": {
|
||||||
"version": "1.0.10",
|
"version": "1.0.10",
|
||||||
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
|
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",
|
||||||
@@ -10771,6 +10851,12 @@
|
|||||||
"url": "https://github.com/sponsors/jet2jet"
|
"url": "https://github.com/sponsors/jet2jet"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/reselect": {
|
||||||
|
"version": "5.1.1",
|
||||||
|
"resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz",
|
||||||
|
"integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==",
|
||||||
|
"license": "MIT"
|
||||||
|
},
|
||||||
"node_modules/resize-observer-polyfill": {
|
"node_modules/resize-observer-polyfill": {
|
||||||
"version": "1.5.1",
|
"version": "1.5.1",
|
||||||
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
|
"resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz",
|
||||||
@@ -12115,6 +12201,15 @@
|
|||||||
"punycode": "^2.1.0"
|
"punycode": "^2.1.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"node_modules/use-sync-external-store": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz",
|
||||||
|
"integrity": "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==",
|
||||||
|
"license": "MIT",
|
||||||
|
"peerDependencies": {
|
||||||
|
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
"node_modules/utf8-byte-length": {
|
"node_modules/utf8-byte-length": {
|
||||||
"version": "1.0.5",
|
"version": "1.0.5",
|
||||||
"resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz",
|
"resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.5.tgz",
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@electron-toolkit/preload": "^3.0.1",
|
"@electron-toolkit/preload": "^3.0.1",
|
||||||
"@electron-toolkit/utils": "^4.0.0",
|
"@electron-toolkit/utils": "^4.0.0",
|
||||||
|
"@reduxjs/toolkit": "^2.6.1",
|
||||||
"chokidar": "^4.0.3",
|
"chokidar": "^4.0.3",
|
||||||
"dbffile": "^1.12.0",
|
"dbffile": "^1.12.0",
|
||||||
"electron-log": "^5.3.2",
|
"electron-log": "^5.3.2",
|
||||||
@@ -32,7 +33,8 @@
|
|||||||
"lodash": "^4.17.21",
|
"lodash": "^4.17.21",
|
||||||
"playwright": "^1.51.0",
|
"playwright": "^1.51.0",
|
||||||
"react-error-boundary": "^5.0.0",
|
"react-error-boundary": "^5.0.0",
|
||||||
"react-i18next": "^15.4.1"
|
"react-i18next": "^15.4.1",
|
||||||
|
"react-redux": "^9.2.0"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@ant-design/v5-patch-for-react-19": "^1.0.3",
|
"@ant-design/v5-patch-for-react-19": "^1.0.3",
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ export interface DecodedAd1 {
|
|||||||
ded_amt?: string;
|
ded_amt?: string;
|
||||||
ded_status?: string;
|
ded_status?: string;
|
||||||
asgn_no?: string;
|
asgn_no?: string;
|
||||||
asgn_date?: string;
|
asgn_date?: Date | string;
|
||||||
asgn_type?: string;
|
asgn_type?: string;
|
||||||
|
|
||||||
// Claim information
|
// Claim information
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import log from "electron-log/main";
|
|||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
||||||
import errorTypeCheck from "../../util/errorTypeCheck";
|
import errorTypeCheck from "../../util/errorTypeCheck";
|
||||||
|
import store from "../store/store";
|
||||||
import { DecodedAd1, OwnerRecordInterface } from "./decode-ad1.interface";
|
import { DecodedAd1, OwnerRecordInterface } from "./decode-ad1.interface";
|
||||||
|
|
||||||
const DecodeAD1 = async (
|
const DecodeAD1 = async (
|
||||||
@@ -26,7 +27,9 @@ const DecodeAD1 = async (
|
|||||||
|
|
||||||
//AD1 will always have only 1 row.
|
//AD1 will always have only 1 row.
|
||||||
//Commented lines have been cross referenced with existing partner fields.
|
//Commented lines have been cross referenced with existing partner fields.
|
||||||
|
const d = rawDBFRecord[0].ASGN_DATE;
|
||||||
|
console.log(d);
|
||||||
|
console.log(typeof rawDBFRecord[0].ASGN_DATE);
|
||||||
const rawAd1Data: DecodedAd1 = deepLowerCaseKeys(
|
const rawAd1Data: DecodedAd1 = deepLowerCaseKeys(
|
||||||
_.pick(rawDBFRecord[0], [
|
_.pick(rawDBFRecord[0], [
|
||||||
//TODO: Add typings for EMS File Formats.
|
//TODO: Add typings for EMS File Formats.
|
||||||
@@ -149,6 +152,11 @@ const DecodeAD1 = async (
|
|||||||
|
|
||||||
//Copy specific logic for manipulation.
|
//Copy specific logic for manipulation.
|
||||||
//If ownr_ph1 is missing, use ownr_ph2
|
//If ownr_ph1 is missing, use ownr_ph2
|
||||||
|
if (rawAd1Data.asgn_date) {
|
||||||
|
const newAsgnDate = new Date(rawAd1Data.asgn_date);
|
||||||
|
rawAd1Data.asgn_date = newAsgnDate.toISOString().split("T")[0];
|
||||||
|
}
|
||||||
|
|
||||||
if (!rawAd1Data.ownr_ph1) {
|
if (!rawAd1Data.ownr_ph1) {
|
||||||
rawAd1Data.ownr_ph1 = rawAd1Data.ownr_ph2;
|
rawAd1Data.ownr_ph1 = rawAd1Data.ownr_ph2;
|
||||||
}
|
}
|
||||||
@@ -161,7 +169,8 @@ const DecodeAD1 = async (
|
|||||||
_.isEmpty(rawAd1Data.ownr_co_nm)
|
_.isEmpty(rawAd1Data.ownr_co_nm)
|
||||||
) {
|
) {
|
||||||
//They're all empty. Using the insured information as a fallback.
|
//They're all empty. Using the insured information as a fallback.
|
||||||
// //Build up the owner record to insert it alongside the job.
|
// Build up the owner record to insert it alongside the job.
|
||||||
|
//TODO: Verify that this should be the insured, and not the claimant.
|
||||||
ownerRecord = {
|
ownerRecord = {
|
||||||
ownr_ln: rawAd1Data.insd_ln,
|
ownr_ln: rawAd1Data.insd_ln,
|
||||||
ownr_fn: rawAd1Data.insd_fn,
|
ownr_fn: rawAd1Data.insd_fn,
|
||||||
@@ -176,8 +185,7 @@ const DecodeAD1 = async (
|
|||||||
ownr_ph1: rawAd1Data.insd_ph1,
|
ownr_ph1: rawAd1Data.insd_ph1,
|
||||||
ownr_ph2: rawAd1Data.insd_ph2,
|
ownr_ph2: rawAd1Data.insd_ph2,
|
||||||
ownr_ea: rawAd1Data.insd_ea,
|
ownr_ea: rawAd1Data.insd_ea,
|
||||||
|
shopid: store.get("app.bodyshop.id"),
|
||||||
shopid: "UUID", //TODO: Need to add the shop uuid to this set of functions.
|
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
//Use the owner information.
|
//Use the owner information.
|
||||||
@@ -195,10 +203,11 @@ const DecodeAD1 = async (
|
|||||||
ownr_ph1: rawAd1Data.ownr_ph1,
|
ownr_ph1: rawAd1Data.ownr_ph1,
|
||||||
ownr_ph2: rawAd1Data.ownr_ph2,
|
ownr_ph2: rawAd1Data.ownr_ph2,
|
||||||
ownr_ea: rawAd1Data.ownr_ea,
|
ownr_ea: rawAd1Data.ownr_ea,
|
||||||
shopid: "UUID", //TODO: Need to add the shop uuid to this set of functions.
|
shopid: store.get("app.bodyshop.id"),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
const s = store.get("app");
|
||||||
|
console.log(s);
|
||||||
return { ...rawAd1Data, owner: { data: ownerRecord } };
|
return { ...rawAd1Data, owner: { data: ownerRecord } };
|
||||||
};
|
};
|
||||||
export default DecodeAD1;
|
export default DecodeAD1;
|
||||||
|
|||||||
@@ -30,24 +30,24 @@ const DecodeAD2 = async (
|
|||||||
const rawAd2Data: DecodedAD2 = deepLowerCaseKeys(
|
const rawAd2Data: DecodedAD2 = deepLowerCaseKeys(
|
||||||
_.pick(rawDBFRecord[0], [
|
_.pick(rawDBFRecord[0], [
|
||||||
//TODO: Add typings for EMS File Formats.
|
//TODO: Add typings for EMS File Formats.
|
||||||
"CLMT_LN",
|
// "CLMT_LN", //TODO: This claimant info shouldnt be passed back. Just for the owner info.
|
||||||
"CLMT_FN",
|
// "CLMT_FN",
|
||||||
"CLMT_TITLE",
|
// "CLMT_TITLE",
|
||||||
"CLMT_CO_NM",
|
// "CLMT_CO_NM",
|
||||||
"CLMT_ADDR1",
|
// "CLMT_ADDR1",
|
||||||
"CLMT_ADDR2",
|
// "CLMT_ADDR2",
|
||||||
"CLMT_CITY",
|
// "CLMT_CITY",
|
||||||
"CLMT_ST",
|
// "CLMT_ST",
|
||||||
"CLMT_ZIP",
|
// "CLMT_ZIP",
|
||||||
"CLMT_CTRY",
|
// "CLMT_CTRY",
|
||||||
"CLMT_PH1",
|
// "CLMT_PH1",
|
||||||
//"CLMT_PH1X",
|
//"CLMT_PH1X",
|
||||||
"CLMT_PH2",
|
//"CLMT_PH2",
|
||||||
//"CLMT_PH2X",
|
//"CLMT_PH2X",
|
||||||
//"CLMT_FAX",
|
//"CLMT_FAX",
|
||||||
//"CLMT_FAXX",
|
//"CLMT_FAXX",
|
||||||
"CLMT_EA",
|
//"CLMT_EA",
|
||||||
"EST_CO_ID",
|
//"EST_CO_ID",
|
||||||
"EST_CO_NM",
|
"EST_CO_NM",
|
||||||
"EST_ADDR1",
|
"EST_ADDR1",
|
||||||
"EST_ADDR2",
|
"EST_ADDR2",
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
export interface DecodedEnv {
|
export interface DecodedEnv {
|
||||||
est_system: string;
|
est_system?: string;
|
||||||
estfile_id: string;
|
estfile_id?: string;
|
||||||
|
ciecaid?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,10 +30,12 @@ const DecodeEnv = async (
|
|||||||
_.pick(rawDBFRecord[0], [
|
_.pick(rawDBFRecord[0], [
|
||||||
//TODO: Add typings for EMS File Formats.
|
//TODO: Add typings for EMS File Formats.
|
||||||
//TODO: Several of these fields will fail. Should extend schema to capture them.
|
//TODO: Several of these fields will fail. Should extend schema to capture them.
|
||||||
"EST_SYSTEM",
|
//"EST_SYSTEM",
|
||||||
"ESTFILE_ID",
|
"ESTFILE_ID",
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
|
rawEnvData.ciecaid = rawEnvData.estfile_id;
|
||||||
|
delete rawEnvData.estfile_id;
|
||||||
|
|
||||||
//Apply business logic transfomrations.
|
//Apply business logic transfomrations.
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export interface DecodedLin {
|
export interface DecodedLinLine {
|
||||||
line_no?: string;
|
line_no?: string;
|
||||||
line_ind?: string;
|
line_ind?: string;
|
||||||
line_ref?: string;
|
line_ref?: string;
|
||||||
@@ -46,3 +46,9 @@ export interface DecodedLin {
|
|||||||
bett_tax?: boolean;
|
bett_tax?: boolean;
|
||||||
op_code_desc?: string;
|
op_code_desc?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DecodedLin {
|
||||||
|
joblines: {
|
||||||
|
data: DecodedLinLine[];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,12 +2,12 @@ import { DBFFile } from "dbffile";
|
|||||||
import log from "electron-log/main";
|
import log from "electron-log/main";
|
||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
||||||
import { DecodedLin } from "./decode-lin.interface";
|
import { DecodedLin, DecodedLinLine } from "./decode-lin.interface";
|
||||||
import errorTypeCheck from "../../util/errorTypeCheck";
|
import errorTypeCheck from "../../util/errorTypeCheck";
|
||||||
|
|
||||||
const DecodeLin = async (
|
const DecodeLin = async (
|
||||||
extensionlessFilePath: string
|
extensionlessFilePath: string
|
||||||
): Promise<DecodedLin[]> => {
|
): Promise<DecodedLin> => {
|
||||||
let dbf: DBFFile | null = null;
|
let dbf: DBFFile | null = null;
|
||||||
try {
|
try {
|
||||||
dbf = await DBFFile.open(`${extensionlessFilePath}.LIN`);
|
dbf = await DBFFile.open(`${extensionlessFilePath}.LIN`);
|
||||||
@@ -26,8 +26,8 @@ const DecodeLin = async (
|
|||||||
//AD2 will always have only 1 row.
|
//AD2 will always have only 1 row.
|
||||||
//Commented lines have been cross referenced with existing partner fields.
|
//Commented lines have been cross referenced with existing partner fields.
|
||||||
|
|
||||||
const rawLinData: DecodedLin[] = rawDBFRecord.map((record) => {
|
const rawLinData: DecodedLinLine[] = rawDBFRecord.map((record) => {
|
||||||
const singleLineData: DecodedLin = deepLowerCaseKeys(
|
const singleLineData: DecodedLinLine = deepLowerCaseKeys(
|
||||||
_.pick(record, [
|
_.pick(record, [
|
||||||
//TODO: Add typings for EMS File Formats.
|
//TODO: Add typings for EMS File Formats.
|
||||||
"LINE_NO",
|
"LINE_NO",
|
||||||
@@ -99,6 +99,6 @@ const DecodeLin = async (
|
|||||||
//Apply business logic transfomrations.
|
//Apply business logic transfomrations.
|
||||||
//We don't have an inspection date, we instead have `date_estimated`
|
//We don't have an inspection date, we instead have `date_estimated`
|
||||||
|
|
||||||
return rawLinData;
|
return { joblines: { data: rawLinData } };
|
||||||
};
|
};
|
||||||
export default DecodeLin;
|
export default DecodeLin;
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ const DecodePfh = async (
|
|||||||
_.pick(rawDBFRecord[0], [
|
_.pick(rawDBFRecord[0], [
|
||||||
//TODO: Add typings for EMS File Formats.
|
//TODO: Add typings for EMS File Formats.
|
||||||
//TODO: Several of these fields will fail. Should extend schema to capture them.
|
//TODO: Several of these fields will fail. Should extend schema to capture them.
|
||||||
"ID_PRO_NAM", //Remove
|
//"ID_PRO_NAM", //Remove
|
||||||
"TAX_PRETHR",
|
"TAX_PRETHR",
|
||||||
"TAX_THRAMT", //Remove
|
"TAX_THRAMT", //Remove
|
||||||
"TAX_PSTTHR",
|
"TAX_PSTTHR",
|
||||||
@@ -48,7 +48,7 @@ const DecodePfh = async (
|
|||||||
"ADJ_G_DISC",
|
"ADJ_G_DISC",
|
||||||
"ADJ_TOWDIS",
|
"ADJ_TOWDIS",
|
||||||
"ADJ_STRDIS",
|
"ADJ_STRDIS",
|
||||||
"ADJ_BTR_IN", //Remove
|
//"ADJ_BTR_IN", //Remove
|
||||||
"TAX_PREDIS",
|
"TAX_PREDIS",
|
||||||
])
|
])
|
||||||
);
|
);
|
||||||
@@ -57,13 +57,13 @@ const DecodePfh = async (
|
|||||||
|
|
||||||
//Standardize some of the numbers and divide by 100.
|
//Standardize some of the numbers and divide by 100.
|
||||||
|
|
||||||
rawPfhData.tax_prethr = rawPfhData.tax_prethr ?? 0 / 100;
|
rawPfhData.tax_prethr = (rawPfhData.tax_prethr ?? 0) / 100;
|
||||||
rawPfhData.tax_pstthr = rawPfhData.tax_pstthr ?? 0 / 100;
|
rawPfhData.tax_pstthr = (rawPfhData.tax_pstthr ?? 0) / 100;
|
||||||
rawPfhData.tax_tow_rt = rawPfhData.tax_tow_rt ?? 0 / 100;
|
rawPfhData.tax_tow_rt = (rawPfhData.tax_tow_rt ?? 0) / 100;
|
||||||
rawPfhData.tax_str_rt = rawPfhData.tax_str_rt ?? 0 / 100;
|
rawPfhData.tax_str_rt = (rawPfhData.tax_str_rt ?? 0) / 100;
|
||||||
rawPfhData.tax_sub_rt = rawPfhData.tax_sub_rt ?? 0 / 100;
|
rawPfhData.tax_sub_rt = (rawPfhData.tax_sub_rt ?? 0) / 100;
|
||||||
rawPfhData.tax_lbr_rt = rawPfhData.tax_lbr_rt ?? 0 / 100;
|
rawPfhData.tax_lbr_rt = (rawPfhData.tax_lbr_rt ?? 0) / 100;
|
||||||
rawPfhData.federal_tax_rate = rawPfhData.tax_gst_rt ?? 0 / 100;
|
rawPfhData.federal_tax_rate = (rawPfhData.tax_gst_rt ?? 0) / 100;
|
||||||
delete rawPfhData.tax_gst_rt;
|
delete rawPfhData.tax_gst_rt;
|
||||||
|
|
||||||
return rawPfhData;
|
return rawPfhData;
|
||||||
|
|||||||
@@ -42,5 +42,9 @@ export interface JobMaterialRateFields {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export interface DecodedPfm extends JobMaterialRateFields {
|
export interface DecodedPfm extends JobMaterialRateFields {
|
||||||
|
materials: {
|
||||||
|
mapa?: DecodedPfmLine;
|
||||||
|
mash?: DecodedPfmLine;
|
||||||
|
};
|
||||||
cieca_pfm: DecodedPfmLine[];
|
cieca_pfm: DecodedPfmLine[];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,12 @@ import log from "electron-log/main";
|
|||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
||||||
import errorTypeCheck from "../../util/errorTypeCheck";
|
import errorTypeCheck from "../../util/errorTypeCheck";
|
||||||
|
import YNBoolConverter from "../../util/ynBoolConverter";
|
||||||
import {
|
import {
|
||||||
DecodedPfm,
|
DecodedPfm,
|
||||||
DecodedPfmLine,
|
DecodedPfmLine,
|
||||||
JobMaterialRateFields,
|
JobMaterialRateFields,
|
||||||
} from "./decode-pfm.interface";
|
} from "./decode-pfm.interface";
|
||||||
import YNBoolConverter from "../../util/ynBoolConverter";
|
|
||||||
|
|
||||||
const DecodePfm = async (
|
const DecodePfm = async (
|
||||||
extensionlessFilePath: string
|
extensionlessFilePath: string
|
||||||
@@ -98,7 +98,7 @@ const DecodePfm = async (
|
|||||||
if (mapaLine) {
|
if (mapaLine) {
|
||||||
jobMaterialRates.rate_mapa =
|
jobMaterialRates.rate_mapa =
|
||||||
mapaLine.cal_lbrrte || mapaLine.cal_prethr || 0;
|
mapaLine.cal_lbrrte || mapaLine.cal_prethr || 0;
|
||||||
jobMaterialRates.tax_paint_mat_rt = mapaLine.mat_taxp ?? 0 / 100;
|
jobMaterialRates.tax_paint_mat_rt = (mapaLine.mat_taxp ?? 0) / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
const mashLine: DecodedPfmLine | undefined = rawPfmData.find(
|
const mashLine: DecodedPfmLine | undefined = rawPfmData.find(
|
||||||
@@ -107,7 +107,7 @@ const DecodePfm = async (
|
|||||||
if (mashLine) {
|
if (mashLine) {
|
||||||
jobMaterialRates.rate_mash =
|
jobMaterialRates.rate_mash =
|
||||||
mashLine.cal_lbrrte || mashLine.cal_prethr || 0;
|
mashLine.cal_lbrrte || mashLine.cal_prethr || 0;
|
||||||
jobMaterialRates.tax_shop_mat_rt = mashLine.mat_taxp ?? 0 / 100;
|
jobMaterialRates.tax_shop_mat_rt = (mashLine.mat_taxp ?? 0) / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
const mahwLine: DecodedPfmLine | undefined = rawPfmData.find(
|
const mahwLine: DecodedPfmLine | undefined = rawPfmData.find(
|
||||||
@@ -116,7 +116,7 @@ const DecodePfm = async (
|
|||||||
if (mahwLine) {
|
if (mahwLine) {
|
||||||
jobMaterialRates.rate_mahw =
|
jobMaterialRates.rate_mahw =
|
||||||
mahwLine.cal_lbrrte || mahwLine.cal_prethr || 0;
|
mahwLine.cal_lbrrte || mahwLine.cal_prethr || 0;
|
||||||
jobMaterialRates.tax_levies_rt = mahwLine.mat_taxp ?? 0 / 100;
|
jobMaterialRates.tax_levies_rt = (mahwLine.mat_taxp ?? 0) / 100;
|
||||||
}
|
}
|
||||||
|
|
||||||
const additionalMaterials = ["MA2S", "MA2T", "MA3S", "MACS", "MABL"];
|
const additionalMaterials = ["MA2S", "MA2T", "MA3S", "MACS", "MABL"];
|
||||||
@@ -133,7 +133,14 @@ const DecodePfm = async (
|
|||||||
//Apply business logic transfomrations.
|
//Apply business logic transfomrations.
|
||||||
//We don't have an inspection date, we instead have `date_estimated`
|
//We don't have an inspection date, we instead have `date_estimated`
|
||||||
|
|
||||||
return { ...jobMaterialRates, cieca_pfm: rawPfmData };
|
return {
|
||||||
|
...jobMaterialRates,
|
||||||
|
materials: {
|
||||||
|
mash: mashLine,
|
||||||
|
mapa: mapaLine,
|
||||||
|
},
|
||||||
|
cieca_pfm: rawPfmData,
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DecodePfm;
|
export default DecodePfm;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export interface DecodedPfo {
|
export interface DecodedPfoLine {
|
||||||
tx_tow_ty?: string;
|
tx_tow_ty?: string;
|
||||||
tow_t_ty1?: string;
|
tow_t_ty1?: string;
|
||||||
tow_t_in1?: boolean;
|
tow_t_in1?: boolean;
|
||||||
@@ -26,3 +26,7 @@ export interface DecodedPfo {
|
|||||||
stor_t_ty6?: string;
|
stor_t_ty6?: string;
|
||||||
stor_t_in6?: boolean;
|
stor_t_in6?: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DecodedPfo {
|
||||||
|
cieca_pfo: DecodedPfoLine;
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import log from "electron-log/main";
|
|||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
||||||
import errorTypeCheck from "../../util/errorTypeCheck";
|
import errorTypeCheck from "../../util/errorTypeCheck";
|
||||||
import { DecodedPfo } from "./decode-pfo.interface";
|
|
||||||
import YNBoolConverter from "../../util/ynBoolConverter";
|
import YNBoolConverter from "../../util/ynBoolConverter";
|
||||||
|
import { DecodedPfo, DecodedPfoLine } from "./decode-pfo.interface";
|
||||||
|
|
||||||
const DecodePfo = async (
|
const DecodePfo = async (
|
||||||
extensionlessFilePath: string
|
extensionlessFilePath: string
|
||||||
@@ -28,7 +28,7 @@ const DecodePfo = async (
|
|||||||
//PFO will always have only 1 row.
|
//PFO will always have only 1 row.
|
||||||
//Commented lines have been cross referenced with existing partner fields.
|
//Commented lines have been cross referenced with existing partner fields.
|
||||||
|
|
||||||
const rawPfoData: DecodedPfo = YNBoolConverter(
|
const rawPfoData: DecodedPfoLine = YNBoolConverter(
|
||||||
deepLowerCaseKeys(
|
deepLowerCaseKeys(
|
||||||
_.pick(rawDBFRecord[0], [
|
_.pick(rawDBFRecord[0], [
|
||||||
//TODO: Add typings for EMS File Formats.
|
//TODO: Add typings for EMS File Formats.
|
||||||
@@ -64,6 +64,6 @@ const DecodePfo = async (
|
|||||||
|
|
||||||
//Apply business logic transfomrations.
|
//Apply business logic transfomrations.
|
||||||
|
|
||||||
return rawPfoData;
|
return { cieca_pfo: rawPfoData };
|
||||||
};
|
};
|
||||||
export default DecodePfo;
|
export default DecodePfo;
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ export interface DecodedPfpLine {
|
|||||||
prt_tx_in5: boolean;
|
prt_tx_in5: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DecodedPfp {
|
export interface DecodedPfpLinesByType {
|
||||||
PAA: DecodedPfpLine;
|
PAA: DecodedPfpLine;
|
||||||
PAC: DecodedPfpLine;
|
PAC: DecodedPfpLine;
|
||||||
PAL: DecodedPfpLine;
|
PAL: DecodedPfpLine;
|
||||||
@@ -31,3 +31,7 @@ export interface DecodedPfp {
|
|||||||
PASL: DecodedPfpLine;
|
PASL: DecodedPfpLine;
|
||||||
PAT: DecodedPfpLine;
|
PAT: DecodedPfpLine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DecodedPfp {
|
||||||
|
parts_tax_rates: DecodedPfpLinesByType;
|
||||||
|
}
|
||||||
|
|||||||
@@ -4,7 +4,11 @@ import _ from "lodash";
|
|||||||
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
||||||
import errorTypeCheck from "../../util/errorTypeCheck";
|
import errorTypeCheck from "../../util/errorTypeCheck";
|
||||||
import YNBoolConverter from "../../util/ynBoolConverter";
|
import YNBoolConverter from "../../util/ynBoolConverter";
|
||||||
import { DecodedPfp, DecodedPfpLine } from "./decode-pfp.interface";
|
import {
|
||||||
|
DecodedPfp,
|
||||||
|
DecodedPfpLine,
|
||||||
|
DecodedPfpLinesByType,
|
||||||
|
} from "./decode-pfp.interface";
|
||||||
|
|
||||||
const DecodePfp = async (
|
const DecodePfp = async (
|
||||||
extensionlessFilePath: string
|
extensionlessFilePath: string
|
||||||
@@ -57,15 +61,15 @@ const DecodePfp = async (
|
|||||||
//Apply business logic transfomrations.
|
//Apply business logic transfomrations.
|
||||||
|
|
||||||
//Convert array of lines to a hash object.
|
//Convert array of lines to a hash object.
|
||||||
const parsedPfpFile: DecodedPfp = rawPfpData.reduce(
|
const parsedPfpFile: DecodedPfpLinesByType = rawPfpData.reduce(
|
||||||
(acc: DecodedPfp, line: DecodedPfpLine) => {
|
(acc: DecodedPfpLinesByType, line: DecodedPfpLine) => {
|
||||||
acc[line.prt_type] = line;
|
acc[line.prt_type] = line;
|
||||||
return acc;
|
return acc;
|
||||||
},
|
},
|
||||||
{} as DecodedPfp
|
{} as DecodedPfpLinesByType
|
||||||
);
|
);
|
||||||
|
|
||||||
return parsedPfpFile;
|
return { parts_tax_rates: parsedPfpFile };
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DecodePfp;
|
export default DecodePfp;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
* Interface representing decoded data from a PFT file
|
* Interface representing decoded data from a PFT file
|
||||||
* Contains tax type information with up to 6 tax types and 5 tiers each
|
* Contains tax type information with up to 6 tax types and 5 tiers each
|
||||||
*/
|
*/
|
||||||
export interface DecodedPft {
|
export interface DecodedPftLine {
|
||||||
// Tax Type 1
|
// Tax Type 1
|
||||||
tax_type1?: string;
|
tax_type1?: string;
|
||||||
ty1_tier1?: number;
|
ty1_tier1?: number;
|
||||||
@@ -141,3 +141,7 @@ export interface DecodedPft {
|
|||||||
ty6_rate5?: number;
|
ty6_rate5?: number;
|
||||||
ty6_sur5?: number;
|
ty6_sur5?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DecodedPft {
|
||||||
|
cieca_pft: DecodedPftLine;
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ import log from "electron-log/main";
|
|||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
||||||
import errorTypeCheck from "../../util/errorTypeCheck";
|
import errorTypeCheck from "../../util/errorTypeCheck";
|
||||||
import { DecodedPft } from "./decode-pft.interface";
|
import { DecodedPft, DecodedPftLine } from "./decode-pft.interface";
|
||||||
|
|
||||||
const DecodePft = async (
|
const DecodePft = async (
|
||||||
extensionlessFilePath: string
|
extensionlessFilePath: string
|
||||||
@@ -25,7 +25,7 @@ const DecodePft = async (
|
|||||||
//PFT will always have only 1 row.
|
//PFT will always have only 1 row.
|
||||||
//Commented lines have been cross referenced with existing partner fields.
|
//Commented lines have been cross referenced with existing partner fields.
|
||||||
|
|
||||||
const rawPftData: DecodedPft = deepLowerCaseKeys(
|
const rawPftData: DecodedPftLine = deepLowerCaseKeys(
|
||||||
_.pick(rawDBFRecord[0], [
|
_.pick(rawDBFRecord[0], [
|
||||||
//TODO: Add typings for EMS File Formats.
|
//TODO: Add typings for EMS File Formats.
|
||||||
"TAX_TYPE1", //The below is is taken from a CCC estimate. Will require validation to ensure it is also accurate for Audatex/Mitchell
|
"TAX_TYPE1", //The below is is taken from a CCC estimate. Will require validation to ensure it is also accurate for Audatex/Mitchell
|
||||||
@@ -160,6 +160,6 @@ const DecodePft = async (
|
|||||||
//Apply business logic transfomrations.
|
//Apply business logic transfomrations.
|
||||||
//We don't have an inspection date, we instead have `date_estimated`
|
//We don't have an inspection date, we instead have `date_estimated`
|
||||||
|
|
||||||
return rawPftData;
|
return { cieca_pft: rawPftData };
|
||||||
};
|
};
|
||||||
export default DecodePft;
|
export default DecodePft;
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
export interface DecodedStl {
|
export interface DecodedStlLine {
|
||||||
ttl_type?: string;
|
ttl_type?: string;
|
||||||
ttl_typecd?: string;
|
ttl_typecd?: string;
|
||||||
t_amt?: number;
|
t_amt?: number;
|
||||||
@@ -18,3 +18,6 @@ export interface DecodedStl {
|
|||||||
ttl_hrs?: number;
|
ttl_hrs?: number;
|
||||||
ttl_amt?: number;
|
ttl_amt?: number;
|
||||||
}
|
}
|
||||||
|
export interface DecodedStl {
|
||||||
|
cieca_stl: DecodedStlLine[];
|
||||||
|
}
|
||||||
|
|||||||
@@ -3,11 +3,11 @@ import log from "electron-log/main";
|
|||||||
import _ from "lodash";
|
import _ from "lodash";
|
||||||
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
||||||
import errorTypeCheck from "../../util/errorTypeCheck";
|
import errorTypeCheck from "../../util/errorTypeCheck";
|
||||||
import { DecodedStl } from "./decode-stl.interface";
|
import { DecodedStl, DecodedStlLine } from "./decode-stl.interface";
|
||||||
|
|
||||||
const DecodeStl = async (
|
const DecodeStl = async (
|
||||||
extensionlessFilePath: string
|
extensionlessFilePath: string
|
||||||
): Promise<DecodedStl[]> => {
|
): Promise<DecodedStl> => {
|
||||||
let dbf: DBFFile | null = null;
|
let dbf: DBFFile | null = null;
|
||||||
try {
|
try {
|
||||||
dbf = await DBFFile.open(`${extensionlessFilePath}.STL`);
|
dbf = await DBFFile.open(`${extensionlessFilePath}.STL`);
|
||||||
@@ -25,8 +25,8 @@ const DecodeStl = async (
|
|||||||
//AD2 will always have only 1 row.
|
//AD2 will always have only 1 row.
|
||||||
//Commented lines have been cross referenced with existing partner fields.
|
//Commented lines have been cross referenced with existing partner fields.
|
||||||
|
|
||||||
const rawStlData: DecodedStl[] = rawDBFRecord.map((record) => {
|
const rawStlData: DecodedStlLine[] = rawDBFRecord.map((record) => {
|
||||||
const singleLineData: DecodedStl = deepLowerCaseKeys(
|
const singleLineData: DecodedStlLine = deepLowerCaseKeys(
|
||||||
_.pick(record, [
|
_.pick(record, [
|
||||||
//TODO: Add typings for EMS File Formats.
|
//TODO: Add typings for EMS File Formats.
|
||||||
"TTL_TYPE",
|
"TTL_TYPE",
|
||||||
@@ -57,6 +57,6 @@ const DecodeStl = async (
|
|||||||
//Apply business logic transfomrations.
|
//Apply business logic transfomrations.
|
||||||
//We don't have an inspection date, we instead have `date_estimated`
|
//We don't have an inspection date, we instead have `date_estimated`
|
||||||
|
|
||||||
return rawStlData;
|
return { cieca_stl: rawStlData };
|
||||||
};
|
};
|
||||||
export default DecodeStl;
|
export default DecodeStl;
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ const DecodeTtl = async (
|
|||||||
//Apply business logic transfomrations.
|
//Apply business logic transfomrations.
|
||||||
|
|
||||||
return {
|
return {
|
||||||
clm_total: 0,
|
clm_total: rawTtlData.g_ttl_amt || 0,
|
||||||
depreciation_taxes: 0,
|
depreciation_taxes: 0, //TODO: Find where this needs to be filled from
|
||||||
cieca_ttl: { data: rawTtlData },
|
cieca_ttl: { data: rawTtlData },
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -10,14 +10,17 @@ export interface DecodedVeh {
|
|||||||
v_model_desc?: string;
|
v_model_desc?: string;
|
||||||
v_color?: string;
|
v_color?: string;
|
||||||
kmin?: number;
|
kmin?: number;
|
||||||
|
area_of_damage?: {
|
||||||
|
impact1?: string;
|
||||||
|
impact2?: string;
|
||||||
|
};
|
||||||
// Complete vehicle data object
|
// Complete vehicle data object
|
||||||
vehicle: { data: VehicleRecordInterface };
|
vehicle: { data: VehicleRecordInterface };
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface VehicleRecordInterface {
|
export interface VehicleRecordInterface {
|
||||||
// Area of damage information
|
// Area of damage information
|
||||||
area_of_damage: {
|
area_of_damage?: {
|
||||||
impact1?: string;
|
impact1?: string;
|
||||||
impact2?: string;
|
impact2?: string;
|
||||||
};
|
};
|
||||||
@@ -45,7 +48,7 @@ export interface VehicleRecordInterface {
|
|||||||
trim_color?: string;
|
trim_color?: string;
|
||||||
v_mldgcode?: string;
|
v_mldgcode?: string;
|
||||||
v_engine?: string;
|
v_engine?: string;
|
||||||
v_mileage?: string;
|
v_mileage?: number; //TODO: This can sometimes come in as UNK.
|
||||||
v_color?: string;
|
v_color?: string;
|
||||||
v_tone?: string;
|
v_tone?: string;
|
||||||
v_stage?: string;
|
v_stage?: string;
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import _ from "lodash";
|
|||||||
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
import deepLowerCaseKeys from "../../util/deepLowercaseKeys";
|
||||||
import { DecodedVeh, VehicleRecordInterface } from "./decode-veh.interface";
|
import { DecodedVeh, VehicleRecordInterface } from "./decode-veh.interface";
|
||||||
import errorTypeCheck from "../../util/errorTypeCheck";
|
import errorTypeCheck from "../../util/errorTypeCheck";
|
||||||
|
import store from "../store/store";
|
||||||
|
|
||||||
const DecodeVeh = async (
|
const DecodeVeh = async (
|
||||||
extensionlessFilePath: string
|
extensionlessFilePath: string
|
||||||
@@ -85,10 +86,10 @@ const DecodeVeh = async (
|
|||||||
delete rawVehData.paint_cd2;
|
delete rawVehData.paint_cd2;
|
||||||
delete rawVehData.paint_cd3;
|
delete rawVehData.paint_cd3;
|
||||||
|
|
||||||
rawVehData.shopid = "UUID"; //TODO: Pass down the shopid for generation.
|
rawVehData.shopid = store.get("app.bodyshop.id");
|
||||||
|
|
||||||
//Aggregate the vehicle data to be stamped onto the job record.
|
//Aggregate the vehicle data to be stamped onto the job record.
|
||||||
const jobVehiclData = {
|
const jobVehicleData: DecodedVeh = {
|
||||||
plate_no: rawVehData.plate_no,
|
plate_no: rawVehData.plate_no,
|
||||||
plate_st: rawVehData.plate_st,
|
plate_st: rawVehData.plate_st,
|
||||||
v_vin: rawVehData.v_vin,
|
v_vin: rawVehData.v_vin,
|
||||||
@@ -97,14 +98,13 @@ const DecodeVeh = async (
|
|||||||
v_model_desc: rawVehData.v_model_desc,
|
v_model_desc: rawVehData.v_model_desc,
|
||||||
v_color: rawVehData.v_color,
|
v_color: rawVehData.v_color,
|
||||||
kmin: rawVehData.v_mileage,
|
kmin: rawVehData.v_mileage,
|
||||||
};
|
area_of_damage: rawVehData.area_of_damage,
|
||||||
|
|
||||||
return {
|
|
||||||
...jobVehiclData,
|
|
||||||
vehicle: {
|
vehicle: {
|
||||||
data: rawVehData,
|
data: rawVehData,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
return jobVehicleData;
|
||||||
};
|
};
|
||||||
|
|
||||||
export default DecodeVeh;
|
export default DecodeVeh;
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ import DecodeVeh from "./decode-veh";
|
|||||||
import { DecodedVeh } from "./decode-veh.interface";
|
import { DecodedVeh } from "./decode-veh.interface";
|
||||||
import { DecodedEnv } from "./decode-env.interface";
|
import { DecodedEnv } from "./decode-env.interface";
|
||||||
import DecodeEnv from "./decode-env";
|
import DecodeEnv from "./decode-env";
|
||||||
|
import fs from "fs";
|
||||||
|
|
||||||
async function ImportJob(filepath: string): Promise<void> {
|
async function ImportJob(filepath: string): Promise<void> {
|
||||||
const parsedFilePath = path.parse(filepath);
|
const parsedFilePath = path.parse(filepath);
|
||||||
@@ -43,30 +44,51 @@ async function ImportJob(filepath: string): Promise<void> {
|
|||||||
const ad1: DecodedAd1 = await DecodeAD1(extensionlessFilePath);
|
const ad1: DecodedAd1 = await DecodeAD1(extensionlessFilePath);
|
||||||
const ad2: DecodedAD2 = await DecodeAD2(extensionlessFilePath);
|
const ad2: DecodedAD2 = await DecodeAD2(extensionlessFilePath);
|
||||||
const veh: DecodedVeh = await DecodeVeh(extensionlessFilePath);
|
const veh: DecodedVeh = await DecodeVeh(extensionlessFilePath);
|
||||||
const lin: DecodedLin[] = await DecodeLin(extensionlessFilePath);
|
const lin: DecodedLin = await DecodeLin(extensionlessFilePath);
|
||||||
const pfh: DecodedPfh = await DecodePfh(extensionlessFilePath);
|
const pfh: DecodedPfh = await DecodePfh(extensionlessFilePath);
|
||||||
const pfl: DecodedPfl = await DecodePfl(extensionlessFilePath);
|
const pfl: DecodedPfl = await DecodePfl(extensionlessFilePath);
|
||||||
const pft: DecodedPft = await DecodePft(extensionlessFilePath);
|
const pft: DecodedPft = await DecodePft(extensionlessFilePath);
|
||||||
const pfm: DecodedPfm = await DecodePfm(extensionlessFilePath);
|
const pfm: DecodedPfm = await DecodePfm(extensionlessFilePath);
|
||||||
const pfo: DecodedPfo = await DecodePfo(extensionlessFilePath); // TODO: This will be the `cieca_pfo` object
|
const pfo: DecodedPfo = await DecodePfo(extensionlessFilePath); // TODO: This will be the `cieca_pfo` object
|
||||||
const stl: DecodedStl[] = await DecodeStl(extensionlessFilePath); // TODO: This will be the `cieca_stl` object
|
const stl: DecodedStl = await DecodeStl(extensionlessFilePath); // TODO: This will be the `cieca_stl` object
|
||||||
const ttl: DecodedTtl = await DecodeTtl(extensionlessFilePath);
|
const ttl: DecodedTtl = await DecodeTtl(extensionlessFilePath);
|
||||||
const pfp: DecodedPfp = await DecodePfp(extensionlessFilePath);
|
const pfp: DecodedPfp = await DecodePfp(extensionlessFilePath);
|
||||||
|
|
||||||
log.debug("Job Object", {
|
const jobObject = {
|
||||||
...env,
|
...env,
|
||||||
...ad1,
|
...ad1,
|
||||||
...ad2,
|
...ad2,
|
||||||
...veh,
|
...veh,
|
||||||
joblines: { data: lin },
|
...lin,
|
||||||
...pfh,
|
...pfh,
|
||||||
cieca_pfl: pfl,
|
...pfl,
|
||||||
cieca_pft: pft,
|
...pft,
|
||||||
materials: pfm,
|
...pfm,
|
||||||
cieca_pfo: pfo,
|
...pfo,
|
||||||
...stl,
|
...stl,
|
||||||
...ttl,
|
...ttl,
|
||||||
parts_tax_rates: pfp,
|
...pfp,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Save jobObject to a timestamped JSON file
|
||||||
|
const timestamp = new Date()
|
||||||
|
.toISOString()
|
||||||
|
.replace(/:/g, "-")
|
||||||
|
.replace(/\..+/, "");
|
||||||
|
const fileName = `job_${timestamp}_${parsedFilePath.name}.json`;
|
||||||
|
const logsDir = path.join(process.cwd(), "logs");
|
||||||
|
|
||||||
|
// Create logs directory if it doesn't exist
|
||||||
|
if (!fs.existsSync(logsDir)) {
|
||||||
|
fs.mkdirSync(logsDir, { recursive: true });
|
||||||
|
}
|
||||||
|
|
||||||
|
const filePath = path.join(logsDir, fileName);
|
||||||
|
fs.writeFileSync(filePath, JSON.stringify(jobObject, null, 2), "utf8");
|
||||||
|
log.info(`Job data saved to: ${filePath}`);
|
||||||
|
|
||||||
|
log.debug("Job Object", {
|
||||||
|
jobObject,
|
||||||
});
|
});
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
log.error("Error encountered while decoding job. ", errorTypeCheck(error));
|
log.error("Error encountered while decoding job. ", errorTypeCheck(error));
|
||||||
|
|||||||
@@ -1,12 +1,13 @@
|
|||||||
import { electronApp, is, optimizer } from "@electron-toolkit/utils";
|
import { electronApp, is, optimizer } from "@electron-toolkit/utils";
|
||||||
import { app, BrowserWindow, shell, webContents } from "electron";
|
import { app, BrowserWindow, Menu, shell } from "electron";
|
||||||
import log from "electron-log/main";
|
import log from "electron-log/main";
|
||||||
import { join } from "path";
|
import path, { join } from "path";
|
||||||
import icon from "../../resources/icon.png?asset";
|
import icon from "../../resources/icon.png?asset";
|
||||||
import ErrorTypeCheck from "../util/errorTypeCheck";
|
import ErrorTypeCheck from "../util/errorTypeCheck";
|
||||||
import store from "./store/store";
|
import store from "./store/store";
|
||||||
|
|
||||||
log.initialize();
|
log.initialize();
|
||||||
|
const isMac = process.platform === "darwin";
|
||||||
function createWindow(): void {
|
function createWindow(): void {
|
||||||
// Create the browser window.
|
// Create the browser window.
|
||||||
const { width, height, x, y } = store.get("app.windowBounds") as {
|
const { width, height, x, y } = store.get("app.windowBounds") as {
|
||||||
@@ -22,7 +23,7 @@ function createWindow(): void {
|
|||||||
x,
|
x,
|
||||||
y,
|
y,
|
||||||
show: false,
|
show: false,
|
||||||
autoHideMenuBar: true,
|
//autoHideMenuBar: true,
|
||||||
...(process.platform === "linux" ? { icon } : {}),
|
...(process.platform === "linux" ? { icon } : {}),
|
||||||
webPreferences: {
|
webPreferences: {
|
||||||
preload: join(__dirname, "../preload/index.js"),
|
preload: join(__dirname, "../preload/index.js"),
|
||||||
@@ -31,6 +32,131 @@ function createWindow(): void {
|
|||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const template = [
|
||||||
|
// { role: 'appMenu' }
|
||||||
|
...(isMac
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
label: app.name,
|
||||||
|
submenu: [
|
||||||
|
{ role: "about" },
|
||||||
|
{ type: "separator" },
|
||||||
|
{ role: "services" },
|
||||||
|
{ type: "separator" },
|
||||||
|
{ role: "hide" },
|
||||||
|
{ role: "hideOthers" },
|
||||||
|
{ role: "unhide" },
|
||||||
|
{ type: "separator" },
|
||||||
|
{ role: "quit" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
// { role: 'fileMenu' }
|
||||||
|
{
|
||||||
|
label: "File",
|
||||||
|
submenu: [isMac ? { role: "close" } : { role: "quit" }],
|
||||||
|
},
|
||||||
|
// { role: 'editMenu' }
|
||||||
|
{
|
||||||
|
label: "Edit",
|
||||||
|
submenu: [
|
||||||
|
{ role: "undo" },
|
||||||
|
{ role: "redo" },
|
||||||
|
{ type: "separator" },
|
||||||
|
{ role: "cut" },
|
||||||
|
{ role: "copy" },
|
||||||
|
{ role: "paste" },
|
||||||
|
...(isMac
|
||||||
|
? [
|
||||||
|
{ role: "pasteAndMatchStyle" },
|
||||||
|
{ role: "delete" },
|
||||||
|
{ role: "selectAll" },
|
||||||
|
{ type: "separator" },
|
||||||
|
{
|
||||||
|
label: "Speech",
|
||||||
|
submenu: [{ role: "startSpeaking" }, { role: "stopSpeaking" }],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: [{ role: "delete" }, { type: "separator" }, { role: "selectAll" }]),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// { role: 'viewMenu' }
|
||||||
|
{
|
||||||
|
label: "View",
|
||||||
|
submenu: [
|
||||||
|
{ role: "reload" },
|
||||||
|
{ role: "forceReload" },
|
||||||
|
{ role: "toggleDevTools" },
|
||||||
|
{ type: "separator" },
|
||||||
|
{ role: "resetZoom" },
|
||||||
|
{ role: "zoomIn" },
|
||||||
|
{ role: "zoomOut" },
|
||||||
|
{ type: "separator" },
|
||||||
|
{ role: "togglefullscreen" },
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// { role: 'windowMenu' }
|
||||||
|
{
|
||||||
|
label: "Window",
|
||||||
|
submenu: [
|
||||||
|
{ role: "minimize" },
|
||||||
|
{ role: "zoom" },
|
||||||
|
...(isMac
|
||||||
|
? [
|
||||||
|
{ type: "separator" },
|
||||||
|
{ role: "front" },
|
||||||
|
{ type: "separator" },
|
||||||
|
{ role: "window" },
|
||||||
|
]
|
||||||
|
: [{ role: "close" }]),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
role: "help",
|
||||||
|
submenu: [
|
||||||
|
{
|
||||||
|
label: "Learn More",
|
||||||
|
click: async () => {
|
||||||
|
const { shell } = require("electron");
|
||||||
|
await shell.openExternal("https://electronjs.org");
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
...(import.meta.env.DEV
|
||||||
|
? [
|
||||||
|
{
|
||||||
|
label: "Development",
|
||||||
|
submenu: [
|
||||||
|
{
|
||||||
|
label: "Open Log Folder",
|
||||||
|
click: (): void => {
|
||||||
|
/* action for item 1 */
|
||||||
|
shell.openPath(log.transports.file.getFile().path);
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Clear Log",
|
||||||
|
click: (): void => {
|
||||||
|
log.transports.file.getFile().clear();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: "Open Config",
|
||||||
|
click: (): void => {
|
||||||
|
shell.openPath(path.dirname(store.path));
|
||||||
|
},
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
]
|
||||||
|
: []),
|
||||||
|
];
|
||||||
|
|
||||||
|
const menu: Electron.Menu = Menu.buildFromTemplate(template);
|
||||||
|
Menu.setApplicationMenu(menu);
|
||||||
|
|
||||||
// Store window properties for later
|
// Store window properties for later
|
||||||
const storeWindowState = (): void => {
|
const storeWindowState = (): void => {
|
||||||
const [width, height] = mainWindow.getSize();
|
const [width, height] = mainWindow.getSize();
|
||||||
|
|||||||
@@ -49,13 +49,20 @@ if (import.meta.env.DEV) {
|
|||||||
log.debug("[IPC Debug Functions] Adding Debug Handlers");
|
log.debug("[IPC Debug Functions] Adding Debug Handlers");
|
||||||
|
|
||||||
ipcMain.on(ipcTypes.toMain.debug.decodeEstimate, async (): Promise<void> => {
|
ipcMain.on(ipcTypes.toMain.debug.decodeEstimate, async (): Promise<void> => {
|
||||||
const relativeEmsFilepath = `_reference/ems/MPI_1/3698420.ENV`;
|
// const relativeEmsFilepath = `_reference/ems/MPI_1/3698420.ENV`;
|
||||||
// Get the app's root directory and create an absolute path
|
// // Get the app's root directory and create an absolute path
|
||||||
const rootDir = app.getAppPath();
|
// const rootDir = app.getAppPath();
|
||||||
const absoluteFilepath = path.join(rootDir, relativeEmsFilepath);
|
// const absoluteFilepath = path.join(rootDir, relativeEmsFilepath);
|
||||||
|
// console.log("*** ~ ipcMain.on ~ absoluteFilepath:", absoluteFilepath);
|
||||||
|
|
||||||
log.debug("[IPC Debug Function] Decode test Estimate", absoluteFilepath);
|
// log.debug("[IPC Debug Function] Decode test Estimate", absoluteFilepath);
|
||||||
await ImportJob(absoluteFilepath);
|
// await ImportJob(absoluteFilepath);
|
||||||
|
|
||||||
|
const job2 = `/Users/pfic/Downloads/12285264/2285264.ENV`;
|
||||||
|
|
||||||
|
const job3 = `/Users/pfic/Downloads/14033376/4033376.ENV`;
|
||||||
|
await ImportJob(job2);
|
||||||
|
await ImportJob(job3);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -17,6 +17,9 @@ const store = new Store({
|
|||||||
y: undefined,
|
y: undefined,
|
||||||
},
|
},
|
||||||
user: null,
|
user: null,
|
||||||
|
bodyshop: {
|
||||||
|
id: "6089913a-7522-49e7-8c96-786a488b738d", //TODO: Remove hard coded default.
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -7,16 +7,17 @@ import ipcTypes from "../../util/ipcTypes.json";
|
|||||||
import NavigationHeader from "./components/NavigationHeader/Navigationheader";
|
import NavigationHeader from "./components/NavigationHeader/Navigationheader";
|
||||||
import SignInForm from "./components/SignInForm/SignInForm";
|
import SignInForm from "./components/SignInForm/SignInForm";
|
||||||
import { auth } from "./util/firebase";
|
import { auth } from "./util/firebase";
|
||||||
import {} from "react-error-boundary";
|
|
||||||
import { ErrorBoundary } from "react-error-boundary";
|
import { ErrorBoundary } from "react-error-boundary";
|
||||||
import ErrorBoundaryFallback from "./components/ErrorBoundaryFallback/ErrorBoundaryFallback";
|
import ErrorBoundaryFallback from "./components/ErrorBoundaryFallback/ErrorBoundaryFallback";
|
||||||
import Settings from "./components/Settings/Settings";
|
|
||||||
import Home from "./components/Home/Home";
|
import Home from "./components/Home/Home";
|
||||||
|
import Settings from "./components/Settings/Settings";
|
||||||
|
import { Provider } from "react-redux";
|
||||||
|
import reduxStore from "./redux/redux-store";
|
||||||
|
|
||||||
const App: React.FC = () => {
|
const App: React.FC = () => {
|
||||||
const [user, setUser] = useState<User | null>(null);
|
const [user, setUser] = useState<User | null>(null);
|
||||||
|
|
||||||
auth.onAuthStateChanged((user) => {
|
auth.onAuthStateChanged((user: User | null) => {
|
||||||
setUser(user);
|
setUser(user);
|
||||||
//Send back to the main process so that it knows we are authenticated.
|
//Send back to the main process so that it knows we are authenticated.
|
||||||
if (user) {
|
if (user) {
|
||||||
@@ -24,27 +25,30 @@ const App: React.FC = () => {
|
|||||||
ipcTypes.toMain.authStateChanged,
|
ipcTypes.toMain.authStateChanged,
|
||||||
user.toJSON()
|
user.toJSON()
|
||||||
);
|
);
|
||||||
|
window.electron.ipcRenderer.send(ipcTypes.toMain.watcher.start);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<BrowserRouter>
|
<Provider store={reduxStore}>
|
||||||
<ErrorBoundary FallbackComponent={ErrorBoundaryFallback}>
|
<BrowserRouter>
|
||||||
<Layout>
|
<ErrorBoundary FallbackComponent={ErrorBoundaryFallback}>
|
||||||
{!user ? (
|
<Layout>
|
||||||
<SignInForm />
|
{!user ? (
|
||||||
) : (
|
<SignInForm />
|
||||||
<>
|
) : (
|
||||||
<NavigationHeader />
|
<>
|
||||||
<Routes>
|
<NavigationHeader />
|
||||||
<Route path="/" element={<Home />} />
|
<Routes>
|
||||||
<Route path="settings" element={<Settings />} />
|
<Route path="/" element={<Home />} />
|
||||||
</Routes>
|
<Route path="settings" element={<Settings />} />
|
||||||
</>
|
</Routes>
|
||||||
)}
|
</>
|
||||||
</Layout>
|
)}
|
||||||
</ErrorBoundary>
|
</Layout>
|
||||||
</BrowserRouter>
|
</ErrorBoundary>
|
||||||
|
</BrowserRouter>
|
||||||
|
</Provider>
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
37
src/renderer/src/redux/app.slice.ts
Normal file
37
src/renderer/src/redux/app.slice.ts
Normal file
@@ -0,0 +1,37 @@
|
|||||||
|
import { createSlice, PayloadAction } from "@reduxjs/toolkit";
|
||||||
|
import type { RootState } from "./redux-store";
|
||||||
|
|
||||||
|
// Define a type for the slice state
|
||||||
|
interface AppState {
|
||||||
|
value: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Define the initial state using that type
|
||||||
|
const initialState: AppState = {
|
||||||
|
value: 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
export const appSlice = createSlice({
|
||||||
|
name: "counter",
|
||||||
|
// `createSlice` will infer the state type from the `initialState` argument
|
||||||
|
initialState,
|
||||||
|
reducers: {
|
||||||
|
increment: (state) => {
|
||||||
|
state.value += 1;
|
||||||
|
},
|
||||||
|
decrement: (state) => {
|
||||||
|
state.value -= 1;
|
||||||
|
},
|
||||||
|
// Use the PayloadAction type to declare the contents of `action.payload`
|
||||||
|
incrementByAmount: (state, action: PayloadAction<number>) => {
|
||||||
|
state.value += action.payload;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
export const { increment, decrement, incrementByAmount } = appSlice.actions;
|
||||||
|
|
||||||
|
// Other code such as selectors can use the imported `RootState` type
|
||||||
|
export const selectCount = (state: RootState): number => state.app.value;
|
||||||
|
|
||||||
|
export default appSlice.reducer;
|
||||||
13
src/renderer/src/redux/redux-store.ts
Normal file
13
src/renderer/src/redux/redux-store.ts
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
import { configureStore } from "@reduxjs/toolkit";
|
||||||
|
import appReducer from "./app.slice";
|
||||||
|
|
||||||
|
const store = configureStore({
|
||||||
|
reducer: { app: appReducer },
|
||||||
|
});
|
||||||
|
|
||||||
|
// Infer the `RootState` and `AppDispatch` types from the store itself
|
||||||
|
export type RootState = ReturnType<typeof store.getState>;
|
||||||
|
// Inferred type: {posts: PostsState, comments: CommentsState, users: UsersState}
|
||||||
|
export type AppDispatch = typeof store.dispatch;
|
||||||
|
export type AppStore = typeof store;
|
||||||
|
export default store;
|
||||||
8
src/renderer/src/redux/reduxHooks.ts
Normal file
8
src/renderer/src/redux/reduxHooks.ts
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
import type { TypedUseSelectorHook } from "react-redux";
|
||||||
|
import { useDispatch, useSelector, useStore } from "react-redux";
|
||||||
|
import type { AppDispatch, AppStore, RootState } from "./redux-store";
|
||||||
|
|
||||||
|
// Use throughout your app instead of plain `useDispatch` and `useSelector`
|
||||||
|
export const useAppDispatch: () => AppDispatch = useDispatch;
|
||||||
|
export const useAppSelector: TypedUseSelectorHook<RootState> = useSelector;
|
||||||
|
export const useAppStore: () => AppStore = useStore;
|
||||||
@@ -22,7 +22,9 @@ function deepLowerCaseKeys<T = any>(obj: any): T {
|
|||||||
const lowercaseKey = key.toLowerCase();
|
const lowercaseKey = key.toLowerCase();
|
||||||
|
|
||||||
result[lowercaseKey] =
|
result[lowercaseKey] =
|
||||||
typeof value === "object" && value !== null
|
typeof value === "object" &&
|
||||||
|
value !== null &&
|
||||||
|
Object.keys(value).length > 0
|
||||||
? deepLowerCaseKeys(value)
|
? deepLowerCaseKeys(value)
|
||||||
: value;
|
: value;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user