144 lines
4.5 KiB
JavaScript
144 lines
4.5 KiB
JavaScript
// Notes: At the moment we take in RO Number, and ShopID. This is not very good considering the RO number can often be null, need
|
|
// to ask if it is possible that we just send the Job ID itself, this way we don't need to really care about the bodyshop, and we
|
|
// don't risk getting a null
|
|
|
|
const axios = require("axios");
|
|
const { S3Client, PutObjectCommand } = require("@aws-sdk/client-s3");
|
|
const { getSignedUrl } = require("@aws-sdk/s3-request-presigner");
|
|
const { GET_JOB_BY_RO_NUMBER_AND_SHOP_ID, INSERT_NEW_DOCUMENT } = require("../../graphql-client/queries");
|
|
const { InstanceRegion } = require("../../utils/instanceMgr");
|
|
const moment = require("moment/moment");
|
|
const client = require("../../graphql-client/graphql-client").client;
|
|
|
|
const S3_BUCKET = process.env?.IMGPROXY_DESTINATION_BUCKET;
|
|
|
|
/**
|
|
* @description VSSTA integration route
|
|
* @type {string[]}
|
|
*/
|
|
const requiredParams = [
|
|
"shop_id",
|
|
"ro_nbr",
|
|
"pdf_download_link",
|
|
"company_api_key",
|
|
"scan_type",
|
|
"scan_time",
|
|
"technician",
|
|
"year",
|
|
"make",
|
|
"model"
|
|
];
|
|
|
|
const vsstaIntegrationRoute = async (req, res) => {
|
|
const { logger } = req;
|
|
|
|
if (!S3_BUCKET) {
|
|
logger.log("vssta-integration-missing-bucket", "error", "api", "vssta");
|
|
return res.status(500).json({ error: "Improper configuration" });
|
|
}
|
|
|
|
try {
|
|
const missingParams = requiredParams.filter((param) => !req.body[param]);
|
|
|
|
if (missingParams.length > 0) {
|
|
logger.log(`vssta-integration-missing-param`, "error", "api", "vssta", {
|
|
params: missingParams
|
|
});
|
|
|
|
return res.status(400).json({
|
|
error: "Missing required parameters",
|
|
missingParams
|
|
});
|
|
}
|
|
|
|
// technician, year, make, model, is also available.
|
|
const { shop_id, ro_nbr, pdf_download_link, scan_type, scan_time, company_api_key } = req.body;
|
|
|
|
// 1. Get the job record by ro_number and shop_id
|
|
const jobResult = await client.request(GET_JOB_BY_RO_NUMBER_AND_SHOP_ID, {
|
|
roNumber: ro_nbr,
|
|
shopId: shop_id
|
|
});
|
|
|
|
if (!jobResult.jobs || jobResult.jobs.length === 0) {
|
|
logger.log(`vssta-integration-missing-ro`, "error", "api", "vssta");
|
|
|
|
return res.status(404).json({ error: "Job not found" });
|
|
}
|
|
|
|
const job = jobResult.jobs[0];
|
|
|
|
// 2. Download the base64-encoded PDF string from the provided link
|
|
const pdfResponse = await axios.get(pdf_download_link, {
|
|
responseType: "text", // Expect base64 string
|
|
headers: {
|
|
"auth-token": company_api_key
|
|
}
|
|
});
|
|
|
|
// 3. Decode the base64 string to a PDF buffer
|
|
const base64String = pdfResponse.data.replace(/^data:application\/pdf;base64,/, "");
|
|
const pdfBuffer = Buffer.from(base64String, "base64");
|
|
|
|
// 4. Generate key for S3
|
|
const timestamp = moment(scan_time).tz(job.bodyshop.timezone).format("YYYYMMDD-HHmmss");
|
|
const fileName = `${timestamp}_VSSTA_${scan_type}`;
|
|
const s3Key = `${job.shopid}/${job.id}/${fileName.replace(/[^A-Z0-9]+/gi, "_")}.pdf`;
|
|
|
|
// 5. Generate presigned URL for S3 upload
|
|
const s3Client = new S3Client({ region: InstanceRegion() });
|
|
|
|
const putCommand = new PutObjectCommand({
|
|
Bucket: S3_BUCKET,
|
|
Key: s3Key,
|
|
ContentType: "application/pdf",
|
|
StorageClass: "INTELLIGENT_TIERING"
|
|
});
|
|
|
|
const presignedUrl = await getSignedUrl(s3Client, putCommand, { expiresIn: 360 });
|
|
|
|
// 6. Upload the decoded PDF to S3
|
|
await axios.put(presignedUrl, pdfBuffer, {
|
|
headers: { "Content-Type": "application/pdf" }
|
|
});
|
|
|
|
// 7. Create document record in database
|
|
const documentMeta = {
|
|
jobid: job.id,
|
|
uploaded_by: "VSSTA Integration",
|
|
name: fileName,
|
|
key: s3Key,
|
|
type: "application/pdf",
|
|
extension: "pdf",
|
|
bodyshopid: job.shopid,
|
|
size: pdfBuffer.length,
|
|
takenat: scan_time
|
|
};
|
|
|
|
const documentInsert = await client.request(INSERT_NEW_DOCUMENT, {
|
|
docInput: [documentMeta]
|
|
});
|
|
|
|
if (!documentInsert.insert_documents?.returning?.length) {
|
|
logger.log(`vssta-integration-failed-to-create-document-record`, "error", "api", "vssta", {
|
|
params: missingParams
|
|
});
|
|
return res.status(500).json({ error: "Failed to create document record" });
|
|
}
|
|
|
|
return res.status(200).json({
|
|
message: "VSSTA integration successful",
|
|
documentId: documentInsert.insert_documents.returning[0].id
|
|
});
|
|
} catch (error) {
|
|
logger.log(`vssta-integration-general`, "error", "api", "vssta", {
|
|
error: error?.message,
|
|
stack: error?.stack
|
|
});
|
|
|
|
return res.status(500).json({ error: error.message });
|
|
}
|
|
};
|
|
|
|
module.exports = vsstaIntegrationRoute;
|