import dotenv from "dotenv"; import { Request, Response } from "express"; import fs from "fs-extra"; import multer from "multer"; import path, { resolve } from "path"; import { logger } from "../server"; import GenerateThumbnail from "../util/generateThumbnail"; import generateUniqueFilename, { generateUniqueBillFilename } from "../util/generateUniqueFilename"; import { ConvertHeicFiles } from "../util/heicConverter"; import { PathToRoBillsFolder, PathToVendorBillsFile } from "../util/pathGenerators"; import { BillsListMedia } from "./billsListMedia"; dotenv.config({ path: resolve(process.cwd(), `.env.${process.env.NODE_ENV || "development"}`) }); export const BillsMediaUploadMulter = multer({ storage: multer.diskStorage({ destination: function (req, file, cb) { const jobid: string = (req.body.jobid || "").trim(); const DestinationFolder: string = PathToRoBillsFolder(jobid); fs.ensureDirSync(DestinationFolder); cb(jobid === "" || jobid === null ? new Error("Job ID not specified.") : null, DestinationFolder); }, filename: function (req, file, cb) { logger.info("Uploading file: ", { file: path.basename(file.originalname) }); const invoice_number: string = (req.body.invoice_number || "").trim(); cb( invoice_number === "" || invoice_number === null ? new Error("Invoice number not specified.") : null, generateUniqueBillFilename(file, invoice_number) ); } }) }); export async function BillsUploadMedia(req: Request, res: Response) { try { if (!req.files) { res.send({ status: false, message: "No file uploaded" }); } else { await ConvertHeicFiles(req.files as Express.Multer.File[]); const thumbnailGenerationQueue: Promise[] = []; //for each file.path, generate the thumbnail. (req.files as Express.Multer.File[]).forEach((file) => { thumbnailGenerationQueue.push(GenerateThumbnail(file.path)); }); await Promise.all(thumbnailGenerationQueue); //Check to see if it should be duplicated to the vendor. if (process.env.DUPLICATE_BILL_TO_VENDOR) { const copyQueue: Promise[] = []; //for each file.path, generate the thumbnail. (req.files as Express.Multer.File[]).forEach((file) => { const vendorid: string = (req.body.vendorid || "").trim(); const invoice_number: string = (req.body.invoice_number || "").trim(); copyQueue.push( (async () => { const target: string = path.join(PathToVendorBillsFile(vendorid), file.filename); await fs.ensureDir(path.dirname(target)); await fs.copyFile(file.path, target); })() ); //Copy Queue is not awaited - we don't care if it finishes before we serve up the thumbnails from the jobs directory. }); } BillsListMedia(req, res); } } catch (error) { logger.error("Error while uploading Bill Media", { files: req.files, error }); res.status(500).send(error); } }