feat: improve template variable handling and add Profit Planet signature stamp functionality
This commit is contained in:
parent
46b36d7edd
commit
25c67783d4
@ -1619,17 +1619,35 @@ exports.previewLatestForMe = async (req, res) => {
|
|||||||
const [rows] = await db.execute('SELECT * FROM company_profiles WHERE user_id = ? LIMIT 1', [targetUserId]);
|
const [rows] = await db.execute('SELECT * FROM company_profiles WHERE user_id = ? LIMIT 1', [targetUserId]);
|
||||||
const c = rows && rows[0] ? rows[0] : null;
|
const c = rows && rows[0] ? rows[0] : null;
|
||||||
if (c) {
|
if (c) {
|
||||||
vars.companyName = c.company_name || '';
|
setIfEmpty('companyName', c.company_name);
|
||||||
vars.registrationNumber = c.registration_number || '';
|
setIfEmpty('registrationNumber', c.registration_number);
|
||||||
vars.companyAddress = c.address || '';
|
setIfEmpty('companyAddress', c.address);
|
||||||
vars.address = vars.companyAddress;
|
setIfEmpty('address', c.address);
|
||||||
vars.zip_code = c.zip_code || '';
|
setIfEmpty('zip_code', c.zip_code);
|
||||||
vars.city = c.city || '';
|
setIfEmpty('city', c.city);
|
||||||
vars.country = c.country || '';
|
setIfEmpty('country', c.country);
|
||||||
vars.contactPersonName = c.contact_person_name || '';
|
setIfEmpty('contactPersonName', c.contact_person_name);
|
||||||
vars.contactPersonPhone = c.contact_person_phone || c.phone || '';
|
setIfEmpty('contactPersonPhone', c.contact_person_phone || c.phone);
|
||||||
vars.companyEmail = c.email || c.company_email || c.contact_email || req.user.email || '';
|
setIfEmpty('companyEmail', c.email || c.company_email || c.contact_email || req.user.email);
|
||||||
vars.companyPhone = c.phone || c.contact_person_phone || '';
|
setIfEmpty('companyPhone', c.phone || c.contact_person_phone);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fallbacks from authenticated user payload (helps dummy/local users without profile rows)
|
||||||
|
setIfEmpty('companyName', req.user.companyName || req.user.company_name || req.user.company);
|
||||||
|
setIfEmpty('registrationNumber', req.user.registrationNumber || req.user.registration_number || req.user.vatNumber);
|
||||||
|
setIfEmpty('companyAddress', req.user.address || req.user.street || req.user.street_address);
|
||||||
|
setIfEmpty('address', req.user.address || req.user.street || req.user.street_address);
|
||||||
|
setIfEmpty('zip_code', req.user.zip_code || req.user.zip || req.user.postalCode || req.user.postal_code);
|
||||||
|
setIfEmpty('city', req.user.city || req.user.town);
|
||||||
|
setIfEmpty('country', req.user.country);
|
||||||
|
setIfEmpty('contactPersonName', req.user.contactPersonName || req.user.contact_person_name);
|
||||||
|
setIfEmpty('contactPersonPhone', req.user.contactPersonPhone || req.user.contact_person_phone || req.user.companyPhone || req.user.phone);
|
||||||
|
setIfEmpty('companyEmail', req.user.companyEmail || req.user.email);
|
||||||
|
setIfEmpty('companyPhone', req.user.companyPhone || req.user.phone);
|
||||||
|
|
||||||
|
if (!vars.companyAddress) setIfEmpty('companyAddress', vars.address);
|
||||||
|
if (!vars.address) setIfEmpty('address', vars.companyAddress);
|
||||||
|
|
||||||
const parts = [];
|
const parts = [];
|
||||||
if (vars.companyAddress) parts.push(vars.companyAddress);
|
if (vars.companyAddress) parts.push(vars.companyAddress);
|
||||||
const zipCity = [vars.zip_code, vars.city].filter(Boolean).join(' ');
|
const zipCity = [vars.zip_code, vars.city].filter(Boolean).join(' ');
|
||||||
@ -1637,14 +1655,13 @@ exports.previewLatestForMe = async (req, res) => {
|
|||||||
vars.companyFullAddress = parts.join(', ');
|
vars.companyFullAddress = parts.join(', ');
|
||||||
|
|
||||||
// Ensure template-prefixed company placeholders are populated
|
// Ensure template-prefixed company placeholders are populated
|
||||||
vars.companyCompanyName = vars.companyName;
|
vars.companyCompanyName = vars.companyName || '';
|
||||||
vars.companyRegistrationNumber = vars.registrationNumber;
|
vars.companyRegistrationNumber = vars.registrationNumber || '';
|
||||||
vars.companyZipCode = vars.zip_code;
|
vars.companyZipCode = vars.zip_code || '';
|
||||||
vars.companyCity = vars.city;
|
vars.companyCity = vars.city || '';
|
||||||
|
|
||||||
// Signature/display name for company preview
|
// Signature/display name for company preview
|
||||||
vars.fullName = vars.contactPersonName || vars.companyName || '';
|
vars.fullName = vars.contactPersonName || vars.companyName || vars.fullName || '';
|
||||||
}
|
|
||||||
logger.debug('[previewLatestForMe] company vars', { userId: targetUserId, found: !!c, vars });
|
logger.debug('[previewLatestForMe] company vars', { userId: targetUserId, found: !!c, vars });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.warn('[previewLatestForMe] company profile lookup failed', e && e.message);
|
logger.warn('[previewLatestForMe] company profile lookup failed', e && e.message);
|
||||||
|
|||||||
@ -3,6 +3,7 @@ const { uploadBuffer, s3: exoS3 } = require('../../utils/exoscaleUploader');
|
|||||||
const PDFDocument = require('pdfkit');
|
const PDFDocument = require('pdfkit');
|
||||||
const { S3Client, GetObjectCommand } = require('@aws-sdk/client-s3');
|
const { S3Client, GetObjectCommand } = require('@aws-sdk/client-s3');
|
||||||
const DocumentTemplateService = require('../template/DocumentTemplateService');
|
const DocumentTemplateService = require('../template/DocumentTemplateService');
|
||||||
|
const CompanyStampService = require('../stamp/company/CompanyStampService');
|
||||||
const db = require('../../database/database');
|
const db = require('../../database/database');
|
||||||
const fs = require('fs');
|
const fs = require('fs');
|
||||||
const path = require('path');
|
const path = require('path');
|
||||||
@ -49,7 +50,7 @@ async function streamToBuffer(body) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function fillTemplate(template, data) {
|
function fillTemplate(template, data) {
|
||||||
return template.replace(/{{(\w+)}}/g, (_, key) => data[key] || '');
|
return template.replace(/{{\s*(\w+)\s*}}/g, (_, key) => data[key] || '');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build placeholder variables by combining DB profile data with any contractData overrides (for both personal/company).
|
// Build placeholder variables by combining DB profile data with any contractData overrides (for both personal/company).
|
||||||
@ -310,7 +311,7 @@ class ContractUploadService {
|
|||||||
// Merge DB-derived vars with request data so placeholders fill like the preview endpoint
|
// Merge DB-derived vars with request data so placeholders fill like the preview endpoint
|
||||||
const vars = await buildTemplateVars({ userId, user_type, contractData, unitOfWork });
|
const vars = await buildTemplateVars({ userId, user_type, contractData, unitOfWork });
|
||||||
Object.entries(vars).forEach(([key, value]) => {
|
Object.entries(vars).forEach(([key, value]) => {
|
||||||
const re = new RegExp(`{{\s*${key}\s*}}`, 'g');
|
const re = new RegExp(`{{\\s*${key}\\s*}}`, 'g');
|
||||||
htmlTemplate = htmlTemplate.replace(re, String(value ?? ''));
|
htmlTemplate = htmlTemplate.replace(re, String(value ?? ''));
|
||||||
});
|
});
|
||||||
if (signatureImage) {
|
if (signatureImage) {
|
||||||
@ -319,6 +320,17 @@ class ContractUploadService {
|
|||||||
htmlTemplate = htmlTemplate.replace(/{{\s*signatureImage\s*}}/g, tag);
|
htmlTemplate = htmlTemplate.replace(/{{\s*signatureImage\s*}}/g, tag);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Apply Profit Planet signature stamp if placeholder exists
|
||||||
|
try {
|
||||||
|
if (htmlTemplate.match(/{{\s*profitplanetSignature\s*}}/i)) {
|
||||||
|
const tag = await CompanyStampService.getProfitPlanetSignatureTag({ maxW: 300, maxH: 300 });
|
||||||
|
htmlTemplate = htmlTemplate.replace(/{{\s*profitplanetSignature\s*}}/gi, tag || '');
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
logger.warn('ContractUploadService.uploadContract:profitplanetSignature failed', { userId, msg: e.message });
|
||||||
|
htmlTemplate = htmlTemplate.replace(/{{\s*profitplanetSignature\s*}}/gi, '');
|
||||||
|
}
|
||||||
|
|
||||||
// Render HTML to PDF via Puppeteer (closest to preview output)
|
// Render HTML to PDF via Puppeteer (closest to preview output)
|
||||||
const browser = await puppeteer.launch({ headless: 'new', args: ['--no-sandbox', '--disable-setuid-sandbox'] });
|
const browser = await puppeteer.launch({ headless: 'new', args: ['--no-sandbox', '--disable-setuid-sandbox'] });
|
||||||
const page = await browser.newPage();
|
const page = await browser.newPage();
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user