@narrow-os/document-templates 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,558 @@
1
+ type A4DocumentTemplateId = "classic" | "modern" | "minimal" | "corporate" | "bold" | "elegant" | "tech" | "vibrant" | "compact" | "mono";
2
+ type ThermalDocumentTemplateId = "classic" | "compact" | "wide" | "dense" | "sparse" | "boxed" | "lined" | "split" | "monobold" | "elegant";
3
+ interface A4DocumentTemplate {
4
+ id: A4DocumentTemplateId;
5
+ name: string;
6
+ description: string;
7
+ primary: string;
8
+ accent: string;
9
+ brand: string;
10
+ headerBg: string;
11
+ headerText: string;
12
+ totalsBg: string;
13
+ totalsBorder: string;
14
+ rowAltBg: string;
15
+ border: string;
16
+ borderFaint: string;
17
+ surface: string;
18
+ text: string;
19
+ textMuted: string;
20
+ fontFamily: string;
21
+ fontFamilyHeading: string;
22
+ fontSize: string;
23
+ borderRadius: string;
24
+ dividerStyle: "solid" | "dashed" | "dotted" | "double" | "none";
25
+ headerLayout: "stacked" | "split" | "banded" | "sidebar";
26
+ titleAlign: "left" | "right" | "center";
27
+ }
28
+ interface ThermalDocumentTemplate {
29
+ id: ThermalDocumentTemplateId;
30
+ name: string;
31
+ description: string;
32
+ fontFamily: string;
33
+ fontSize: string;
34
+ fontWeightBase: number;
35
+ dividerStyle: "solid" | "dashed" | "dotted" | "double" | "none";
36
+ headerLayout: "centered" | "left-aligned" | "boxed";
37
+ itemSpacing: "tight" | "normal" | "loose";
38
+ showBorders?: boolean;
39
+ totalsStyle?: "bordered" | "plain" | "accent";
40
+ inkColor?: string;
41
+ accentColor?: string;
42
+ backgroundColor?: string;
43
+ }
44
+
45
+ interface CompanyInfo {
46
+ id?: string;
47
+ companyName?: string;
48
+ taxId?: string;
49
+ address?: string;
50
+ Address?: string;
51
+ city?: string;
52
+ website?: string;
53
+ paymentTerms?: string;
54
+ note?: string;
55
+ bankAccount?: string;
56
+ bankAccount2?: string;
57
+ bankName?: string;
58
+ bankName2?: string;
59
+ logo?: string;
60
+ terminalLogo?: string;
61
+ province?: string;
62
+ postCode?: string;
63
+ phone?: string;
64
+ phone2?: string;
65
+ phone3?: string;
66
+ email?: string;
67
+ signature?: string;
68
+ showWatermark?: boolean;
69
+ showSignature?: boolean;
70
+ deliveryNoteNote?: string;
71
+ deliveryNoteTerms?: string;
72
+ purchaseOrderNote?: string;
73
+ purchaseOrderTerms?: string;
74
+ proFormaNote?: string;
75
+ proFormaTerms?: string;
76
+ creditNoteNote?: string;
77
+ creditNoteTerms?: string;
78
+ supplierListNote?: string;
79
+ supplierListTerms?: string;
80
+ }
81
+ interface ReceiptCompanyInfo {
82
+ name: string;
83
+ address: string;
84
+ phone: string;
85
+ email: string;
86
+ taxNumber?: string;
87
+ logo?: string;
88
+ terminalLogo?: string;
89
+ signature?: string;
90
+ showWatermark?: boolean;
91
+ showSignature?: boolean;
92
+ website?: string;
93
+ }
94
+
95
+ type DocumentTypeKey = "invoice" | "quotation" | "invoiceDocument" | "deliveryNote" | "thermal";
96
+ interface DocumentTypeSettings {
97
+ showSignature: boolean;
98
+ showWatermark: boolean;
99
+ showBarcode: boolean;
100
+ showQRCode: boolean;
101
+ showPreparedBy: boolean;
102
+ showLastUpdatedBy: boolean;
103
+ showDescription: boolean;
104
+ showPaymentTerms: boolean;
105
+ showAdditionalNotes: boolean;
106
+ showTaxNumber: boolean;
107
+ showEmail: boolean;
108
+ showPhone: boolean;
109
+ showWebsite: boolean;
110
+ showBankDetails: boolean;
111
+ }
112
+ type DocumentSettingsMap = Partial<Record<DocumentTypeKey, DocumentTypeSettings>>;
113
+ interface OrganizationDocumentSettings {
114
+ documentSettings?: DocumentSettingsMap;
115
+ }
116
+
117
+ interface InvoiceItemData {
118
+ id?: string;
119
+ description?: string | null;
120
+ quantity: string | number | any;
121
+ unitPrice: string | number | any;
122
+ amount: string | number | any;
123
+ taxRate?: string | number | any;
124
+ taxAmount?: string | number | any;
125
+ shopProductId?: string | null;
126
+ serviceId?: string | null;
127
+ itemDiscountType?: "AMOUNT" | "PERCENTAGE" | null;
128
+ itemDiscountAmount?: string | number | any;
129
+ details?: string | null;
130
+ }
131
+ interface InvoicePaymentData {
132
+ id?: string;
133
+ amount: string | number | any;
134
+ method?: string | null;
135
+ reference?: string | null;
136
+ notes?: string | null;
137
+ status?: string | null;
138
+ paidAt?: string | Date | null;
139
+ isDeleted?: boolean;
140
+ deletedBy?: string;
141
+ documents?: any[];
142
+ transactionId?: string | null;
143
+ createdBy?: string | null;
144
+ creator?: {
145
+ name: string;
146
+ };
147
+ bank?: {
148
+ id: string;
149
+ name: string;
150
+ };
151
+ }
152
+ interface ClientData {
153
+ id?: string;
154
+ name?: string | null;
155
+ company?: string | null;
156
+ fullName?: string | null;
157
+ address?: string | null;
158
+ phone?: string | null;
159
+ phone2?: string | null;
160
+ email?: string | null;
161
+ taxNumber?: string | null;
162
+ registrationNumber?: string | null;
163
+ city?: string | null;
164
+ town?: string | null;
165
+ village?: string | null;
166
+ province?: string | null;
167
+ postalCode?: string | null;
168
+ website?: string | null;
169
+ }
170
+ interface InvoiceDocumentData {
171
+ id?: string;
172
+ invoiceNumber?: string | null;
173
+ issueDate?: Date | string | null;
174
+ dueDate?: Date | string | null;
175
+ status?: string | null;
176
+ description?: string | null;
177
+ salutation?: string | null;
178
+ paymentTerms?: string | null;
179
+ notes?: string | null;
180
+ terms?: string | null;
181
+ amount?: number | string | any;
182
+ subtotal?: number | string | any;
183
+ totalAmount?: number | string | any;
184
+ taxAmount?: number | string | any;
185
+ taxRate?: number | string | any;
186
+ discountAmount?: number | string | any;
187
+ discountType?: string | null | any;
188
+ pdfUrl?: string | null;
189
+ depositRequired?: boolean | null;
190
+ depositType?: string | null | any;
191
+ depositAmount?: number | string | any;
192
+ depositRate?: number | string | any;
193
+ installmentPeriod?: string | null;
194
+ interestRate?: number | string | any;
195
+ interestAmount?: number | string | any;
196
+ items: InvoiceItemData[];
197
+ payments?: InvoicePaymentData[];
198
+ client: ClientData;
199
+ creator?: {
200
+ name?: string;
201
+ GeneralSetting?: Array<{
202
+ companyName?: string;
203
+ Address?: string;
204
+ city?: string;
205
+ logo?: string;
206
+ province?: string;
207
+ postCode?: string;
208
+ phone?: string;
209
+ phone2?: string;
210
+ phone3?: string;
211
+ website?: string;
212
+ bankAccount?: string;
213
+ bankAccount2?: string;
214
+ bankName?: string;
215
+ bankName2?: string;
216
+ email?: string;
217
+ taxId?: string;
218
+ taxRate?: string;
219
+ paymentInstructions?: string;
220
+ }> | any;
221
+ };
222
+ createdBy?: string;
223
+ lastUpdatedBy?: {
224
+ id: string;
225
+ name: string;
226
+ } | null;
227
+ }
228
+ type InvoiceProps = InvoiceDocumentData;
229
+ interface CombinedServiceData {
230
+ description: string;
231
+ quantity: number;
232
+ unitPrice: number;
233
+ linePrice: number;
234
+ discountInput: string;
235
+ vat: number;
236
+ total: number;
237
+ individualServices: Array<{
238
+ description: string;
239
+ qty: number;
240
+ unitPrice: number;
241
+ linePrice: number;
242
+ discountInput: string;
243
+ vat: number;
244
+ total: number;
245
+ details?: string | null;
246
+ }>;
247
+ displayType: "combined-service";
248
+ }
249
+ interface InvoiceReportGeneratorOptions {
250
+ combineServices?: boolean;
251
+ hideItemPrices?: boolean;
252
+ templateId?: string;
253
+ docSettings?: DocumentTypeSettings;
254
+ }
255
+
256
+ interface QuotationItemData {
257
+ id?: string;
258
+ description?: string | null;
259
+ quantity: number | string | any;
260
+ unitPrice: number | string | any;
261
+ amount: number | string | any;
262
+ taxAmount?: number | string | any;
263
+ taxRate?: number | string | any;
264
+ details?: string | null;
265
+ serviceId?: string | null;
266
+ shopProductId?: string | null;
267
+ }
268
+ interface QuotationDocumentData {
269
+ id?: string;
270
+ quotationNumber?: string | null;
271
+ issueDate?: Date | string | null;
272
+ date?: Date | string | null;
273
+ createdAt?: Date | string | null;
274
+ dueDate?: Date | string | null;
275
+ validUntil?: Date | string | null;
276
+ status?: string | null;
277
+ salutation?: string | null;
278
+ description?: string | null;
279
+ notes?: string | null;
280
+ terms?: string | null;
281
+ amount?: number | string | any;
282
+ subtotal?: number | string | any;
283
+ totalAmount?: number | string | any;
284
+ taxAmount?: number | string | any;
285
+ taxRate?: number | string | any;
286
+ discountAmount?: number | string | any;
287
+ discountType?: string | null | any;
288
+ depositRequired?: boolean | null;
289
+ depositType?: string | null | any;
290
+ depositAmount?: number | string | any;
291
+ installmentPeriod?: number | string | any;
292
+ interestRate?: number | string | any;
293
+ interestAmount?: number | string | any;
294
+ items: QuotationItemData[];
295
+ client: ClientData;
296
+ creator?: {
297
+ id?: string;
298
+ name?: string;
299
+ GeneralSetting?: Array<{
300
+ logo?: string;
301
+ companyName?: string;
302
+ Address?: string;
303
+ city?: string;
304
+ taxId?: string;
305
+ province?: string;
306
+ postCode?: string;
307
+ email?: string;
308
+ phone?: string;
309
+ phone2?: string;
310
+ phone3?: string;
311
+ website?: string;
312
+ bankAccount?: string;
313
+ bankAccount2?: string;
314
+ bankName?: string;
315
+ bankName2?: string;
316
+ }> | any;
317
+ };
318
+ lastUpdatedBy?: {
319
+ id: string;
320
+ name: string;
321
+ } | null;
322
+ }
323
+ type QuotationWithRelations = QuotationDocumentData;
324
+ interface QuotationReportGeneratorOptions {
325
+ combineServices?: boolean;
326
+ hideItemPrices?: boolean;
327
+ templateId?: string;
328
+ docSettings?: DocumentTypeSettings;
329
+ }
330
+
331
+ interface SaleItem {
332
+ id: string;
333
+ shopProductId?: string;
334
+ quantity: number;
335
+ price: number;
336
+ total: number;
337
+ product?: {
338
+ name: string;
339
+ sku?: string;
340
+ };
341
+ hadNegativeStock?: boolean;
342
+ awaitedQuantity?: number;
343
+ }
344
+ interface ReceiptData {
345
+ id: string;
346
+ saleNumber: string;
347
+ date: string;
348
+ customerName?: string;
349
+ customerPhone?: string;
350
+ customerEmail?: string;
351
+ items: SaleItem[];
352
+ subtotal: number;
353
+ discount: number;
354
+ discountPercent?: number;
355
+ tax: number;
356
+ taxPercent?: number;
357
+ total: number;
358
+ paymentMethod: string;
359
+ amountReceived?: number;
360
+ change?: number;
361
+ company: ReceiptCompanyInfo;
362
+ createdBy?: string;
363
+ status?: string;
364
+ stockAwaitItems?: Array<{
365
+ id: string;
366
+ shopProduct: {
367
+ name: string;
368
+ sku: string;
369
+ };
370
+ quantity: number;
371
+ }>;
372
+ }
373
+ type ReceiptSize = "A4" | "thermal";
374
+
375
+ interface DeliveryNoteItemData {
376
+ id: string;
377
+ description: string;
378
+ quantity: number | string;
379
+ unitPrice?: number | string;
380
+ amount?: number | string;
381
+ details?: string | null;
382
+ }
383
+ interface DeliveryNoteDocumentData {
384
+ id: string;
385
+ deliveryNoteNumber: string;
386
+ date: Date | string;
387
+ referenceNumber?: string;
388
+ status?: string;
389
+ notes?: string;
390
+ terms?: string;
391
+ items: DeliveryNoteItemData[];
392
+ client: ClientData;
393
+ company?: CompanyInfo;
394
+ creator?: {
395
+ name?: string;
396
+ };
397
+ }
398
+ interface DeliveryNoteGeneratorOptions {
399
+ templateId?: string;
400
+ docSettings?: DocumentTypeSettings;
401
+ }
402
+
403
+ declare const A4_TEMPLATES: A4DocumentTemplate[];
404
+
405
+ declare const THERMAL_TEMPLATES: ThermalDocumentTemplate[];
406
+
407
+ declare const DEFAULT_A4_ID: A4DocumentTemplateId;
408
+ declare const DEFAULT_THERMAL_ID: ThermalDocumentTemplateId;
409
+ declare const A4_TEMPLATE_IDS: A4DocumentTemplateId[];
410
+ declare const THERMAL_TEMPLATE_IDS: ThermalDocumentTemplateId[];
411
+ declare function isA4TemplateId(value: unknown): value is A4DocumentTemplateId;
412
+ declare function isThermalTemplateId(value: unknown): value is ThermalDocumentTemplateId;
413
+ declare function getA4Template(id?: string | null): A4DocumentTemplate;
414
+ declare function getThermalTemplate(id?: string | null): ThermalDocumentTemplate;
415
+ declare function isClassicTemplate(id?: string | null): boolean;
416
+
417
+ /**
418
+ * Shared contact/address block used by invoice, quotation and document
419
+ * HTML/PDF generators. Renders the same fields, in the same order, with
420
+ * the same conditional rendering so all document types look consistent.
421
+ */
422
+ interface RenderContactBoxInput {
423
+ /** Label shown above the box ("BILL TO", "FOR", "SUPPLIER", ...). */
424
+ label: string;
425
+ /** Primary name (company fullName preferred, fall back to display name). */
426
+ name: string;
427
+ /** Optional full legal name shown on its own line if different from `name`. */
428
+ fullName?: string | null;
429
+ /** VAT/Tax registration number. */
430
+ taxNumber?: string | null;
431
+ /** Company registration number. */
432
+ registrationNumber?: string | null;
433
+ /** Street address line. */
434
+ address?: string | null;
435
+ /** City/Town (may include village depending on caller). */
436
+ city?: string | null;
437
+ /** Postal/ZIP code. */
438
+ postalCode?: string | null;
439
+ /** Province/State. */
440
+ province?: string | null;
441
+ /** Primary phone. */
442
+ phone?: string | null;
443
+ /** Secondary phone. */
444
+ phone2?: string | null;
445
+ /** Email. */
446
+ email?: string | null;
447
+ /** Website URL. */
448
+ website?: string | null;
449
+ }
450
+ /**
451
+ * Returns the HTML for the shared contact block.
452
+ */
453
+ declare function renderContactBox(input: RenderContactBoxInput): string;
454
+
455
+ interface SectionContext {
456
+ logo: string;
457
+ cName: string;
458
+ cAddress: string;
459
+ cCity: string;
460
+ cCode: string;
461
+ cProv: string;
462
+ cVat: string;
463
+ cReg: string;
464
+ cPhone: string;
465
+ cPhone2: string;
466
+ cEmail: string;
467
+ cWeb: string;
468
+ cContact: string;
469
+ template: A4DocumentTemplate;
470
+ templateId: string;
471
+ docTitle: string;
472
+ docNumber: string;
473
+ barcodeDataUrl: string | null;
474
+ qrDataUrl: string | null;
475
+ settings: {
476
+ showBarcode: boolean;
477
+ showQRCode: boolean;
478
+ showWatermark: boolean;
479
+ showPhone: boolean;
480
+ showEmail: boolean;
481
+ showWebsite: boolean;
482
+ showTaxNumber: boolean;
483
+ showDescription?: boolean;
484
+ };
485
+ }
486
+ declare function renderHeaderSection(ctx: SectionContext): string;
487
+ declare function renderClassicHeader(ctx: SectionContext): string;
488
+
489
+ declare class InvoiceReportGenerator {
490
+ private static decimalToNumber;
491
+ private static formatMoney;
492
+ static generateInvoiceReportHTML(invoice: InvoiceDocumentData, companyInfo?: CompanyInfo | null, combineServices?: boolean, templateId?: string, docSettings?: DocumentTypeSettings): Promise<string>;
493
+ }
494
+ declare function generateInvoiceHTML(invoice: InvoiceDocumentData, options?: InvoiceReportGeneratorOptions & {
495
+ companyInfo?: CompanyInfo | null;
496
+ }): Promise<string>;
497
+
498
+ declare class QuotationReportGenerator {
499
+ private static decimalToNumber;
500
+ private static formatMoney;
501
+ static generateQuotationReportHTML(quotation: QuotationDocumentData, companyInfo?: CompanyInfo | null, optionsOrCombineServices?: boolean | QuotationReportGeneratorOptions, legacyTemplateId?: string, docSettings?: DocumentTypeSettings): Promise<string>;
502
+ }
503
+ declare function generateQuotationHTML(quotation: QuotationDocumentData, options?: QuotationReportGeneratorOptions & {
504
+ companyInfo?: CompanyInfo | null;
505
+ }): Promise<string>;
506
+
507
+ declare class ReceiptGenerator {
508
+ private companyInfo;
509
+ private readonly DEFAULT_TAX_RATE;
510
+ constructor(companyInfo?: ReceiptCompanyInfo | null);
511
+ setCompanyInfo(companyInfo: CompanyInfo | ReceiptCompanyInfo | null): void;
512
+ setTerminalLogo(logoUrl: string | undefined): void;
513
+ private formatNumber;
514
+ private formatDate;
515
+ private getItemName;
516
+ private getItemSKU;
517
+ generateReceiptHTML(saleData: any, size?: ReceiptSize, forPrint?: boolean): Promise<string>;
518
+ private generateA4ReceiptHTML;
519
+ private generateThermalReceiptHTML;
520
+ }
521
+ declare const receiptGenerator: ReceiptGenerator;
522
+
523
+ declare class DeliveryNoteGenerator {
524
+ static generateDeliveryNoteHTML(deliveryNote: DeliveryNoteDocumentData, companyInfo?: CompanyInfo | null, templateId?: string, docSettings?: DocumentTypeSettings): Promise<string>;
525
+ }
526
+ declare function generateDeliveryNoteHTML(deliveryNote: DeliveryNoteDocumentData, options?: DeliveryNoteGeneratorOptions & {
527
+ companyInfo?: CompanyInfo | null;
528
+ }): Promise<string>;
529
+
530
+ declare function escapeHtml(value: unknown): string;
531
+ declare function hasVisibleText(str: string | null | undefined): boolean;
532
+ declare function getClientDisplayName(client: ClientData | null | undefined): string;
533
+ declare function formatCurrency(amount: number | string | null | undefined, currency?: string): string;
534
+ declare function formatDate(date: Date | string | null | undefined): string;
535
+ declare function formatCompanyAddress(companyInfo: CompanyInfo | null | undefined): string;
536
+
537
+ /**
538
+ * Universal Code 128 vector SVG generator (zero canvas/DOM dependencies).
539
+ * Works reliably in Node.js, Next.js server components, browser, and serverless.
540
+ */
541
+ declare function generateCode128Svg(text: string, height?: number): string;
542
+ /**
543
+ * Generates a Code 128 barcode as an SVG Data URI.
544
+ */
545
+ declare function generateBarcode(value: string): Promise<string>;
546
+ /**
547
+ * Universal QR code generator producing an SVG Data URI.
548
+ * Works without canvas or DOM in both Node.js and browser environments.
549
+ */
550
+ declare function generateQRCode(value: string): Promise<string>;
551
+
552
+ declare const DEFAULT_TAX_RATE = 0.15;
553
+ declare const DEFAULT_DOCUMENT_TYPE_SETTINGS: DocumentTypeSettings;
554
+ declare function getDocumentTypeSettings(settings: Record<string, any> | undefined | null, docType: DocumentTypeKey): DocumentTypeSettings;
555
+ declare const DEFAULT_COMPANY_INFO: CompanyInfo;
556
+ declare const DEFAULT_RECEIPT_COMPANY_INFO: ReceiptCompanyInfo;
557
+
558
+ export { type A4DocumentTemplate, type A4DocumentTemplateId, A4_TEMPLATES, A4_TEMPLATE_IDS, type ClientData, type CombinedServiceData, type CompanyInfo, DEFAULT_A4_ID, DEFAULT_COMPANY_INFO, DEFAULT_DOCUMENT_TYPE_SETTINGS, DEFAULT_RECEIPT_COMPANY_INFO, DEFAULT_TAX_RATE, DEFAULT_THERMAL_ID, type DeliveryNoteDocumentData, DeliveryNoteGenerator, type DeliveryNoteGeneratorOptions, type DeliveryNoteItemData, type DocumentSettingsMap, type DocumentTypeKey, type DocumentTypeSettings, type InvoiceDocumentData, type InvoiceItemData, type InvoicePaymentData, type InvoiceProps, InvoiceReportGenerator, type InvoiceReportGeneratorOptions, type OrganizationDocumentSettings, type QuotationDocumentData, type QuotationItemData, QuotationReportGenerator, type QuotationReportGeneratorOptions, type QuotationWithRelations, type ReceiptCompanyInfo, type ReceiptData, ReceiptGenerator, type ReceiptSize, type RenderContactBoxInput, type SaleItem, type SectionContext, THERMAL_TEMPLATES, THERMAL_TEMPLATE_IDS, type ThermalDocumentTemplate, type ThermalDocumentTemplateId, escapeHtml, formatCompanyAddress, formatCurrency, formatDate, generateBarcode, generateCode128Svg, generateDeliveryNoteHTML, generateInvoiceHTML, generateQRCode, generateQuotationHTML, getA4Template, getClientDisplayName, getDocumentTypeSettings, getThermalTemplate, hasVisibleText, isA4TemplateId, isClassicTemplate, isThermalTemplateId, receiptGenerator, renderClassicHeader, renderContactBox, renderHeaderSection };