mirror of
https://github.com/Tria-plc/edr-platform.git
synced 2026-08-30 15:48:11 +00:00
feat(last-mile): customer-signed LM contract gates the advance invoice
Approval now snapshots the rate estimate and generates a last-mile contract instead of invoicing immediately. The customer picks a delivery date on the confirm form, then reviews and signs the contract in the portal (saved signature or drawn); the signed PDF is stored as LM_<CustomerName>.pdf and only then is the advance invoice issued. Backoffice shows signature status and the contract download.
This commit is contained in:
114
apps/edr-freight-api/src/contracts/templates/last-mile.hbs
Normal file
114
apps/edr-freight-api/src/contracts/templates/last-mile.hbs
Normal file
@@ -0,0 +1,114 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="utf-8" />
|
||||
<title>Last-Mile Delivery Contract — {{bookingReference}}</title>
|
||||
<style>
|
||||
* { box-sizing: border-box; }
|
||||
body { font-family: 'Helvetica Neue', Arial, sans-serif; color: #1a1a1a; margin: 0; font-size: 12px; line-height: 1.5; }
|
||||
main { padding: 32px 40px; }
|
||||
.brand-row { display: flex; align-items: center; gap: 14px; border-bottom: 3px solid #1a5632; padding-bottom: 14px; }
|
||||
.logo-mark { background: #1a5632; color: #fff; font-weight: 700; font-size: 18px; padding: 10px 14px; border-radius: 6px; }
|
||||
.kicker { margin: 0; font-weight: 700; }
|
||||
.muted { margin: 0; color: #666; }
|
||||
h1 { font-size: 20px; margin: 24px 0 4px; }
|
||||
h2 { font-size: 14px; margin: 26px 0 8px; color: #1a5632; border-bottom: 1px solid #d8d8d8; padding-bottom: 4px; }
|
||||
table { width: 100%; border-collapse: collapse; margin-top: 8px; }
|
||||
th, td { border: 1px solid #d8d8d8; padding: 6px 10px; text-align: left; vertical-align: top; }
|
||||
th { background: #f2f6f3; width: 32%; font-weight: 600; }
|
||||
.rates th { width: auto; }
|
||||
.rates .amount { text-align: right; white-space: nowrap; }
|
||||
.rates tfoot td { font-weight: 700; background: #f2f6f3; }
|
||||
.terms p { margin: 6px 0; }
|
||||
.sig-grid { display: flex; gap: 24px; margin-top: 18px; }
|
||||
.sig-card { flex: 1; border: 1px solid #d8d8d8; border-radius: 6px; padding: 14px; min-height: 130px; }
|
||||
.sig-card h3 { margin: 0 0 8px; font-size: 12px; color: #1a5632; }
|
||||
.sig-card img { max-height: 60px; max-width: 100%; }
|
||||
.sig-line { border-top: 1px solid #999; margin-top: 40px; padding-top: 4px; color: #666; }
|
||||
.consent { margin-top: 6px; font-style: italic; color: #444; }
|
||||
.pending { color: #999; font-style: italic; }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<main>
|
||||
<div class="brand-row">
|
||||
<div class="logo-mark">EDR</div>
|
||||
<div>
|
||||
<p class="kicker">Ethio-Djibouti Standard Gauge Railway Share Company</p>
|
||||
<p class="muted">Last-Mile Delivery Contract</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<h1>Last-Mile Delivery Contract</h1>
|
||||
<p class="muted">Booking {{bookingReference}} — {{companyName}}</p>
|
||||
|
||||
<h2>Shipment Details</h2>
|
||||
<table>
|
||||
<tr><th>Client</th><td>{{companyName}}</td></tr>
|
||||
<tr><th>Booking Reference</th><td>{{bookingReference}}</td></tr>
|
||||
{{#if containerCount}}
|
||||
<tr><th>Number of Containers</th><td>{{containerCount}}</td></tr>
|
||||
<tr><th>Containers</th><td>{{containerList}}</td></tr>
|
||||
{{/if}}
|
||||
{{#if cargoDescription}}
|
||||
<tr><th>Cargo Description</th><td>{{cargoDescription}}</td></tr>
|
||||
{{/if}}
|
||||
{{#if deliveryAddress}}
|
||||
<tr><th>Delivery Address</th><td>{{deliveryAddress}}</td></tr>
|
||||
{{/if}}
|
||||
{{#if trainDepartureDate}}
|
||||
<tr><th>Train Departure from Djibouti</th><td>{{trainDepartureDate}}</td></tr>
|
||||
{{/if}}
|
||||
<tr><th>Last-Mile Delivery Date</th><td>{{deliveryDate}}</td></tr>
|
||||
<tr><th>Request Date</th><td>{{requestDate}}</td></tr>
|
||||
<tr><th>Approval Date</th><td>{{approvalDate}}</td></tr>
|
||||
</table>
|
||||
|
||||
<h2>Rates</h2>
|
||||
<table class="rates">
|
||||
<thead>
|
||||
<tr><th>Description</th><th class="amount">Amount{{#if currency}} ({{currency}}){{/if}}</th></tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{{#each rateLines}}
|
||||
<tr><td>{{description}}</td><td class="amount">{{amount}}</td></tr>
|
||||
{{/each}}
|
||||
{{#if estimatedKm}}
|
||||
<tr><td class="muted">Estimated distance</td><td class="amount">{{estimatedKm}} km</td></tr>
|
||||
{{/if}}
|
||||
</tbody>
|
||||
<tfoot>
|
||||
<tr><td>Advance payable on signing</td><td class="amount">{{advanceAmount}}{{#if currency}} {{currency}}{{/if}}</td></tr>
|
||||
</tfoot>
|
||||
</table>
|
||||
|
||||
<h2>Terms</h2>
|
||||
<div class="terms">
|
||||
<p>1. The Service Provider shall deliver the goods identified above from the arrival yard to the Client's delivery address on or about the last-mile delivery date stated above.</p>
|
||||
<p>2. The Client shall pay the advance stated above upon signing this contract. The final delivery fee is computed on completion per the Service Provider's published last-mile rates and actual distance.</p>
|
||||
<p>3. The Client shall ensure access and receipt of the goods at the delivery address. Waiting time and truck detention beyond free time may incur additional charges per the applicable tariff.</p>
|
||||
<p>4. This contract is governed by the laws applicable to the Ethio-Djibouti Standard Gauge Railway Share Company's freight services.</p>
|
||||
</div>
|
||||
|
||||
<h2>Signatures</h2>
|
||||
<div class="sig-grid">
|
||||
<div class="sig-card">
|
||||
<h3>Client</h3>
|
||||
{{#if signature}}
|
||||
<img src="{{signature.imageUrl}}" alt="Customer signature" />
|
||||
<div class="sig-line">{{signature.signerDisplayName}} — signed {{signature.signedAt}}</div>
|
||||
{{#if signature.consentText}}<div class="consent">"{{signature.consentText}}"</div>{{/if}}
|
||||
{{else}}
|
||||
<p class="pending">Awaiting customer signature.</p>
|
||||
<div class="sig-line">Name, signature & date</div>
|
||||
{{/if}}
|
||||
</div>
|
||||
<div class="sig-card">
|
||||
<h3>Service Provider</h3>
|
||||
<p>Ethio-Djibouti Standard Gauge Railway Share Company</p>
|
||||
<div class="sig-line">Authorized representative</div>
|
||||
</div>
|
||||
</div>
|
||||
</main>
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user