From c92e450e46e208b603dc169aeefc599cb4e4b2ec Mon Sep 17 00:00:00 2001 From: Gowtham M Date: Tue, 6 Jan 2026 18:45:07 +0530 Subject: [PATCH] EMAIL template image issue : GWM --- app/assets/FCSCLogo.png | Bin 0 -> 2452 bytes app/controllers/calculation.controller.js | 2 - app/controllers/establishment.controller.js | 7 +- ...l_missing_quarterly_submissions_service.js | 88 ++++++++++++------ server.js | 5 + 5 files changed, 71 insertions(+), 31 deletions(-) create mode 100644 app/assets/FCSCLogo.png diff --git a/app/assets/FCSCLogo.png b/app/assets/FCSCLogo.png new file mode 100644 index 0000000000000000000000000000000000000000..0148d29a75d03b641930c43fc63553a4223d7cdd GIT binary patch literal 2452 zcmV;F32XL=P)_6ddta?4@lCoug4mLDK6=N`bGCy?d|ET59waIiV#W(|Ve z0&M#bU~?MHV)KLX%zF8mRa-@hq9}{<%4>f>n`E=Py1Kf$y1Ur&4uETHFLv;VJH;>M z`V`xTudyDE^YkiDGjt2`z06a{(=<&LHCFyMS1Gw=|b|;JSFn(O{EO!2IvmtcP#ZpxIN-LjpY7j0R95^3x_By z8ge~Dp%f}RLeaP$*2hrzjxewAOzLJm>JgS1UIdf73!DnST@;>*7&Xv)T}2IaKTa7Q zBdlk2Ax{UjZ_+qd;^(skW+i@{#1NgHxE&Desq+_spNl z{dtS}C~KGADna3q&RpGb1HI}bLeZ{;-m1^w_scS02wWy2`IdY%HefY(hs+F*C=oA=zb%t z4l@1{O(Q*xqkPI(w0j8ol;L+fRk=JOS0|H>0^>EG*EO{6XhB|Z`3VXmdWp@*!FKxT zql$pV`Y6fVm4_fhzrfifXyJ6x9Jzb0{#lJo>w1Sa2n~60p7v45yoc`f!wx~^{^ttvDABkW@8<|f@h~qwD-{_pb!mn2&?+2-GRcJfons*xY-IKca(E;w8LBy~<{cXWfn!)DW zfW=!_(mZ!`O_9i`CQrX|rsxJwYU*4x?cEBuT0{K#vor+ z;{@$NrBZ=omsfrE(D+IU>vYY_cHUpLgj6@2wmxqtVyyr0RnCp^`o(erS+ z2zh!Zd7-8r{eBV4z3R;0v)t_rV*LMq1B*w*CNV^L5p`F=Fk*~Cc{KVUc?V7oPB9V6 z-xH=V8QU!Wy1*{hz{&Tx9Zh@dzRCj)WcHoHTsOH)v!PxiP)uOkw<>Nk`qvuCo5D(q%6#qcP`$&0L2H9};NIcEptV6~!B9UP@miqwPDfH#uAG8UTdLt>TyM`F{Z9r*bS8wF%={ugm z$)K?VAHvqucXbC>zE>l6-_cde^eX&zPkE$Tf74!cabDEVjmWq zNl_e{VdFLAd?I!Of6<4TROX)W z*LI{LAMcNy>}QUb$}tk!Lzn@kuz1Blc=u6`p`4%`%sPV&uy!8euU8+iMaW=QK1F$y z(&Bl(FoMPI-?{f19C{(o35xLai-!8BaDUqA!aXywGhf3F+Xj@6*7-WWsIi4JbA+;&+=csb(Ncrpbg^YfVV!s`&)xv2aE{tco~fWyxeq8tRt)P%4Fkuh z2YDxscW|^+{A<{u+F7M;Ex!l*o)P3e!|E8rPMinHdn^2ctM3)cVf3k^39wMLu0w{x zbGbqM?dsbZwg*#pPr0a^F|0$_@tj)^VDWv9*3^~fz0T7|Ldy<&QsJpy=RorG7h-(o zG{O?n7f2UM@ZUr)^Ctawf3YhyIE^mUL06XDIJ)$~VR#zWM$N zTZnaIgE7CH9j3?iQWeVy})%}BF= z_09oAu-|s_+H>!y$m51`p^`U7VJK8$g85@-G0gjLYu98DROVBd;S3sR1Ll8{AEZ3X zvJKTv?P31hx`>=l}pzDB3)I((Po-uwm6W1T9;GG(FhJ(e;9Muo{f6C#IMmVSPyx_bx*Di{rFq zJ`uy*f1SLZhti`WYqdNaZRBKC?>K`^S6)6|gDaagw8MMaObudNv4cn4DSiN-G1~J8 S6so=e0000 { const result3 = await autoSubmissionService.verifyCompleteness(year, quarter); - // Or verify entire year - // await autoSubmissionService.verifyCompleteness(year); res.json({ success: true, autoFillMissingSubmissions: result , verifyCompleteness: result3 }); diff --git a/app/controllers/establishment.controller.js b/app/controllers/establishment.controller.js index b8b91e7..b8a92a4 100644 --- a/app/controllers/establishment.controller.js +++ b/app/controllers/establishment.controller.js @@ -1089,10 +1089,11 @@ exports.requestOTPForLogin = async (req, res) => { const hashedOtp = await bcrypt.hash(otp, 10); // Store OTP in the correct model with WHERE clause + const otp_expiry = new Date(Date.now() + 10 * 60 * 1000); await userModel.update( { login_otp: hashedOtp, - login_otp_expires_at: new Date(Date.now() + 10 * 60 * 1000), + login_otp_expires_at: otp_expiry, }, { where: { email: registered_email } @@ -1101,8 +1102,10 @@ exports.requestOTPForLogin = async (req, res) => { const placeHolderData = { username: loggingUser.name, verfication_code: otp, + otp_expiry: otp_expiry, support_email: process.env.SUPPORT_EMAIL, - support_phone: process.env.SUPPORT_PHONE + support_phone: process.env.SUPPORT_PHONE, + logo_url: `${process.env.APP_BASE_URL}/assets/FCSCLogo.png` }; await sendEmailService(registered_email, "sign_in_verification_code", placeHolderData); diff --git a/app/services/auto_fill_missing_quarterly_submissions_service.js b/app/services/auto_fill_missing_quarterly_submissions_service.js index 1d4d0fe..1d682d8 100644 --- a/app/services/auto_fill_missing_quarterly_submissions_service.js +++ b/app/services/auto_fill_missing_quarterly_submissions_service.js @@ -269,27 +269,27 @@ class AutoFillSubmissionService { product.product_id, product.unit_id, product.annual_installed_capacity, - // Previous = Current from source (shift forward) + // Previous = Current from source + product.current_quantity_period_one || 0, + product.current_quantity_period_two || 0, + product.current_quantity_period_three || 0, + product.current_cost_period_one || 0, + product.current_cost_period_two || 0, + product.current_cost_period_three || 0, + // Current = Current from source + product.current_quantity_period_one || 0, + product.current_quantity_period_two || 0, + product.current_quantity_period_three || 0, + product.current_cost_period_one || 0, + product.current_cost_period_two || 0, + product.current_cost_period_three || 0, + // Forecast = Current from source product.current_quantity_period_one || 0, product.current_quantity_period_two || 0, product.current_quantity_period_three || 0, product.current_cost_period_one || 0, product.current_cost_period_two || 0, product.current_cost_period_three || 0, - // Current = Forecast from source (use forecast values) - product.forecast_quantity_period_one || 0, - product.forecast_quantity_period_two || 0, - product.forecast_quantity_period_three || 0, - product.forecast_cost_period_one || 0, - product.forecast_cost_period_two || 0, - product.forecast_cost_period_three || 0, - // Forecast = Same as current (or could apply growth rate) - product.forecast_quantity_period_one || 0, - product.forecast_quantity_period_two || 0, - product.forecast_quantity_period_three || 0, - product.forecast_cost_period_one || 0, - product.forecast_cost_period_two || 0, - product.forecast_cost_period_three || 0, // Totals this.calculateTotal( product.current_quantity_period_one, @@ -302,24 +302,24 @@ class AutoFillSubmissionService { product.current_cost_period_three ), this.calculateTotal( - product.forecast_quantity_period_one, - product.forecast_quantity_period_two, - product.forecast_quantity_period_three + product.current_quantity_period_one, + product.current_quantity_period_two, + product.current_quantity_period_three ), this.calculateTotal( - product.forecast_cost_period_one, - product.forecast_cost_period_two, - product.forecast_cost_period_three + product.current_cost_period_one, + product.current_cost_period_two, + product.current_cost_period_three ), this.calculateTotal( - product.forecast_quantity_period_one, - product.forecast_quantity_period_two, - product.forecast_quantity_period_three + product.current_quantity_period_one, + product.current_quantity_period_two, + product.current_quantity_period_three ), this.calculateTotal( - product.forecast_cost_period_one, - product.forecast_cost_period_two, - product.forecast_cost_period_three + product.current_cost_period_one, + product.current_cost_period_two, + product.current_cost_period_three ), // Other fields product.variation_reason_master_id, @@ -469,6 +469,40 @@ class AutoFillSubmissionService { } } + // HELPER : calculation log + async logRecord(calculation_type, reference_year, reference_month = null, status = 'Started', logId = null, records_processed = 0, error_message = null, useConnection = null) { + + const connection = useConnection || await this.pool.getConnection(); + try { + if (!logId) { + const [result] = await connection.query( + `INSERT INTO calculation_log (calculation_type, reference_year, reference_month, status) + VALUES (?, ?, ?, ?)`, + [calculation_type, reference_year, reference_month, status] + ); + return result.insertId; + } + + if(records_processed == 0) + { + status = 'Failed'; + } + + await connection.query( + `UPDATE calculation_log + SET status=?, records_processed=?, error_message=?, completed_at=NOW() + WHERE id=?`, + [status, records_processed, error_message?.substring(0,65535) || null, logId] + ); + + } catch (err) { + console.error('[LOG ERROR]', err.message); + logger.error(` Log record error: ${err.message} `); + } finally { + if (!useConnection) connection.release(); + } + } + // Close pool async close() { await this.pool.end(); diff --git a/server.js b/server.js index 77e68ef..4e016c7 100644 --- a/server.js +++ b/server.js @@ -56,6 +56,11 @@ app.set("trust proxy", 1); app.use(express.json()); app.use(cookieParser()); +app.use( + "/assets", + express.static(path.join(__dirname, "app/assets")) +); + /** * ========================= * HELMET + SECURITY HEADERS