feature/IO-3205-Paint-Scale-Integrations: Pre Change Checkpoint
This commit is contained in:
@@ -4,4 +4,6 @@ VITE_FIREBASE_CONFIG_TEST={ "apiKey":"AIzaSyBw7_GTy7GtQyfkIRPVrWHEGKfcqeyXw0c"
|
||||
VITE_GRAPHQL_ENDPOINT_TEST=https://db.test.bodyshop.app/v1/graphql
|
||||
VITE_COMPANY=IMEX
|
||||
VITE_FE_URL=https://imex.online
|
||||
VITE_FE_URL_TEST=https://test.imex.online
|
||||
VITE_FE_URL_TEST=https://test.imex.online
|
||||
VITE_API_URL="http://localhost:4000"
|
||||
VITE_API_TEST_URL="http://api.test.imex.online"
|
||||
@@ -4,4 +4,6 @@ VITE_FIREBASE_CONFIG_TEST={ "apiKey":"AIzaSyBw7_GTy7GtQyfkIRPVrWHEGKfcqeyXw0c"
|
||||
VITE_GRAPHQL_ENDPOINT_TEST=https://db.test.bodyshop.app/v1/graphql
|
||||
VITE_COMPANY=IMEX
|
||||
VITE_FE_URL=https://imex.online
|
||||
VITE_FE_URL_TEST=https://test.imex.online
|
||||
VITE_FE_URL_TEST=https://test.imex.online
|
||||
VITE_API_URL="http://localhost:4000"
|
||||
VITE_API_TEST_URL="http://api.test.imex.online"
|
||||
@@ -4,4 +4,6 @@ VITE_FIREBASE_CONFIG_TEST={ "apiKey": "AIzaSyAuLQR9SV5LsVxjU8wh9hvFLdhcAHU6cxE"
|
||||
VITE_GRAPHQL_ENDPOINT_TEST=https://db.test.romeonline.io/v1/graphql
|
||||
VITE_COMPANY=ROME
|
||||
VITE_FE_URL=https://romeonline.io
|
||||
VITE_FE_URL_TEST=https://test.romeonline.io
|
||||
VITE_FE_URL_TEST=https://test.romeonline.io
|
||||
VITE_API_URL="http://localhost:4000"
|
||||
VITE_API_TEST_URL="http://api.test.romeonline.io"
|
||||
@@ -119,7 +119,6 @@ const initializeCronTasks = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
// Log all IPC messages and their payloads
|
||||
const logIpcMessages = (): void => {
|
||||
Object.keys(ipcTypes.toMain).forEach((key) => {
|
||||
@@ -180,6 +179,7 @@ const inputTypeHandlers: Record<
|
||||
|
||||
// Upload file to API
|
||||
const formData = new FormData();
|
||||
|
||||
formData.append(
|
||||
"file",
|
||||
new Blob([await fs.readFile(filePath)]),
|
||||
@@ -190,17 +190,20 @@ const inputTypeHandlers: Record<
|
||||
(store.get("app.bodyshop") as BodyShop)?.shopname || "",
|
||||
);
|
||||
|
||||
// TODO Clear up how to fetch API URL
|
||||
const response = await axios.post(
|
||||
"https://your-api-base-url/mixdata/upload",
|
||||
formData,
|
||||
{
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
const baseURL = store.get("app.isTest")
|
||||
? import.meta.env.VITE_API_TEST_URL
|
||||
: import.meta.env.VITE_API_URL;
|
||||
|
||||
const finalUrl = `${baseURL}/mixdata/upload`;
|
||||
|
||||
log.debug(`Uploading file to ${finalUrl}`);
|
||||
|
||||
const response = await axios.post(finalUrl, formData, {
|
||||
headers: {
|
||||
Authorization: `Bearer ${token}`,
|
||||
"Content-Type": "multipart/form-data",
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
if (response.status === 200) {
|
||||
log.info(`Successful upload of ${filePath}`);
|
||||
@@ -234,69 +237,69 @@ const outputTypeHandlers: Record<
|
||||
|
||||
// GraphQL query for jobs
|
||||
const query = `
|
||||
query PpgData($today: date!, $todayplus5: date!, $shopid: uuid!) {
|
||||
bodyshops_by_pk(id: $shopid) {
|
||||
imexshopid
|
||||
shopname
|
||||
query PpgData($today: date!, $todayplus5: date!, $shopid: uuid!) {
|
||||
bodyshops_by_pk(id: $shopid) {
|
||||
imexshopid
|
||||
shopname
|
||||
}
|
||||
jobs(where: {
|
||||
_and: [
|
||||
{ shop_id: { _eq: $shopid } },
|
||||
{ _or: [
|
||||
{ status: { _eq: "Active" } },
|
||||
{ scheduled_date: { _gte: $today, _lte: $todayplus5 } }
|
||||
] }
|
||||
]
|
||||
}) {
|
||||
ro_number
|
||||
ownr_ln
|
||||
ownr_fn
|
||||
plate_no
|
||||
v_vin
|
||||
v_model_yr
|
||||
v_make_desc
|
||||
v_model_desc
|
||||
vehicle {
|
||||
v_paint_codes {
|
||||
paint_cd1
|
||||
}
|
||||
}
|
||||
jobs(where: {
|
||||
_and: [
|
||||
{ shop_id: { _eq: $shopid } },
|
||||
{ _or: [
|
||||
{ status: { _eq: "Active" } },
|
||||
{ scheduled_date: { _gte: $today, _lte: $todayplus5 } }
|
||||
] }
|
||||
]
|
||||
}) {
|
||||
ro_number
|
||||
ownr_ln
|
||||
ownr_fn
|
||||
plate_no
|
||||
v_vin
|
||||
v_model_yr
|
||||
v_make_desc
|
||||
v_model_desc
|
||||
vehicle {
|
||||
v_paint_codes {
|
||||
paint_cd1
|
||||
larhrs_aggregate: estimate_lines_aggregate(where: { line_type: { _eq: "Paint" } }) {
|
||||
aggregate {
|
||||
sum {
|
||||
mod_lb_hrs
|
||||
}
|
||||
}
|
||||
larhrs_aggregate: estimate_lines_aggregate(where: { line_type: { _eq: "Paint" } }) {
|
||||
aggregate {
|
||||
sum {
|
||||
mod_lb_hrs
|
||||
}
|
||||
}
|
||||
}
|
||||
ins_co_nm
|
||||
est_ct_ln
|
||||
est_ct_fn
|
||||
job_totals {
|
||||
rates {
|
||||
mapa {
|
||||
total {
|
||||
amount
|
||||
}
|
||||
}
|
||||
}
|
||||
totals {
|
||||
subtotal {
|
||||
}
|
||||
ins_co_nm
|
||||
est_ct_ln
|
||||
est_ct_fn
|
||||
job_totals {
|
||||
rates {
|
||||
mapa {
|
||||
total {
|
||||
amount
|
||||
}
|
||||
}
|
||||
}
|
||||
rate_mapa
|
||||
labhrs_aggregate: estimate_lines_aggregate(where: { line_type: { _eq: "Body" } }) {
|
||||
aggregate {
|
||||
sum {
|
||||
mod_lb_hrs
|
||||
}
|
||||
totals {
|
||||
subtotal {
|
||||
amount
|
||||
}
|
||||
}
|
||||
rate_lab
|
||||
}
|
||||
rate_mapa
|
||||
labhrs_aggregate: estimate_lines_aggregate(where: { line_type: { _eq: "Body" } }) {
|
||||
aggregate {
|
||||
sum {
|
||||
mod_lb_hrs
|
||||
}
|
||||
}
|
||||
}
|
||||
rate_lab
|
||||
}
|
||||
`;
|
||||
}
|
||||
`;
|
||||
|
||||
const variables = {
|
||||
today: new Date().toISOString().split("T")[0],
|
||||
@@ -311,137 +314,80 @@ const outputTypeHandlers: Record<
|
||||
variables,
|
||||
)) as GraphQLResponse;
|
||||
|
||||
// Generate XML
|
||||
const doc = create({ version: "1.0" })
|
||||
.ele("PPG")
|
||||
.ele("Header")
|
||||
.ele("Protocol")
|
||||
.ele("Message")
|
||||
.txt("PaintShopInterface")
|
||||
.up()
|
||||
.ele("Name")
|
||||
.txt("PPG")
|
||||
.up()
|
||||
.ele("Version")
|
||||
.txt("1.5.0")
|
||||
.up()
|
||||
.up()
|
||||
.ele("Transaction")
|
||||
.ele("TransactionID")
|
||||
.txt("")
|
||||
.up()
|
||||
.ele("TransactionDate")
|
||||
.txt(new Date().toISOString().replace("T", " ").substring(0, 19))
|
||||
.up()
|
||||
.up()
|
||||
.ele("Product")
|
||||
.ele("Name")
|
||||
.txt("ImEX Online")
|
||||
.up()
|
||||
.ele("Version")
|
||||
.txt("")
|
||||
.up()
|
||||
.up()
|
||||
.up()
|
||||
.ele("DataInterface")
|
||||
.ele("ROData")
|
||||
.ele("ShopInfo")
|
||||
.ele("ShopID")
|
||||
.txt(response.bodyshops_by_pk?.imexshopid || "")
|
||||
.up()
|
||||
.ele("ShopName")
|
||||
.txt(response.bodyshops_by_pk?.shopname || "")
|
||||
.up()
|
||||
.up()
|
||||
.ele("RepairOrders")
|
||||
.ele("ROCount")
|
||||
.txt((response.jobs?.length || 0).toString())
|
||||
.up()
|
||||
.up()
|
||||
.up()
|
||||
.up();
|
||||
// Build JSON structure
|
||||
const jsonData = {
|
||||
PPG: {
|
||||
Header: {
|
||||
Protocol: {
|
||||
Message: "PaintShopInterface",
|
||||
Name: "PPG",
|
||||
Version: "1.5.0",
|
||||
},
|
||||
Transaction: {
|
||||
TransactionID: "",
|
||||
TransactionDate: new Date()
|
||||
.toISOString()
|
||||
.replace("T", " ")
|
||||
.substring(0, 19),
|
||||
},
|
||||
Product: {
|
||||
Name: "ImEX Online",
|
||||
Version: "",
|
||||
},
|
||||
},
|
||||
DataInterface: {
|
||||
ROData: {
|
||||
ShopInfo: {
|
||||
ShopID: response.bodyshops_by_pk?.imexshopid || "",
|
||||
ShopName: response.bodyshops_by_pk?.shopname || "",
|
||||
},
|
||||
RepairOrders: {
|
||||
ROCount: (response.jobs?.length || 0).toString(),
|
||||
RO:
|
||||
response.jobs?.map((job) => ({
|
||||
RONumber: job.ro_number || "",
|
||||
ROStatus: "Open",
|
||||
Customer: `${job.ownr_ln || ""}, ${job.ownr_fn || ""}`,
|
||||
ROPainterNotes: "",
|
||||
LicensePlateNum: job.plate_no || "",
|
||||
VIN: job.v_vin || "",
|
||||
ModelYear: job.v_model_yr || "",
|
||||
MakeDesc: job.v_make_desc || "",
|
||||
ModelName: job.v_model_desc || "",
|
||||
OEMColorCode: job.vehicle?.v_paint_codes?.paint_cd1 || "",
|
||||
RefinishLaborHours:
|
||||
job.larhrs_aggregate?.aggregate?.sum?.mod_lb_hrs || 0,
|
||||
InsuranceCompanyName: job.ins_co_nm || "",
|
||||
EstimatorName: `${job.est_ct_ln || ""}, ${job.est_ct_fn || ""}`,
|
||||
PaintMaterialsRevenue: (
|
||||
(job.job_totals?.rates?.mapa?.total?.amount || 0) / 100
|
||||
).toFixed(2),
|
||||
PaintMaterialsRate: job.rate_mapa || 0,
|
||||
BodyHours:
|
||||
job.labhrs_aggregate?.aggregate?.sum?.mod_lb_hrs || 0,
|
||||
BodyLaborRate: job.rate_lab || 0,
|
||||
TotalCostOfRepairs: (
|
||||
(job.job_totals?.totals?.subtotal?.amount || 0) / 100
|
||||
).toFixed(2),
|
||||
})) || [],
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
const repairOrders = (doc.root() as any).findOne("RepairOrders");
|
||||
(response as GraphQLResponse).jobs?.forEach((job: any) => {
|
||||
repairOrders
|
||||
.ele("RO")
|
||||
.ele("RONumber")
|
||||
.txt(job.ro_number || "")
|
||||
.up()
|
||||
.ele("ROStatus")
|
||||
.txt("Open")
|
||||
.up()
|
||||
.ele("Customer")
|
||||
.txt(`${job.ownr_ln || ""}, ${job.ownr_fn || ""}`)
|
||||
.up()
|
||||
.ele("ROPainterNotes")
|
||||
.txt("")
|
||||
.up()
|
||||
.ele("LicensePlateNum")
|
||||
.txt(job.plate_no || "")
|
||||
.up()
|
||||
.ele("VIN")
|
||||
.txt(job.v_vin || "")
|
||||
.up()
|
||||
.ele("ModelYear")
|
||||
.txt(job.v_model_yr || "")
|
||||
.up()
|
||||
.ele("MakeDesc")
|
||||
.txt(job.v_make_desc || "")
|
||||
.up()
|
||||
.ele("ModelName")
|
||||
.txt(job.v_model_desc || "")
|
||||
.up()
|
||||
.ele("OEMColorCode")
|
||||
.txt(job.vehicle?.v_paint_codes?.paint_cd1 || "")
|
||||
.up()
|
||||
.ele("RefinishLaborHours")
|
||||
.txt(job.larhrs_aggregate?.aggregate?.sum?.mod_lb_hrs || 0)
|
||||
.up()
|
||||
.ele("InsuranceCompanyName")
|
||||
.txt(job.ins_co_nm || "")
|
||||
.up()
|
||||
.ele("EstimatorName")
|
||||
.txt(`${job.est_ct_ln || ""}, ${job.est_ct_fn || ""}`)
|
||||
.up()
|
||||
.ele("PaintMaterialsRevenue")
|
||||
.txt(
|
||||
((job.job_totals?.rates?.mapa?.total?.amount || 0) / 100).toFixed(
|
||||
2,
|
||||
),
|
||||
)
|
||||
.up()
|
||||
.ele("PaintMaterialsRate")
|
||||
.txt(job.rate_mapa || 0)
|
||||
.up()
|
||||
.ele("BodyHours")
|
||||
.txt(job.labhrs_aggregate?.aggregate?.sum?.mod_lb_hrs || 0)
|
||||
.up()
|
||||
.ele("BodyLaborRate")
|
||||
.txt(job.rate_lab || 0)
|
||||
.up()
|
||||
.ele("TotalCostOfRepairs")
|
||||
.txt(
|
||||
((job.job_totals?.totals?.subtotal?.amount || 0) / 100).toFixed(2),
|
||||
)
|
||||
.up();
|
||||
});
|
||||
// Convert JSON to XML
|
||||
const doc = create({ version: "1.0" }, jsonData);
|
||||
const xmlString = doc.end({ prettyPrint: true });
|
||||
|
||||
// Save XML to file
|
||||
const xmlString = doc.end({ prettyPrint: true });
|
||||
const timestamp = new Date()
|
||||
.toISOString()
|
||||
.replace(/[-:]/g, "")
|
||||
.replace("T", "")
|
||||
.substring(0, 14);
|
||||
const outputPath = path.join(config.path!, `PPGPaint_${timestamp}.xml`);
|
||||
const outputPath = path.join(config.path!, `PPGPaint.xml`);
|
||||
await fs.writeFile(outputPath, xmlString);
|
||||
log.info(`Saved PPG output XML to ${outputPath}`);
|
||||
} catch (error) {
|
||||
log.error(`Error generating PPG output for config ${config.id}:`, error);
|
||||
}
|
||||
},
|
||||
// Add other output type handlers as needed
|
||||
}, // Add other output type handlers as needed
|
||||
};
|
||||
|
||||
// Default handler for unsupported types
|
||||
@@ -469,7 +415,7 @@ const handlePaintScaleInputCron = async (configs: PaintScaleConfig[]) => {
|
||||
await handler(config);
|
||||
});
|
||||
log.info(
|
||||
`Started input cron task for config ${config.id} (type: ${config.type}) with interval ${config.pollingInterval}s`,
|
||||
`Started input cron task for config ${config.id} (type: ${config.type}) with interval ${config.pollingInterval}m`,
|
||||
);
|
||||
});
|
||||
};
|
||||
@@ -492,7 +438,7 @@ const handlePaintScaleOutputCron = async (configs: PaintScaleConfig[]) => {
|
||||
await handler(config);
|
||||
});
|
||||
log.info(
|
||||
`Started output cron task for config ${config.id} (type: ${config.type}) with interval ${config.pollingInterval}s`,
|
||||
`Started output cron task for config ${config.id} (type: ${config.type}) with interval ${config.pollingInterval}m`,
|
||||
);
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user