first commit

This commit is contained in:
Isuru Bimsara
2026-08-14 22:46:02 +05:30
commit 81d0e65686
132 changed files with 24398 additions and 0 deletions
@@ -0,0 +1,266 @@
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
@page {
size: A4;
margin: 0;
}
body {
background: #fff;
font-family: Arial, Helvetica, sans-serif;
padding: 8px;
}
.sheet {
width: 100%;
border: 1px solid #222;
background: #fff;
}
.top-band {
display: grid;
grid-template-columns: 1.45fr 1fr;
border-bottom: 1px solid #444;
min-height: 76px;
}
.top-left,
.top-right {
padding: 4px 6px;
font-size: 10px;
}
.top-right {
text-align: right;
line-height: 1.2;
}
.top-line {
margin-bottom: 2px;
}
.highlight-box {
display: grid;
grid-template-columns: 1.6fr 1fr;
border-bottom: 1px solid #444;
}
.highlight-left,
.highlight-right {
padding: 4px 6px;
min-height: 58px;
font-size: 10px;
}
.highlight-left {
border-right: 1px solid #444;
}
.highlight-row {
display: grid;
grid-template-columns: 155px 1fr;
gap: 6px;
margin-bottom: 2px;
}
.label {
font-weight: 700;
}
.permission-line {
text-align: center;
padding: 10px 8px 4px;
font-size: 10px;
}
.dots {
text-align: center;
letter-spacing: 3px;
color: #555;
padding: 2px 0 8px;
}
.company-name {
text-align: center;
font-size: 18px;
font-weight: 700;
padding: 6px 0 10px;
}
.company-subtitle {
text-align: center;
font-size: 13px;
font-weight: 700;
padding-bottom: 10px;
}
.date-row {
display: flex;
justify-content: flex-end;
border-bottom: 1px solid #444;
padding: 0 6px 4px;
}
.date-box {
min-width: 138px;
background: #ffeb3b;
font-weight: 700;
padding: 2px 8px;
text-align: right;
}
.form-code {
font-size: 9px;
padding: 2px 4px 3px;
}
.items-table {
width: 100%;
border-collapse: collapse;
table-layout: fixed;
}
.items-table th,
.items-table td {
border: 1px solid #444;
font-size: 10px;
padding: 2px 3px;
vertical-align: middle;
}
.items-table th {
text-align: center;
font-weight: 700;
background: #fff;
}
.items-table thead th {
height: 33px;
}
.no-col { width: 8%; }
.qty-col { width: 7%; }
.unit-col { width: 7%; }
.description-col { width: 40%; }
.rate-col { width: 13%; }
.total-col { width: 12%; }
.confirm-col { width: 13%; }
.center {
text-align: center;
}
.right {
text-align: right;
}
.spacer-row td {
height: 24px;
}
.muted {
color: #666;
}
</style>
</head>
<body>
<%
const customTitle = typeof title !== 'undefined' && title ? title : 'CUSTOM DOCUMENT';
const customDate = typeof date !== 'undefined' && date ? date : 'N/A';
const customTelePhone = typeof telePhone !== 'undefined' && telePhone ? telePhone : '';
const customEmail = typeof emailAddress !== 'undefined' && emailAddress ? emailAddress : '';
const customOfficeAddressLine1 = typeof officeAddressLine1 !== 'undefined' && officeAddressLine1 ? officeAddressLine1 : '';
const customOfficeAddressLine2 = typeof officeAddressLine2 !== 'undefined' && officeAddressLine2 ? officeAddressLine2 : '';
const customOfficeAddressLine3 = typeof officeAddressLine3 !== 'undefined' && officeAddressLine3 ? officeAddressLine3 : '';
const customDirectorOfCustoms = typeof directorOfCustoms !== 'undefined' && directorOfCustoms ? directorOfCustoms : '';
const customVehicleNo = typeof vehicleNo !== 'undefined' && vehicleNo ? vehicleNo : '';
const customPermitNo = typeof permitNo !== 'undefined' && permitNo ? permitNo : '';
const customChiefSecurityOfficer = typeof chiefSecurityOfficer !== 'undefined' && chiefSecurityOfficer ? chiefSecurityOfficer : '';
const customExportGate = typeof exportGate !== 'undefined' && exportGate ? exportGate : '';
const customSlpa = typeof slpa !== 'undefined' && slpa ? slpa : '';
const customGateNo = typeof gateNo !== 'undefined' && gateNo ? gateNo : '';
const customPermissionText = typeof permissionText !== 'undefined' && permissionText ? permissionText : '';
const customCompanyName = typeof companyName !== 'undefined' && companyName ? companyName : 'Oceanic Maritime Solutions (Pvt) Ltd';
const customSubtitle = typeof subtitle !== 'undefined' && subtitle ? subtitle : 'LICENSED SHIPCHANDLERS';
const customSectionCode = typeof sectionCode !== 'undefined' && sectionCode ? sectionCode : 'SC/FORM/06';
const customDateLabel = typeof dateLabel !== 'undefined' && dateLabel ? dateLabel : 'DATE :';
const customItems = typeof items !== 'undefined' && Array.isArray(items) ? items : [];
const rows = Math.max(7, customItems.length);
%>
<div class="sheet">
<div class="top-band">
<div class="top-left">
<div class="top-line"><span class="label">Tele :</span> <%= customTelePhone || '' %></div>
<div class="top-line"><span class="label">E-mail Address :</span> <%= customEmail || '' %></div>
</div>
<div class="top-right">
<div><%= customOfficeAddressLine1 %></div>
<div><%= customOfficeAddressLine2 %></div>
<div><%= customOfficeAddressLine3 %></div>
</div>
</div>
<div class="highlight-box">
<div class="highlight-left">
<div class="highlight-row"><div class="label">The Director of Customs</div><div><%= customDirectorOfCustoms %></div></div>
<div class="highlight-row"><div class="label">Export Gate</div><div><span style="color:#e53935;">Colombo 1.</span></div></div>
<div class="highlight-row"><div class="label">Vehicle No. / Permit No.</div><div><%= customVehicleNo %> / <%= customPermitNo %></div></div>
</div>
<div class="highlight-right">
<div class="highlight-row"><div class="label">Chief Security Officer</div><div><%= customChiefSecurityOfficer %></div></div>
<div class="highlight-row"><div class="label">SLPA</div><div><%= customSlpa %></div></div>
<div class="highlight-row"><div class="label">Gate No.</div><div><%= customGateNo %></div></div>
</div>
</div>
<div class="permission-line"><%= customPermissionText %></div>
<div class="dots">............................................................</div>
<div class="company-name"><%= customCompanyName %></div>
<div class="company-subtitle"><%= customSubtitle %></div>
<div class="date-row">
<div class="date-box"><%= customDateLabel %> <%= customDate %></div>
</div>
<div class="form-code"><%= customSectionCode %></div>
<table class="items-table">
<thead>
<tr>
<th class="no-col">NO</th>
<th class="qty-col">QTY</th>
<th class="unit-col">UNIT</th>
<th class="description-col">DESCRIPTION</th>
<th class="rate-col">RATE</th>
<th class="total-col">TOTAL</th>
<th class="confirm-col">Confirm<br/>Order Rate</th>
</tr>
</thead>
<tbody>
<% for (let index = 0; index < rows; index++) { %>
<% const item = customItems[index] || {}; %>
<tr class="spacer-row">
<td class="center"><%= index + 1 %></td>
<td class="center"><%= item.quantity || item.qty || '' %></td>
<td class="center"><%= item.unit || '' %></td>
<td><%= item.description || item.item_name || item.name || '' %></td>
<td class="right"><%= item.rate || item.unit_price || '-' %></td>
<td class="right"><%= item.total || item.amount || '-' %></td>
<td><%= item.confirmOrderRate || item.confirm_order_rate || '' %></td>
</tr>
<% } %>
</tbody>
</table>
</div>
</body>
</html>
@@ -0,0 +1,81 @@
/**
* Copyright (c) 2026 Niolla
* All rights reserved.
*
* This source code is proprietary and confidential.
* Unauthorized copying, modification, distribution, or use
* of this file, via any medium, is strictly prohibited.
*/
// app/templates/documents/customDocument/customDocument.template.js
const { log } = require("../../../utils/consoleLog.utill");
module.exports = async (data) => {
log("📋 Preparing Custom Document data for PDF...");
let payload = data;
if (typeof payload === "string") {
try {
payload = JSON.parse(payload);
} catch (error) {
payload = {};
}
}
const source = payload.documentData || payload.document_data || payload.data || payload;
const pick = (...keys) => {
for (const key of keys) {
const value = source?.[key];
if (value !== undefined && value !== null && value !== "") {
return value;
}
}
return "";
};
const templateData = {
logoUrl:
pick("logoUrl", "logo_url") ||
"https://res.cloudinary.com/dtthuvvir/image/upload/v1780748661/company_logo_transperent_bg_uullzw.png",
title: pick("title") || "CUSTOM DOCUMENT",
documentNumber: pick("documentNumber", "document_number") || "",
date: pick("date") || new Date().toLocaleDateString(),
telePhone: pick("telePhone", "telephone", "phone", "tel") || "",
emailAddress: pick("emailAddress", "email", "e_mail") || "",
officeAddressLine1: pick("officeAddressLine1", "office_address_line1") || "",
officeAddressLine2: pick("officeAddressLine2", "office_address_line2") || "",
officeAddressLine3: pick("officeAddressLine3", "office_address_line3") || "",
directorOfCustoms: pick("directorOfCustoms", "director_of_customs") || "",
vehicleNo: pick("vehicleNo", "vehicle_no") || "",
permitNo: pick("permitNo", "permit_no") || "",
chiefSecurityOfficer: pick("chiefSecurityOfficer", "chief_security_officer") || "",
exportGate: pick("exportGate", "export_gate") || "",
slpa: pick("slpa") || "",
gateNo: pick("gateNo", "gate_no") || "",
permissionText: pick("permissionText", "permission_text") || "Please grant permission to pass these Customs entry papers to supply goods to the vessel",
companyName: pick("companyName", "company_name") || "Oceanic Maritime Solutions (Pvt) Ltd",
subtitle: pick("subtitle") || "LICENSED SHIPCHANDLERS",
sectionCode: pick("sectionCode", "section_code") || "SC/FORM/06",
dateLabel: pick("dateLabel", "date_label") || "DATE :",
items: Array.isArray(source.items) ? source.items : [],
itemHeaders:
pick("itemHeaders", "item_headers") ||
["NO", "QTY", "UNIT", "DESCRIPTION", "RATE", "TOTAL", "Confirm Order Rate"],
footerText: pick("footerText", "footer_text") || "",
};
log("✅ Custom Document data prepared");
return templateData;
};