102 lines
3.9 KiB
TypeScript
102 lines
3.9 KiB
TypeScript
|
|
import type { Template } from '@pdfme/common';
|
||
|
|
|
||
|
|
export const interestSummaryTemplate: Template = {
|
||
|
|
basePdf: 'BLANK_PDF' as any,
|
||
|
|
schemas: [
|
||
|
|
[
|
||
|
|
{ name: 'portName', type: 'text', position: { x: 20, y: 15 }, width: 100, height: 10, fontSize: 16 },
|
||
|
|
{ name: 'title', type: 'text', position: { x: 20, y: 30 }, width: 170, height: 8, fontSize: 14 },
|
||
|
|
{ name: 'clientInfo', type: 'text', position: { x: 20, y: 45 }, width: 80, height: 30, fontSize: 9 },
|
||
|
|
{ name: 'berthInfo', type: 'text', position: { x: 110, y: 45 }, width: 80, height: 30, fontSize: 9 },
|
||
|
|
{ name: 'stageAndCategory', type: 'text', position: { x: 20, y: 80 }, width: 170, height: 15, fontSize: 9 },
|
||
|
|
{ name: 'milestones', type: 'text', position: { x: 20, y: 100 }, width: 170, height: 40, fontSize: 8 },
|
||
|
|
{ name: 'notes', type: 'text', position: { x: 20, y: 145 }, width: 170, height: 30, fontSize: 9 },
|
||
|
|
{ name: 'recentTimeline', type: 'text', position: { x: 20, y: 180 }, width: 170, height: 85, fontSize: 8 },
|
||
|
|
{ name: 'generatedAt', type: 'text', position: { x: 20, y: 275 }, width: 170, height: 6, fontSize: 7 },
|
||
|
|
],
|
||
|
|
],
|
||
|
|
};
|
||
|
|
|
||
|
|
function formatDate(d: Date | string | null | undefined): string {
|
||
|
|
if (!d) return 'N/A';
|
||
|
|
return new Date(d).toLocaleDateString('en-GB');
|
||
|
|
}
|
||
|
|
|
||
|
|
export function buildInterestSummaryInputs(
|
||
|
|
interest: any,
|
||
|
|
client: any,
|
||
|
|
berth: any,
|
||
|
|
timeline: any[],
|
||
|
|
port: any,
|
||
|
|
): Record<string, string> {
|
||
|
|
const clientInfo = [
|
||
|
|
`Name: ${client?.fullName ?? 'N/A'}`,
|
||
|
|
client?.companyName ? `Company: ${client.companyName}` : null,
|
||
|
|
client?.yachtName ? `Yacht: ${client.yachtName}` : null,
|
||
|
|
client?.yachtLengthFt
|
||
|
|
? `Length: ${client.yachtLengthFt}ft${client.yachtLengthM ? ` / ${client.yachtLengthM}m` : ''}`
|
||
|
|
: null,
|
||
|
|
]
|
||
|
|
.filter(Boolean)
|
||
|
|
.join('\n');
|
||
|
|
|
||
|
|
const berthInfo = berth
|
||
|
|
? [
|
||
|
|
`Mooring: ${berth.mooringNumber}`,
|
||
|
|
berth.area ? `Area: ${berth.area}` : null,
|
||
|
|
berth.lengthFt ? `Length: ${berth.lengthFt}ft` : null,
|
||
|
|
berth.price ? `Price: ${berth.priceCurrency ?? 'USD'} ${Number(berth.price).toLocaleString()}` : null,
|
||
|
|
`Status: ${berth.status ?? 'available'}`,
|
||
|
|
]
|
||
|
|
.filter(Boolean)
|
||
|
|
.join('\n')
|
||
|
|
: 'No berth linked';
|
||
|
|
|
||
|
|
const stageAndCategory = [
|
||
|
|
`Stage: ${interest.pipelineStage ?? 'open'}`,
|
||
|
|
interest.leadCategory ? `Category: ${interest.leadCategory}` : null,
|
||
|
|
interest.source ? `Source: ${interest.source}` : null,
|
||
|
|
interest.eoiStatus ? `EOI status: ${interest.eoiStatus}` : null,
|
||
|
|
interest.contractStatus ? `Contract: ${interest.contractStatus}` : null,
|
||
|
|
interest.depositStatus ? `Deposit: ${interest.depositStatus}` : null,
|
||
|
|
]
|
||
|
|
.filter(Boolean)
|
||
|
|
.join(' | ');
|
||
|
|
|
||
|
|
const milestones = [
|
||
|
|
`First contact: ${formatDate(interest.dateFirstContact)}`,
|
||
|
|
`Last contact: ${formatDate(interest.dateLastContact)}`,
|
||
|
|
`EOI sent: ${formatDate(interest.dateEoiSent)}`,
|
||
|
|
`EOI signed: ${formatDate(interest.dateEoiSigned)}`,
|
||
|
|
`Contract sent: ${formatDate(interest.dateContractSent)}`,
|
||
|
|
`Contract signed: ${formatDate(interest.dateContractSigned)}`,
|
||
|
|
`Deposit received: ${formatDate(interest.dateDepositReceived)}`,
|
||
|
|
].join('\n');
|
||
|
|
|
||
|
|
const notesText = interest.notes
|
||
|
|
? `Notes:\n${interest.notes}`
|
||
|
|
: 'No notes';
|
||
|
|
|
||
|
|
const timelineText =
|
||
|
|
timeline.length > 0
|
||
|
|
? timeline
|
||
|
|
.map(
|
||
|
|
(e) =>
|
||
|
|
`${formatDate(e.createdAt)} ${e.action ?? e.eventType ?? 'event'} ${e.entityType ?? e.type ?? ''}${e.fieldChanged ? ` [${e.fieldChanged}]` : ''}`,
|
||
|
|
)
|
||
|
|
.join('\n')
|
||
|
|
: 'No timeline events';
|
||
|
|
|
||
|
|
return {
|
||
|
|
portName: port?.name ?? 'Port Nimara',
|
||
|
|
title: `Interest Summary — ${client?.fullName ?? 'Unknown Client'}`,
|
||
|
|
clientInfo,
|
||
|
|
berthInfo,
|
||
|
|
stageAndCategory,
|
||
|
|
milestones: `Milestones:\n${milestones}`,
|
||
|
|
notes: notesText,
|
||
|
|
recentTimeline: `Recent Timeline (last ${timeline.length}):\n${timelineText}`,
|
||
|
|
generatedAt: `Generated: ${new Date().toLocaleString('en-GB')}`,
|
||
|
|
};
|
||
|
|
}
|