@dloizides/invoice-core 0.1.0 → 0.2.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.
- package/CHANGELOG.md +4 -0
- package/README.md +14 -1
- package/dist/index.d.mts +46 -1
- package/dist/index.d.ts +46 -1
- package/dist/index.js +175 -4
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +165 -5
- package/dist/index.mjs.map +1 -1
- package/package.json +2 -1
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/storage.ts","../src/types.ts","../src/folder.ts","../src/InvoiceKind.ts","../src/LayoutAlign.ts","../src/layouts.ts","../src/money.ts","../src/period.ts","../src/lines.ts","../src/numbering.ts","../src/rules.ts","../src/schema.ts","../src/validate.ts","../src/parties.ts","../src/view.ts","../src/pdfDefinition.ts","../src/pdf.ts","../src/issue.ts","../src/creditNote.ts","../src/exportCsv.ts","../src/memoryStorage.ts","../src/schedule.ts"],"names":["value","InvoiceKind","LayoutAlign","lines","required","totals","YEAR","vatCents","toBytes","SAFE_ID"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The data folder as the core sees it. Paths are relative, with forward slashes.\n * Browser and Node implementations live outside this package.\n */\nexport interface InvoiceStorage {\n /** Returns the file as text, or null if it does not exist. */\n readText(path: string): Promise<string | null>;\n /** Returns the file as bytes, or null if it does not exist. */\n readBytes(path: string): Promise<Uint8Array | null>;\n /** Returns the names of a folder's direct children; empty if it does not exist. */\n list(dir: string): Promise<string[]>;\n /** Creates a file and its parents; throws StorageExistsError if the file exists. */\n writeNew(path: string, data: string | Uint8Array): Promise<void>;\n /** Creates or overwrites a file; never used on an issued record. */\n replace(path: string, data: string | Uint8Array): Promise<void>;\n /** Deletes a file; does nothing if it does not exist. */\n remove(path: string): Promise<void>;\n /** Runs work while holding the named lock; other holders of that name wait. */\n withLock<T>(name: string, work: () => Promise<T>): Promise<T>;\n}\n\n/** Thrown by writeNew when the file already exists. */\nexport class StorageExistsError extends Error {\n constructor(path: string) {\n super(`already exists: ${path}`);\n this.name = 'StorageExistsError';\n }\n}\n","import type { InvoiceKind } from './InvoiceKind';\n\n/** One validation problem: a field path and what is wrong with it. */\nexport interface FieldError { path: string; message: string; }\n\n/** The issuing company, read from company.json in the data folder. */\nexport interface Company {\n name: string; addressLines: string[]; regNo: string; vatNumber: string;\n bank: string; iban: string; bic: string; logo?: string; template?: string; layout?: string;\n}\n\n/** A client, read from clients/<id>.json in the data folder. */\nexport interface Client {\n name: string; addressLines: string[]; taxLines: string[]; vatNumber: string;\n vatRule: string; paymentTermsDays: number | null; description: string; template?: string; layout?: string;\n}\n\n/** A VAT treatment, built in or read from a rule file. */\nexport interface VatRule {\n id: string; ratePercent: number; labelEn: string; labelEl: string;\n rateTextEn: string; rateTextEl: string; noteEn: string; noteEl: string; source: string;\n reviewedByAccountant?: boolean;\n}\n\n/** A line as entered: its own description and an amount such as 2952.50. */\nexport interface InvoiceLine { description: string; amount: string; }\n\n/** A line ready to print and total. */\nexport interface ResolvedLine { description: string; cents: number; }\n\n/** Totals in whole cents. */\nexport interface Totals { netCents: number; vatCents: number; totalCents: number; }\n\n/** The per-invoice request. Lines win over amounts, which use the client description. */\nexport interface InvoiceRequest {\n clientId: string; period: string; date: string; amounts: string[]; lines?: InvoiceLine[];\n template?: string; layout?: string; draft: boolean;\n}\n\n/** The three files an invoice is built from. */\nexport interface Parties { company: Company; client: Client; rule: VatRule; }\n\n/** Which schedule month an issued record came from. */\nexport interface ScheduleRef { id: string; period: string; }\n\n/** The immutable record of an issued invoice or credit note. */\nexport interface InvoiceRecord extends Parties {\n kind: InvoiceKind; number: string; request: InvoiceRequest; lines: ResolvedLine[]; totals: Totals;\n schedule?: ScheduleRef; creditFor?: string; reason?: string;\n}\n\n/** Where an issued record and its PDF were saved. */\nexport interface IssuedInvoice { number: string; pdfPath: string; recordPath: string; }\n\n/** Thrown for any refusal; errors name each field. */\nexport class InvoiceError extends Error {\n readonly errors: FieldError[];\n\n constructor(errors: FieldError[]) {\n super(errors.map((e) => `${e.path}: ${e.message}`).join('; '));\n this.name = 'InvoiceError';\n this.errors = errors;\n }\n}\n","import { StorageExistsError } from './storage';\nimport type { InvoiceStorage } from './storage';\nimport { InvoiceError } from './types';\n\nconst FORMAT_PATH = 'format.json';\nconst FORMAT_VERSION = 1;\nconst NUMBER_YEAR = /(\\d{4})-\\d+$/;\nconst LEGACY_YEAR = /^\\d{4}$/;\nconst LEGACY_FILE = /^(\\d{4}-\\d+)\\.(json|pdf)$/;\n\n/** Serialises a folder file the one way every writer does. */\nexport function toJson(value: unknown): string {\n return JSON.stringify(value, null, 2);\n}\n\n/** The year folder a number belongs to. */\nexport function numberYear(number: string): string {\n return NUMBER_YEAR.exec(number)?.[1] ?? '';\n}\n\n/** The folder of an issued invoice or credit note. */\nexport function invoiceDir(number: string): string {\n return `invoices/${numberYear(number)}/${number}`;\n}\n\n/** The path of an issued record. */\nexport function recordPath(number: string): string {\n return `${invoiceDir(number)}/invoice.json`;\n}\n\n/** The path of an issued PDF. */\nexport function pdfPath(number: string): string {\n return `${invoiceDir(number)}/${number}.pdf`;\n}\n\n/** Reads a JSON object, refusing a missing file or bad JSON under the given label. */\nexport async function readJsonFile<T>(storage: InvoiceStorage, path: string, label: string): Promise<T> {\n const text = await storage.readText(path);\n if (text === null) {\n throw new InvoiceError([{ path: label, message: `file not found: ${path}` }]);\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(text) as unknown;\n } catch {\n throw new InvoiceError([{ path: label, message: `invalid JSON: ${path}` }]);\n }\n if (typeof parsed !== 'object' || parsed === null) {\n throw new InvoiceError([{ path: label, message: `must be a JSON object: ${path}` }]);\n }\n return parsed as T;\n}\n\n/** Creates format.json in a new folder and refuses a folder newer than this code. */\nexport async function ensureFormat(storage: InvoiceStorage): Promise<void> {\n const text = await storage.readText(FORMAT_PATH);\n if (text === null) {\n await storage.writeNew(FORMAT_PATH, toJson({ version: FORMAT_VERSION })).catch((error: unknown) => {\n if (!(error instanceof StorageExistsError)) {\n throw error;\n }\n });\n return;\n }\n const { version } = await readJsonFile<{ version?: unknown }>(storage, FORMAT_PATH, 'format');\n if (typeof version !== 'number' || version > FORMAT_VERSION) {\n throw new InvoiceError([{ path: 'format', message: `folder format ${String(version)} is not supported; this code reads up to ${FORMAT_VERSION}` }]);\n }\n}\n\nasync function migrateNumber(storage: InvoiceStorage, year: string, number: string): Promise<boolean> {\n const oldRecord = await storage.readBytes(`${year}/${number}.json`);\n const oldPdf = await storage.readBytes(`${year}/${number}.pdf`);\n const taken = (await storage.readBytes(recordPath(number))) !== null || (await storage.readBytes(pdfPath(number))) !== null;\n if (taken) {\n return false;\n }\n if (oldRecord) {\n await storage.writeNew(recordPath(number), oldRecord);\n }\n if (oldPdf) {\n await storage.writeNew(pdfPath(number), oldPdf);\n }\n await storage.remove(`${year}/${number}.json`);\n await storage.remove(`${year}/${number}.pdf`);\n return true;\n}\n\n/** What a migration moved, and the numbers left in place because the target exists. */\nexport interface MigrationResult { moved: string[]; conflicts: string[]; }\n\n/** Moves <year>/<number>.json + .pdf to invoices/<year>/<number>/. Never overwrites. */\nexport async function migrateLegacyFolder(storage: InvoiceStorage): Promise<MigrationResult> {\n await ensureFormat(storage);\n const result: MigrationResult = { moved: [], conflicts: [] };\n const years = (await storage.list('')).filter((name) => LEGACY_YEAR.test(name));\n for (const year of years) {\n const names = await storage.list(year);\n const numbers = [...new Set(names.flatMap((name) => LEGACY_FILE.exec(name)?.[1] ?? []))].sort((a, b) => a.localeCompare(b));\n for (const number of numbers) {\n const moved = await migrateNumber(storage, year, number);\n (moved ? result.moved : result.conflicts).push(number);\n }\n }\n return result;\n}\n","/** Whether an issued record is an invoice or a credit note. */\nexport const enum InvoiceKind {\n Invoice = 'invoice',\n CreditNote = 'credit-note',\n}\n","/** Where a layout places the document title. */\nexport const enum LayoutAlign {\n Left = 'left',\n Right = 'right',\n}\n","import { LayoutAlign } from './LayoutAlign';\nimport type { InvoiceStorage } from './storage';\nimport { InvoiceError } from './types';\nimport type { FieldError, InvoiceRequest, Parties } from './types';\n\nconst SAFE_NAME = /^[\\w-]+$/;\nconst HEX_COLOUR = /^#[0-9a-fA-F]{6}$/;\nconst NUMBER_RANGES: Record<string, [number, number]> = { pageMargin: [10, 80], bodySize: [6, 14], titleSize: [10, 40], logoWidth: [20, 240] };\nconst COLOUR_KEYS = ['accent', 'muted', 'band'];\nconst ALLOWED_KEYS = new Set(['name', 'titleAlign', ...COLOUR_KEYS, ...Object.keys(NUMBER_RANGES)]);\n\n/** The name a request uses when neither it, the client nor the company picks a layout. */\nexport const DEFAULT_LAYOUT = 'classic';\n\n/** The look of a PDF: plain data only, so a layout cannot run anything. */\nexport interface InvoiceLayout {\n name: string; pageMargin: number; bodySize: number; titleSize: number; logoWidth: number;\n accent: string; muted: string; band: string; titleAlign: LayoutAlign;\n}\n\n/** The layouts every folder can use; a file in layouts/ overrides them by name. */\nexport const BUILT_IN_LAYOUTS = {\n classic: { name: 'classic', pageMargin: 40, bodySize: 9.5, titleSize: 22, logoWidth: 90, accent: '#1F3A5F', muted: '#666666', band: '#E4ECF5', titleAlign: LayoutAlign.Right },\n compact: { name: 'compact', pageMargin: 28, bodySize: 8.5, titleSize: 16, logoWidth: 60, accent: '#2F4F4F', muted: '#5F5F5F', band: '#E8EFEE', titleAlign: LayoutAlign.Left },\n} as const satisfies Record<string, InvoiceLayout>;\n\nconst BUILT_IN_BY_NAME: ReadonlyMap<string, InvoiceLayout> = new Map(Object.entries(BUILT_IN_LAYOUTS));\n\nfunction fieldErrors(data: Record<string, unknown>): FieldError[] {\n const errors: FieldError[] = Object.keys(data).filter((key) => !ALLOWED_KEYS.has(key)).map((key) => ({ path: `layout.${key}`, message: 'unknown field' }));\n if (typeof data.name !== 'string') {\n errors.push({ path: 'layout.name', message: 'must be text' });\n }\n if (data.titleAlign !== LayoutAlign.Left && data.titleAlign !== LayoutAlign.Right) {\n errors.push({ path: 'layout.titleAlign', message: 'must be left or right' });\n }\n COLOUR_KEYS.filter((key) => typeof data[key] !== 'string' || !HEX_COLOUR.test(data[key])).forEach((key) => errors.push({ path: `layout.${key}`, message: 'must be a colour like #1F3A5F' }));\n Object.entries(NUMBER_RANGES).forEach(([key, [min, max]]) => {\n const value = data[key];\n if (typeof value !== 'number' || !(value >= min && value <= max)) {\n errors.push({ path: `layout.${key}`, message: `must be a number from ${min} to ${max}` });\n }\n });\n return errors;\n}\n\n/** Checks a parsed layout file; refuses unknown fields and anything but plain values. */\nexport function parseLayout(raw: unknown): InvoiceLayout {\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n throw new InvoiceError([{ path: 'layout', message: 'must be a JSON object' }]);\n }\n const errors = fieldErrors(raw as Record<string, unknown>);\n if (errors.length > 0) {\n throw new InvoiceError(errors);\n }\n return raw as InvoiceLayout;\n}\n\nfunction parseLayoutText(text: string, name: string): InvoiceLayout {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text) as unknown;\n } catch {\n throw new InvoiceError([{ path: 'layout', message: `invalid JSON in layout \"${name}\"` }]);\n }\n return parseLayout(parsed);\n}\n\n/** Finds a layout in the data folder, then the built-in set; an unknown name is refused and named. */\nexport async function resolveLayout(storage: InvoiceStorage, name: string): Promise<InvoiceLayout> {\n const text = SAFE_NAME.test(name) ? await storage.readText(`layouts/${name}.json`) : null;\n if (text !== null) {\n return parseLayoutText(text, name);\n }\n const builtIn = BUILT_IN_BY_NAME.get(name);\n if (!builtIn) {\n throw new InvoiceError([{ path: 'layout', message: `unknown layout \"${name}\"` }]);\n }\n return builtIn;\n}\n\n/** The layout name in force: request, then client, then company, then the default. */\nexport function selectLayoutName(request: InvoiceRequest, parties: Parties): string {\n return request.layout ?? parties.client.layout ?? parties.company.layout ?? DEFAULT_LAYOUT;\n}\n","const CENTS_PER_UNIT = 100;\nconst GROUP_SIZE = 3;\nconst AMOUNT = /^\\d{1,12}(\\.\\d{1,2})?$/;\n\nfunction groupThousands(digits: string): string {\n const groups: string[] = [];\n for (let end = digits.length; end > 0; end -= GROUP_SIZE) {\n groups.unshift(digits.slice(Math.max(end - GROUP_SIZE, 0), end));\n }\n return groups.join('.');\n}\n\n/** Parses \"2952\" or \"2952.50\" into integer cents; returns null if malformed. */\nexport function toCents(amount: string): number | null {\n if (!AMOUNT.test(amount)) {\n return null;\n }\n const [whole, fraction = ''] = amount.split('.');\n return Number(whole) * CENTS_PER_UNIT + Number(fraction.padEnd(2, '0'));\n}\n\n/** Formats cents in Greek style: 295200 becomes \"2.952,00\". */\nexport function formatCents(cents: number): string {\n const whole = groupThousands(Math.floor(cents / CENTS_PER_UNIT).toString());\n return `${whole},${(cents % CENTS_PER_UNIT).toString().padStart(2, '0')}`;\n}\n\n/** Formats cents as a plain amount: -4000 becomes \"-40.00\". */\nexport function centsToAmount(cents: number): string {\n const size = Math.abs(cents);\n const text = `${Math.floor(size / CENTS_PER_UNIT)}.${(size % CENTS_PER_UNIT).toString().padStart(2, '0')}`;\n return cents < 0 ? `-${text}` : text;\n}\n\n/** Computes VAT in whole cents, rounded half up. */\nexport function vatCents(netCents: number, ratePercent: number): number {\n return Math.round((netCents * ratePercent) / CENTS_PER_UNIT);\n}\n","const MONTHS_EN = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];\nconst MONTHS_EL = ['Ιανουάριος', 'Φεβρουάριος', 'Μάρτιος', 'Απρίλιος', 'Μάιος', 'Ιούνιος', 'Ιούλιος', 'Αύγουστος', 'Σεπτέμβριος', 'Οκτώβριος', 'Νοέμβριος', 'Δεκέμβριος'];\nconst MONTHS_EL_ACCUSATIVE = ['Ιανουάριο', 'Φεβρουάριο', 'Μάρτιο', 'Απρίλιο', 'Μάιο', 'Ιούνιο', 'Ιούλιο', 'Αύγουστο', 'Σεπτέμβριο', 'Οκτώβριο', 'Νοέμβριο', 'Δεκέμβριο'];\n\n/** Period texts for a YYYY-MM period. */\nexport function periodTexts(period: string): { en: string; el: string; elAccusative: string } {\n const year = period.slice(0, 4);\n const i = Number(period.slice(5)) - 1;\n return {\n en: `${MONTHS_EN[i] ?? ''} ${year}`,\n el: `${MONTHS_EL[i] ?? ''} ${year}`,\n elAccusative: `${MONTHS_EL_ACCUSATIVE[i] ?? ''} ${year}`,\n };\n}\n\n/** Formats YYYY-MM-DD as DD/MM/YYYY. */\nexport function displayDate(iso: string): string {\n return iso.split('-').reverse().join('/');\n}\n\n/** Adds days to a YYYY-MM-DD date. */\nexport function addDays(iso: string, days: number): string {\n const date = new Date(`${iso}T00:00:00Z`);\n date.setUTCDate(date.getUTCDate() + days);\n return date.toISOString().slice(0, 10);\n}\n","import { toCents, vatCents } from './money';\nimport { periodTexts } from './period';\nimport type { Client, InvoiceRequest, ResolvedLine, Totals } from './types';\n\n/** Fills {periodElAccusative} and {periodEn} in a client description. */\nexport function expandDescription(description: string, period: string): string {\n const texts = periodTexts(period);\n return description.split('{periodElAccusative}').join(texts.elAccusative).split('{periodEn}').join(texts.en);\n}\n\n/** Turns a request into printable lines: its own lines, else amounts with the client description. */\nexport function resolveLines(request: InvoiceRequest, client: Client): ResolvedLine[] {\n if (request.lines && request.lines.length > 0) {\n return request.lines.map((line) => ({ description: line.description, cents: toCents(line.amount) ?? 0 }));\n }\n const description = expandDescription(client.description, request.period);\n return request.amounts.map((amount) => ({ description, cents: toCents(amount) ?? 0 }));\n}\n\n/** Sums lines in whole cents and adds VAT at the given rate. */\nexport function computeTotals(lines: ResolvedLine[], ratePercent: number): Totals {\n const netCents = lines.reduce((sum, line) => sum + line.cents, 0);\n const vat = vatCents(netCents, ratePercent);\n return { netCents, vatCents: vat, totalCents: netCents + vat };\n}\n","import { recordPath, toJson } from './folder';\nimport { InvoiceKind } from './InvoiceKind';\nimport { StorageExistsError } from './storage';\nimport type { InvoiceStorage } from './storage';\nimport { InvoiceError } from './types';\nimport type { InvoiceRecord } from './types';\n\nconst PAD = 3;\nconst YEAR = /^\\d{4}$/;\nconst CREDIT_PREFIX = 'CN-';\n\nfunction highest(names: string[], pattern: RegExp): number {\n return names.reduce((max, name) => Math.max(max, Number(pattern.exec(name)?.[1] ?? 0)), 0);\n}\n\n/** Returns the next gap-free number for a year, such as 2030-002 or CN-2030-001. */\nexport async function nextNumber(storage: InvoiceStorage, year: string, kind: InvoiceKind = InvoiceKind.Invoice): Promise<string> {\n if (!YEAR.test(year)) {\n throw new InvoiceError([{ path: 'year', message: 'must be YYYY' }]);\n }\n const prefix = kind === InvoiceKind.CreditNote ? CREDIT_PREFIX : '';\n const current = highest(await storage.list(`invoices/${year}`), new RegExp(`^${prefix}${year}-(\\\\d+)$`));\n const legacy = prefix === '' ? highest(await storage.list(year), new RegExp(`^${year}-(\\\\d+)\\\\.(?:json|pdf)$`)) : 0;\n return `${prefix}${year}-${String(Math.max(current, legacy) + 1).padStart(PAD, '0')}`;\n}\n\n/** Writes the record, refusing if that number was already issued. Issued records are never replaced. */\nexport async function claimInvoice(storage: InvoiceStorage, record: InvoiceRecord): Promise<string> {\n const path = recordPath(record.number);\n try {\n await storage.writeNew(path, toJson(record));\n } catch (error) {\n const message = error instanceof StorageExistsError ? `${record.number} is already issued` : `could not save ${record.number}: ${(error as Error).message}`;\n throw new InvoiceError([{ path: 'number', message }]);\n }\n return path;\n}\n","import type { VatRule } from './types';\n\nconst CY_DOMESTIC_19: VatRule = {\n id: 'cy-domestic-19',\n ratePercent: 19,\n labelEn: 'VAT',\n labelEl: 'ΦΠΑ',\n rateTextEn: '19%',\n rateTextEl: '19%',\n noteEn: '',\n noteEl: '',\n source: 'Cyprus VAT Law 95(I)/2000, standard rate',\n reviewedByAccountant: false,\n};\n\nconst CY_TO_EU_B2B_SERVICES: VatRule = {\n id: 'cy-to-eu-b2b-services',\n ratePercent: 0,\n labelEn: 'VAT',\n labelEl: 'ΦΠΑ',\n rateTextEn: 'Reverse charge',\n rateTextEl: 'Αντίστροφη επιβάρυνση',\n noteEn: 'Reverse charge: VAT is payable by the recipient, Art. 196 Directive 2006/112/EC.',\n noteEl: 'Αντίστροφη επιβάρυνση: ο ΦΠΑ οφείλεται από τον λήπτη, άρθρο 196 Οδηγίας 2006/112/ΕΚ.',\n source: 'Directive 2006/112/EC Art. 44, 196, 226(11a)',\n reviewedByAccountant: false,\n};\n\n/** The built-in VAT rules by id; a rule file in the data folder overrides them. Not tax advice. */\nexport const BUILT_IN_RULES: ReadonlyMap<string, VatRule> = new Map([\n [CY_DOMESTIC_19.id, CY_DOMESTIC_19],\n [CY_TO_EU_B2B_SERVICES.id, CY_TO_EU_B2B_SERVICES],\n]);\n","import type { FieldError } from './types';\n\nconst MAX_RATE = 100;\n\nfunction strings(prefix: string, data: Record<string, unknown>, keys: string[]): FieldError[] {\n return keys\n .filter((key) => data[key] !== undefined && typeof data[key] !== 'string')\n .map((key) => ({ path: `${prefix}.${key}`, message: 'must be text' }));\n}\n\nfunction required(prefix: string, data: Record<string, unknown>, keys: string[]): FieldError[] {\n return keys\n .filter((key) => typeof data[key] !== 'string')\n .map((key) => ({ path: `${prefix}.${key}`, message: 'must be text' }));\n}\n\nfunction isTextList(value: unknown): boolean {\n return Array.isArray(value) && value.every((line) => typeof line === 'string');\n}\n\nfunction lines(prefix: string, data: Record<string, unknown>, keys: string[]): FieldError[] {\n return keys\n .filter((key) => !isTextList(data[key]))\n .map((key) => ({ path: `${prefix}.${key}`, message: 'must be a list of text lines' }));\n}\n\n/** Checks the shape of company.json. */\nexport function companyShape(company: object): FieldError[] {\n const data = company as Record<string, unknown>;\n return [\n ...required('company', data, ['name', 'regNo', 'vatNumber', 'bank', 'iban', 'bic']),\n ...strings('company', data, ['logo', 'template', 'layout']),\n ...lines('company', data, ['addressLines']),\n ];\n}\n\n/** Checks the shape of a client file. */\nexport function clientShape(client: object): FieldError[] {\n const data = client as Record<string, unknown>;\n const days = data.paymentTermsDays;\n const badDays = days !== null && (!Number.isInteger(days) || (days as number) < 0);\n return [\n ...required('client', data, ['name', 'vatNumber', 'vatRule', 'description']),\n ...strings('client', data, ['template', 'layout']),\n ...lines('client', data, ['addressLines', 'taxLines']),\n ...(badDays ? [{ path: 'client.paymentTermsDays', message: 'must be null or a whole number of days, 0 or more' }] : []),\n ];\n}\n\n/** Checks the shape of a VAT rule file. */\nexport function ruleShape(rule: object): FieldError[] {\n const data = rule as Record<string, unknown>;\n const rate = data.ratePercent;\n const badRate = typeof rate !== 'number' || !Number.isFinite(rate) || rate < 0 || rate > MAX_RATE;\n return [\n ...required('rule', data, ['labelEn', 'labelEl', 'rateTextEn', 'rateTextEl', 'noteEn', 'noteEl']),\n ...(badRate ? [{ path: 'rule.ratePercent', message: 'must be a number from 0 to 100' }] : []),\n ];\n}\n","import { toCents } from './money';\nimport type { Client, Company, FieldError, InvoiceLine, InvoiceRequest } from './types';\n\nconst PERIOD = /^\\d{4}-(0[1-9]|1[0-2])$/;\nconst DATE = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n/** True for an empty value or a placeholder such as CY[____]. */\nexport function isBlank(value: unknown): boolean {\n if (value === undefined || value === null) {\n return true;\n }\n const text = String(value);\n return text.trim() === '' || text.includes('__');\n}\n\n/** True for a real calendar date written as YYYY-MM-DD. */\nexport function isRealDate(date: string): boolean {\n if (!DATE.test(date)) {\n return false;\n }\n const parsed = new Date(`${date}T00:00:00Z`);\n return !Number.isNaN(parsed.getTime()) && parsed.toISOString().slice(0, 10) === date;\n}\n\nfunction amountErrors(amount: string, path: string): FieldError[] {\n const cents = toCents(amount);\n if (cents === null) {\n return [{ path, message: 'must look like 2952 or 2952.50' }];\n }\n return cents === 0 ? [{ path, message: 'must be more than zero' }] : [];\n}\n\n/** Checks each line's amount; a description may stay blank until final. */\nexport function validateLines(lines: InvoiceLine[]): FieldError[] {\n return lines.flatMap((line, i) => amountErrors(line.amount, `lines[${i}].amount`));\n}\n\n/** Checks the request shape; these errors apply to drafts too. */\nexport function validateRequest(req: InvoiceRequest): FieldError[] {\n const errors: FieldError[] = [];\n const lines = req.lines ?? [];\n if (!PERIOD.test(req.period)) {\n errors.push({ path: 'period', message: 'must be YYYY-MM' });\n }\n if (!isRealDate(req.date)) {\n errors.push({ path: 'date', message: 'must be a real date as YYYY-MM-DD' });\n }\n if (req.amounts.length === 0 && lines.length === 0) {\n errors.push({ path: 'amounts', message: 'at least one amount is required' });\n }\n req.amounts.forEach((amount, i) => errors.push(...amountErrors(amount, `amounts[${i}]`)));\n errors.push(...validateLines(lines));\n return errors;\n}\n\n/** Lists required fields still blank; a final invoice is refused if any are. */\nexport function missingForFinal(company: Company, client: Client, lines: InvoiceLine[] = []): FieldError[] {\n const required: [string, unknown][] = [\n ['company.name', company.name], ['company.addressLines', company.addressLines?.join('')],\n ['company.regNo', company.regNo], ['company.vatNumber', company.vatNumber],\n ['company.bank', company.bank], ['company.iban', company.iban], ['company.bic', company.bic],\n ['client.name', client.name], ['client.addressLines', client.addressLines?.join('')],\n ['client.vatNumber', client.vatNumber], ['client.paymentTermsDays', client.paymentTermsDays],\n ...(lines.length === 0 ? [['client.description', client.description] as [string, unknown]] : []),\n ...lines.map((line, i): [string, unknown] => [`lines[${i}].description`, line.description]),\n ];\n const errors = required.filter(([, value]) => isBlank(value)).map(([path]) => ({ path, message: 'required for a final invoice' }));\n const vatShown = isBlank(client.vatNumber) || client.taxLines.some((line) => line.includes(client.vatNumber));\n return vatShown ? errors : [...errors, { path: 'client.taxLines', message: 'must show the client VAT number' }];\n}\n","import { readJsonFile } from './folder';\nimport { BUILT_IN_RULES } from './rules';\nimport { clientShape, companyShape, ruleShape } from './schema';\nimport type { InvoiceStorage } from './storage';\nimport { InvoiceError } from './types';\nimport type { Client, Company, InvoiceRequest, Parties, VatRule } from './types';\nimport { missingForFinal, validateRequest } from './validate';\n\nconst SAFE_ID = /^[\\w-]+$/;\n\nasync function loadRule(storage: InvoiceStorage, id: string): Promise<VatRule> {\n const safe = SAFE_ID.test(id);\n if (safe && (await storage.readText(`rules/${id}.json`)) !== null) {\n return readJsonFile<VatRule>(storage, `rules/${id}.json`, 'rule');\n }\n const builtIn = BUILT_IN_RULES.get(id);\n if (!builtIn) {\n throw new InvoiceError([{ path: 'client.vatRule', message: `unknown VAT rule \"${id}\"` }]);\n }\n return builtIn;\n}\n\n/** Reads the request's company, client and VAT rule, refusing if any is missing. */\nexport async function loadParties(storage: InvoiceStorage, clientId: string): Promise<Parties> {\n if (!SAFE_ID.test(clientId)) {\n throw new InvoiceError([{ path: 'clientId', message: 'must hold only letters, digits, - and _' }]);\n }\n const company = await readJsonFile<Company>(storage, 'company.json', 'company');\n const client = await readJsonFile<Client>(storage, `clients/${clientId}.json`, 'client');\n return { company, client, rule: await loadRule(storage, client.vatRule) };\n}\n\n/** Checks a request and returns its parties; final mode also refuses blank required fields. */\nexport async function checkRequest(storage: InvoiceStorage, request: InvoiceRequest): Promise<Parties> {\n const errors = validateRequest(request);\n if (errors.length > 0) {\n throw new InvoiceError(errors);\n }\n const parties = await loadParties(storage, request.clientId);\n const shape = [...companyShape(parties.company), ...clientShape(parties.client), ...ruleShape(parties.rule)];\n if (shape.length > 0) {\n throw new InvoiceError(shape);\n }\n const missing = request.draft ? [] : missingForFinal(parties.company, parties.client, request.lines);\n if (missing.length > 0) {\n throw new InvoiceError(missing);\n }\n return parties;\n}\n","import { InvoiceKind } from './InvoiceKind';\nimport { computeTotals, resolveLines } from './lines';\nimport { formatCents } from './money';\nimport { addDays, displayDate, periodTexts } from './period';\nimport type { InvoiceRequest, Parties, ResolvedLine } from './types';\nimport { isBlank } from './validate';\n\n/** What a blank required field prints as on a draft. */\nexport const BLANK_MARK = '[________]';\n\nconst DRAFT_NUMBER = 'DRAFT';\n\n/** What a renderer receives. A null number means a draft. */\nexport interface RenderInput {\n request: InvoiceRequest; number: string | null; parties: Parties;\n lines?: ResolvedLine[]; kind?: InvoiceKind; creditFor?: string; reason?: string;\n}\n\n/** Everything a PDF prints, already formatted. */\nexport interface InvoiceView {\n draft: boolean; creditNote: boolean; number: string; date: string; dueDate: string; periodEn: string; periodEl: string;\n company: { name: string; addressLines: string[]; regNo: string; vatNumber: string; bank: string; iban: string; bic: string };\n client: { name: string; addressLines: string[]; taxLines: string[] };\n rows: { description: string; amount: string }[];\n net: string; vat: string; total: string; vatLabel: string; noteEn: string; noteEl: string;\n creditFor?: string; reason?: string;\n}\n\nfunction shown(value: unknown): string {\n return isBlank(value) ? BLANK_MARK : String(value);\n}\n\n/** Formats a request into what the PDF prints. */\nexport function buildInvoiceView(input: RenderInput): InvoiceView {\n const { request, number, parties: { company, client, rule } } = input;\n const lines = input.lines ?? resolveLines(request, client);\n const totals = computeTotals(lines, rule.ratePercent);\n const period = periodTexts(request.period);\n return {\n draft: number === null,\n creditNote: input.kind === InvoiceKind.CreditNote,\n number: number ?? DRAFT_NUMBER,\n date: displayDate(request.date),\n dueDate: typeof client.paymentTermsDays === 'number' ? displayDate(addDays(request.date, client.paymentTermsDays)) : BLANK_MARK,\n periodEn: period.en,\n periodEl: period.el,\n company: {\n name: shown(company.name), addressLines: company.addressLines, regNo: shown(company.regNo), vatNumber: shown(company.vatNumber),\n bank: shown(company.bank), iban: shown(company.iban), bic: shown(company.bic),\n },\n client: { name: shown(client.name), addressLines: client.addressLines, taxLines: client.taxLines },\n rows: lines.map((line) => ({ description: shown(line.description), amount: formatCents(line.cents) })),\n net: formatCents(totals.netCents),\n vat: formatCents(totals.vatCents),\n total: formatCents(totals.totalCents),\n vatLabel: `${rule.labelEn} / ${rule.labelEl} (${rule.rateTextEn} / ${rule.rateTextEl})`,\n noteEn: rule.noteEn,\n noteEl: rule.noteEl,\n creditFor: input.creditFor,\n reason: input.reason,\n };\n}\n","import type { InvoiceLayout } from './layouts';\nimport { BLANK_MARK } from './view';\nimport type { InvoiceView } from './view';\n\nconst WHITE = '#FFFFFF';\nconst BLANK_BACKGROUND = '#FFF2B3';\nconst WATERMARK_COLOUR = '#A00000';\nconst WATERMARK_OPACITY = 0.13;\nconst FOOT_SIZE_DROP = 1.5;\nconst COMPANY_SIZE_GAIN = 3;\nconst GRAND_SIZE_GAIN = 1;\nconst SECTION_GAP = 14;\nconst PAGE_SIZE = 'A4';\n\ntype PdfNode = Record<string, unknown>;\n\n/** The logo a PDF shows: an image data URL or SVG text. */\nexport type PdfLogo = { image: string } | { svg: string };\n\nfunction value(text: string): PdfNode {\n return text === BLANK_MARK ? { text, background: BLANK_BACKGROUND } : { text };\n}\n\nfunction labelled(label: string, text: string): PdfNode {\n return { text: [`${label}: `, value(text)] };\n}\n\nfunction titleBlock(view: InvoiceView, layout: InvoiceLayout): PdfNode {\n const [en, el] = view.creditNote ? ['CREDIT NOTE', 'ΠΙΣΤΩΤΙΚΟ ΣΗΜΕΙΩΜΑ'] : ['INVOICE', 'ΤΙΜΟΛΟΓΙΟ'];\n return {\n width: 'auto',\n alignment: layout.titleAlign,\n color: layout.accent,\n bold: true,\n stack: [{ text: en, fontSize: layout.titleSize }, { text: el, fontSize: layout.bodySize + GRAND_SIZE_GAIN }],\n };\n}\n\nfunction header(view: InvoiceView, layout: InvoiceLayout, logo?: PdfLogo): PdfNode {\n const company = {\n width: '*',\n stack: [\n ...(logo ? [{ ...logo, width: layout.logoWidth, margin: [0, 0, 0, 6] }] : []),\n { ...value(view.company.name), bold: true, fontSize: layout.bodySize + COMPANY_SIZE_GAIN, color: layout.accent },\n ...view.company.addressLines,\n labelled('Reg. No. / Αρ. Εγγραφής', view.company.regNo),\n labelled('VAT No. / Αρ. ΦΠΑ', view.company.vatNumber),\n ],\n };\n return { columns: [company, titleBlock(view, layout)], margin: [0, 0, 0, SECTION_GAP] };\n}\n\nfunction meta(view: InvoiceView, layout: InvoiceLayout): PdfNode {\n const billTo = {\n width: '*',\n stack: [\n { text: 'BILL TO / ΠΕΛΑΤΗΣ', bold: true, color: layout.accent },\n { ...value(view.client.name), bold: true },\n ...view.client.addressLines,\n ...view.client.taxLines,\n ],\n };\n const numberLabel = view.creditNote ? 'Credit Note No. / Αρ. Πιστωτικού' : 'Invoice No. / Αρ. Τιμολογίου';\n const details = {\n width: 'auto',\n stack: [\n labelled(numberLabel, view.number),\n ...(view.creditFor ? [labelled('Credits invoice / Πιστώνει το τιμολόγιο', view.creditFor)] : []),\n labelled('Date / Ημερομηνία', view.date),\n labelled('Period / Περίοδος', `${view.periodEn} / ${view.periodEl}`),\n labelled('Currency / Νόμισμα', 'EUR (€)'),\n ],\n };\n return { columns: [billTo, details], margin: [0, 0, 0, SECTION_GAP] };\n}\n\nfunction items(view: InvoiceView, layout: InvoiceLayout): PdfNode {\n const head = [\n { text: 'DESCRIPTION / ΠΕΡΙΓΡΑΦΗ', bold: true, color: WHITE, fillColor: layout.accent },\n { text: 'AMOUNT / ΠΟΣΟ (€)', bold: true, color: WHITE, fillColor: layout.accent, alignment: 'right' },\n ];\n const rows = view.rows.map((row) => [value(row.description), { text: row.amount, alignment: 'right' }]);\n return { table: { headerRows: 1, widths: ['*', 'auto'], body: [head, ...rows] }, layout: 'lightHorizontalLines', margin: [0, 0, 0, SECTION_GAP] };\n}\n\nfunction totals(view: InvoiceView, layout: InvoiceLayout): PdfNode {\n const grand = { bold: true, color: layout.accent, fillColor: layout.band, fontSize: layout.bodySize + GRAND_SIZE_GAIN };\n const grandLabel = view.creditNote ? 'TOTAL CREDIT / ΣΥΝΟΛΟ ΠΙΣΤΩΣΗΣ' : 'TOTAL DUE / ΣΥΝΟΛΟ ΠΛΗΡΩΤΕΟ';\n const body = [\n ['Net Amount / Καθαρή Αξία', { text: view.net, alignment: 'right' }],\n [view.vatLabel, { text: view.vat, alignment: 'right' }],\n [{ text: grandLabel, ...grand }, { text: `€ ${view.total}`, alignment: 'right', ...grand }],\n ];\n return { table: { widths: ['*', 'auto'], body }, layout: 'noBorders', margin: [0, 0, 0, SECTION_GAP] };\n}\n\nfunction payment(view: InvoiceView, layout: InvoiceLayout): PdfNode[] {\n if (view.creditNote) {\n return view.reason ? [labelled('Reason / Αιτιολογία', view.reason)] : [];\n }\n const rows = [\n ['Bank / Τράπεζα', view.company.bank], ['IBAN', view.company.iban], ['BIC / SWIFT', view.company.bic],\n ['Due date / Ημ. Πληρωμής', view.dueDate], ['Reference / Αιτιολογία', view.number],\n ];\n return [\n { text: 'PAYMENT DETAILS / ΣΤΟΙΧΕΙΑ ΠΛΗΡΩΜΗΣ', bold: true, color: layout.accent },\n { table: { widths: ['auto', '*'], body: rows.map(([label = '', text = '']) => [{ text: label, color: layout.muted }, value(text)]) }, layout: 'noBorders' },\n ];\n}\n\nfunction note(view: InvoiceView, layout: InvoiceLayout): PdfNode[] {\n return view.noteEn === '' && view.noteEl === '' ? [] : [{ stack: [view.noteEn, view.noteEl], color: layout.muted, margin: [0, 0, 0, SECTION_GAP] }];\n}\n\n/** Builds the pdfmake document from plain view data and a layout. */\nexport function buildPdfDefinition(view: InvoiceView, layout: InvoiceLayout, logo?: PdfLogo): PdfNode {\n const foot = `${view.company.name} · Reg. No. ${view.company.regNo} · ${view.company.addressLines.join(', ')}`;\n return {\n pageSize: PAGE_SIZE,\n pageMargins: layout.pageMargin,\n defaultStyle: { fontSize: layout.bodySize },\n ...(view.draft ? { watermark: { text: 'DRAFT', color: WATERMARK_COLOUR, opacity: WATERMARK_OPACITY, bold: true } } : {}),\n footer: { text: foot, alignment: 'center', color: layout.muted, fontSize: layout.bodySize - FOOT_SIZE_DROP },\n content: [header(view, layout, logo), meta(view, layout), items(view, layout), totals(view, layout), ...note(view, layout), ...payment(view, layout)],\n };\n}\n","import { resolveLayout, selectLayoutName } from './layouts';\nimport { buildPdfDefinition } from './pdfDefinition';\nimport type { PdfLogo } from './pdfDefinition';\nimport type { InvoiceStorage } from './storage';\nimport { InvoiceError } from './types';\nimport { buildInvoiceView } from './view';\nimport type { RenderInput } from './view';\n\nconst IMAGE_TYPES: Record<string, string> = { png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg' };\nconst BASE64_CHUNK = 32768;\n\ninterface PdfDocument { getBuffer(callback: (bytes: Uint8Array) => void): void; }\ninterface PdfMake { createPdf(definition: object, layouts?: unknown, fonts?: unknown, vfs?: unknown): PdfDocument; }\ninterface FontModule { vfs?: unknown; pdfMake?: { vfs?: unknown }; }\n\nfunction unwrap<T>(module: { default?: T } & T): T {\n return module.default ?? module;\n}\n\nasync function loadPdfMake(): Promise<{ pdfMake: PdfMake; vfs: unknown }> {\n const [pdfModule, fontModule] = await Promise.all([\n import('pdfmake/build/pdfmake.js') as Promise<{ default?: PdfMake } & PdfMake>,\n import('pdfmake/build/vfs_fonts.js') as Promise<{ default?: FontModule } & FontModule>,\n ]);\n const fonts = unwrap<FontModule>(fontModule);\n return { pdfMake: unwrap<PdfMake>(pdfModule), vfs: fonts.pdfMake?.vfs ?? fonts.vfs ?? fonts };\n}\n\nfunction toBase64(bytes: Uint8Array): string {\n let binary = '';\n for (let start = 0; start < bytes.length; start += BASE64_CHUNK) {\n binary += String.fromCharCode(...bytes.subarray(start, start + BASE64_CHUNK));\n }\n return btoa(binary);\n}\n\n/** Reads the company logo for a PDF; PNG, JPG or SVG, refusing anything else or a missing file. */\nexport async function loadLogo(storage: InvoiceStorage, logo?: string): Promise<PdfLogo | undefined> {\n if (!logo) {\n return undefined;\n }\n const extension = logo.split('.').pop()?.toLowerCase() ?? '';\n const type = IMAGE_TYPES[extension];\n if (!type && extension !== 'svg') {\n throw new InvoiceError([{ path: 'company.logo', message: 'must be PNG, JPG or SVG' }]);\n }\n const bytes = await storage.readBytes(logo);\n if (!bytes) {\n throw new InvoiceError([{ path: 'company.logo', message: `file not found: ${logo}` }]);\n }\n return type ? { image: `data:${type};base64,${toBase64(bytes)}` } : { svg: new TextDecoder().decode(bytes) };\n}\n\nfunction toBytes(pdfMake: PdfMake, definition: object, vfs: unknown): Promise<Uint8Array> {\n return new Promise((resolve, reject) => {\n try {\n pdfMake.createPdf(definition, undefined, undefined, vfs).getBuffer((bytes) => resolve(new Uint8Array(bytes)));\n } catch (error) {\n reject(error instanceof Error ? error : new Error(String(error)));\n }\n });\n}\n\n/** Renders an invoice or credit note to PDF bytes with selectable Greek text. Works in browsers and Node. */\nexport async function renderInvoicePdf(storage: InvoiceStorage, input: RenderInput): Promise<Uint8Array> {\n const layout = await resolveLayout(storage, selectLayoutName(input.request, input.parties));\n const logo = await loadLogo(storage, input.parties.company.logo);\n const { pdfMake, vfs } = await loadPdfMake();\n return toBytes(pdfMake, buildPdfDefinition(buildInvoiceView(input), layout, logo), vfs);\n}\n","import { ensureFormat, numberYear, pdfPath, readJsonFile, recordPath } from './folder';\nimport { InvoiceKind } from './InvoiceKind';\nimport { resolveLayout, selectLayoutName } from './layouts';\nimport { computeTotals, resolveLines } from './lines';\nimport { claimInvoice, nextNumber } from './numbering';\nimport { checkRequest } from './parties';\nimport { renderInvoicePdf } from './pdf';\nimport type { InvoiceStorage } from './storage';\nimport { InvoiceError } from './types';\nimport type { InvoiceRecord, InvoiceRequest, IssuedInvoice, ScheduleRef } from './types';\nimport type { RenderInput } from './view';\n\nconst NUMBER_SHAPE = /^(CN-)?\\d{4}-\\d+$/;\n\n/** The lock every number claim holds, so two tabs never take one number. */\nexport const NUMBER_LOCK = 'invoice-number';\n\n/** Renders PDF bytes; the default is renderInvoicePdf. */\nexport type PdfRender = (input: RenderInput) => Promise<Uint8Array>;\n\n/** Options for issuing; schedule marks which schedule month this came from. */\nexport interface IssueOptions { render?: PdfRender; schedule?: ScheduleRef; }\n\n/** The renderer in force for these options. */\nexport function rendererFor(storage: InvoiceStorage, options: IssueOptions): PdfRender {\n return options.render ?? ((input): Promise<Uint8Array> => renderInvoicePdf(storage, input));\n}\n\n/** Saves the record first, then its PDF; a failed PDF leaves a record that reprintInvoice can finish. */\nexport async function commitRecord(storage: InvoiceStorage, record: InvoiceRecord, pdf: Uint8Array): Promise<IssuedInvoice> {\n const savedRecord = await claimInvoice(storage, record);\n const savedPdf = pdfPath(record.number);\n try {\n await storage.writeNew(savedPdf, pdf);\n } catch {\n throw new InvoiceError([{ path: 'number', message: `${record.number} is issued but its PDF could not be saved; run: reprint --number ${record.number}` }]);\n }\n return { number: record.number, pdfPath: savedPdf, recordPath: savedRecord };\n}\n\n/** Issues a final invoice: renders first, then claims the number, so a failed render uses none. */\nexport async function issueInvoice(storage: InvoiceStorage, request: InvoiceRequest, options: IssueOptions = {}): Promise<IssuedInvoice> {\n const final = { ...request, draft: false };\n const parties = await checkRequest(storage, final);\n await resolveLayout(storage, selectLayoutName(final, parties));\n await ensureFormat(storage);\n const render = rendererFor(storage, options);\n return storage.withLock(NUMBER_LOCK, async () => {\n const number = await nextNumber(storage, final.date.slice(0, 4));\n const lines = resolveLines(final, parties.client);\n const pdf = await render({ request: final, number, parties, lines });\n const totals = computeTotals(lines, parties.rule.ratePercent);\n const record: InvoiceRecord = { kind: InvoiceKind.Invoice, number, request: final, ...parties, lines, totals, ...(options.schedule ? { schedule: options.schedule } : {}) };\n return commitRecord(storage, record, pdf);\n });\n}\n\n/** Renders a draft PDF that takes no number. */\nexport async function renderDraftPdf(storage: InvoiceStorage, request: InvoiceRequest, options: IssueOptions = {}): Promise<Uint8Array> {\n const draft = { ...request, draft: true };\n const parties = await checkRequest(storage, draft);\n return rendererFor(storage, options)({ request: draft, number: null, parties });\n}\n\nfunction completeRecord(raw: Partial<InvoiceRecord> & Pick<InvoiceRecord, 'number' | 'request' | 'company' | 'client' | 'rule'>): InvoiceRecord {\n const lines = raw.lines ?? resolveLines(raw.request, raw.client);\n return { ...raw, kind: raw.kind ?? InvoiceKind.Invoice, lines, totals: raw.totals ?? computeTotals(lines, raw.rule.ratePercent) };\n}\n\n/** Reads an issued record; a record from the old layout's shape gets its kind, lines and totals. */\nexport async function readInvoice(storage: InvoiceStorage, number: string): Promise<InvoiceRecord> {\n if (!NUMBER_SHAPE.test(number)) {\n throw new InvoiceError([{ path: 'invoiceNumber', message: 'must look like 2030-001 or CN-2030-001' }]);\n }\n return completeRecord(await readJsonFile<InvoiceRecord>(storage, recordPath(number), 'invoiceNumber'));\n}\n\n/** Lists a year's issued invoices and credit notes; folders with no record are skipped. */\nexport async function listIssued(storage: InvoiceStorage, year: string): Promise<InvoiceRecord[]> {\n const names = (await storage.list(`invoices/${year}`)).filter((name) => NUMBER_SHAPE.test(name) && numberYear(name) === year);\n const present = await Promise.all(names.map(async (name) => ((await storage.readText(recordPath(name))) === null ? null : name)));\n return Promise.all(present.flatMap((name) => name ?? []).map((name) => readInvoice(storage, name)));\n}\n\n/** Recreates the missing PDF of an issued record; never replaces an existing PDF. */\nexport async function reprintInvoice(storage: InvoiceStorage, number: string, options: IssueOptions = {}): Promise<{ number: string; pdfPath: string }> {\n const record = await readInvoice(storage, number);\n const path = pdfPath(number);\n if ((await storage.readBytes(path)) !== null) {\n throw new InvoiceError([{ path: 'number', message: `${number} already has a PDF` }]);\n }\n const { company, client, rule } = record;\n const pdf = await rendererFor(storage, options)({\n request: record.request, number, parties: { company, client, rule }, lines: record.lines, kind: record.kind, creditFor: record.creditFor, reason: record.reason,\n });\n await storage.writeNew(path, pdf);\n return { number, pdfPath: path };\n}\n","import { ensureFormat, numberYear } from './folder';\nimport { InvoiceKind } from './InvoiceKind';\nimport { commitRecord, listIssued, NUMBER_LOCK, readInvoice, rendererFor } from './issue';\nimport type { IssueOptions } from './issue';\nimport { computeTotals } from './lines';\nimport { centsToAmount, toCents } from './money';\nimport { nextNumber } from './numbering';\nimport type { InvoiceStorage } from './storage';\nimport { InvoiceError } from './types';\nimport type { InvoiceRecord, IssuedInvoice } from './types';\nimport { isBlank, isRealDate } from './validate';\n\n/** What to credit. Without an amount the credit note covers all the invoice has left. */\nexport interface CreditNoteRequest { invoiceNumber: string; date: string; reason: string; amount?: string; }\n\nfunction checkInput(input: CreditNoteRequest): void {\n if (isBlank(input.reason)) {\n throw new InvoiceError([{ path: 'reason', message: 'required for a credit note' }]);\n }\n if (!isRealDate(input.date)) {\n throw new InvoiceError([{ path: 'date', message: 'must be a real date as YYYY-MM-DD' }]);\n }\n}\n\nasync function creditedSoFar(storage: InvoiceStorage, invoice: InvoiceRecord, date: string): Promise<number> {\n const first = Number(numberYear(invoice.number));\n const last = Number(date.slice(0, 4));\n const years = Array.from({ length: Math.max(last - first + 1, 0) }, (_, i) => String(first + i));\n const records = (await Promise.all(years.map((year) => listIssued(storage, year)))).flat();\n return records.filter((record) => record.creditFor === invoice.number).reduce((sum, record) => sum + record.totals.netCents, 0);\n}\n\nfunction creditCents(input: CreditNoteRequest, remaining: number): number {\n const cents = input.amount === undefined ? remaining : toCents(input.amount);\n if (cents === null || cents <= 0 || cents > remaining) {\n throw new InvoiceError([{ path: 'amount', message: `must be more than zero and at most ${centsToAmount(remaining)}` }]);\n }\n return cents;\n}\n\nfunction checkTarget(invoice: InvoiceRecord, input: CreditNoteRequest): void {\n if (invoice.kind !== InvoiceKind.Invoice) {\n throw new InvoiceError([{ path: 'invoiceNumber', message: `${invoice.number} is a credit note; only an invoice can be credited` }]);\n }\n if (input.date < invoice.request.date) {\n throw new InvoiceError([{ path: 'date', message: `must not be before the invoice date ${invoice.request.date}` }]);\n }\n}\n\n/** Issues a credit note that references its invoice and takes its own gap-free CN- number. */\nexport async function issueCreditNote(storage: InvoiceStorage, input: CreditNoteRequest, options: IssueOptions = {}): Promise<IssuedInvoice> {\n checkInput(input);\n await ensureFormat(storage);\n const invoice = await readInvoice(storage, input.invoiceNumber);\n checkTarget(invoice, input);\n const render = rendererFor(storage, options);\n return storage.withLock(NUMBER_LOCK, async () => {\n const remaining = invoice.totals.netCents - (await creditedSoFar(storage, invoice, input.date));\n const cents = creditCents(input, remaining);\n const number = await nextNumber(storage, input.date.slice(0, 4), InvoiceKind.CreditNote);\n const description = `Credit for invoice ${invoice.number}: ${input.reason}`;\n const lines = [{ description, cents }];\n const { company, client, rule } = invoice;\n const request = { ...invoice.request, date: input.date, amounts: [], lines: [{ description, amount: centsToAmount(cents) }], draft: false };\n const shared = { kind: InvoiceKind.CreditNote, creditFor: invoice.number, reason: input.reason, lines } as const;\n const pdf = await render({ request, number, parties: { company, client, rule }, ...shared, lines });\n return commitRecord(storage, { number, request, company, client, rule, ...shared, lines, totals: computeTotals(lines, rule.ratePercent) }, pdf);\n });\n}\n","import { listIssued } from './issue';\nimport { InvoiceKind } from './InvoiceKind';\nimport { centsToAmount } from './money';\nimport type { InvoiceStorage } from './storage';\nimport { InvoiceError } from './types';\nimport type { InvoiceRecord } from './types';\n\nconst BOM = '';\nconst NEWLINE = '\\r\\n';\nconst MONTHS_PER_QUARTER = 3;\nconst LAST_QUARTER = 4;\nconst YEAR = /^\\d{4}$/;\nconst FORMULA_START = /^[=+\\-@\\t\\r]/;\nconst NEEDS_QUOTES = /[\",\\r\\n]/;\nconst HEADER = ['number', 'kind', 'date', 'period', 'client', 'client_vat', 'net', 'vat', 'total', 'currency', 'vat_rule', 'credit_for', 'reason'];\nconst CURRENCY = 'EUR';\n\nfunction textCell(value: string): string {\n const safe = FORMULA_START.test(value) ? `'${value}` : value;\n return NEEDS_QUOTES.test(safe) ? `\"${safe.split('\"').join('\"\"')}\"` : safe;\n}\n\nfunction toRow(record: InvoiceRecord): string {\n const sign = record.kind === InvoiceKind.CreditNote ? -1 : 1;\n const { netCents, vatCents, totalCents } = record.totals;\n return [\n record.number, record.kind, record.request.date, record.request.period, textCell(record.client.name), textCell(record.client.vatNumber),\n centsToAmount(sign * netCents), centsToAmount(sign * vatCents), centsToAmount(sign * totalCents), CURRENCY,\n textCell(record.rule.id), record.creditFor ?? '', textCell(record.reason ?? ''),\n ].join(',');\n}\n\nfunction inQuarter(record: InvoiceRecord, quarter: number): boolean {\n const month = Number(record.request.date.slice(5, 7));\n return Math.ceil(month / MONTHS_PER_QUARTER) === quarter;\n}\n\nfunction byDateThenNumber(a: InvoiceRecord, b: InvoiceRecord): number {\n return a.request.date.localeCompare(b.request.date) || a.number.localeCompare(b.number);\n}\n\n/** The accountant's CSV of one quarter's invoices and credit notes, by date; credit notes are negative. */\nexport async function exportQuarterCsv(storage: InvoiceStorage, year: string, quarter: number): Promise<string> {\n if (!Number.isInteger(quarter) || quarter < 1 || quarter > LAST_QUARTER) {\n throw new InvoiceError([{ path: 'quarter', message: 'must be 1, 2, 3 or 4' }]);\n }\n if (!YEAR.test(year)) {\n throw new InvoiceError([{ path: 'year', message: 'must be YYYY' }]);\n }\n const records = (await listIssued(storage, year)).filter((record) => inQuarter(record, quarter)).sort(byDateThenNumber);\n return `${BOM}${[HEADER.join(','), ...records.map(toRow)].join(NEWLINE)}${NEWLINE}`;\n}\n","import { StorageExistsError } from './storage';\nimport type { InvoiceStorage } from './storage';\n\nfunction toBytes(data: string | Uint8Array): Uint8Array {\n return typeof data === 'string' ? new TextEncoder().encode(data) : data;\n}\n\nfunction childName(path: string, prefix: string): string[] {\n return path.startsWith(prefix) ? [path.slice(prefix.length).split('/')[0] ?? ''] : [];\n}\n\n/** Creates an in-memory storage, for tests and previews. */\nexport function createMemoryStorage(initial: Record<string, string | Uint8Array> = {}): InvoiceStorage {\n const files = new Map(Object.entries(initial).map(([path, data]) => [path, toBytes(data)]));\n const queues = new Map<string, Promise<unknown>>();\n return {\n readText: (path): Promise<string | null> => {\n const bytes = files.get(path);\n return Promise.resolve(bytes ? new TextDecoder().decode(bytes) : null);\n },\n readBytes: (path): Promise<Uint8Array | null> => Promise.resolve(files.get(path) ?? null),\n list: (dir): Promise<string[]> => {\n const prefix = dir === '' ? '' : `${dir}/`;\n return Promise.resolve([...new Set([...files.keys()].flatMap((path) => childName(path, prefix)))].sort((a, b) => a.localeCompare(b)));\n },\n writeNew: (path, data): Promise<void> => {\n if (files.has(path)) {\n return Promise.reject(new StorageExistsError(path));\n }\n files.set(path, toBytes(data));\n return Promise.resolve();\n },\n replace: (path, data): Promise<void> => {\n files.set(path, toBytes(data));\n return Promise.resolve();\n },\n remove: (path): Promise<void> => {\n files.delete(path);\n return Promise.resolve();\n },\n withLock: <T>(name: string, work: () => Promise<T>): Promise<T> => {\n const run = (queues.get(name) ?? Promise.resolve()).then(work, work);\n queues.set(name, run.catch(() => undefined));\n return run;\n },\n };\n}\n","import { ensureFormat, readJsonFile, toJson } from './folder';\nimport { issueInvoice, listIssued } from './issue';\nimport type { PdfRender } from './issue';\nimport { expandDescription } from './lines';\nimport { toCents } from './money';\nimport { loadParties } from './parties';\nimport { StorageExistsError } from './storage';\nimport type { InvoiceStorage } from './storage';\nimport { InvoiceError } from './types';\nimport type { FieldError, InvoiceLine } from './types';\nimport { isRealDate, validateLines } from './validate';\n\nconst MONTHS_IN_YEAR = 12;\nconst YEAR = /^\\d{4}$/;\nconst SAFE_ID = /^[\\w-]+$/;\n\n/** One month of a schedule: a draft until number is set. */\nexport interface ScheduleMonth { period: string; lines: InvoiceLine[]; number: string | null; issuedOn: string | null; }\n\n/** A client's yearly schedule, stored in schedules/<id>.json. */\nexport interface InvoiceSchedule { id: string; clientId: string; year: string; months: ScheduleMonth[]; }\n\n/** What to prepare: a client and the amount each month starts with. */\nexport interface PrepareScheduleRequest { clientId: string; year: string; monthlyAmount: string; }\n\n/** The clock and renderer for issuing due months. */\nexport interface IssueDueOptions { today: string; render?: PdfRender; }\n\n/** What issuing due months did; a failure stops the run and leaves the rest as drafts. */\nexport interface IssueDueResult {\n issued: { period: string; number: string }[];\n failed: { period: string; errors: FieldError[] } | null;\n remaining: string[];\n}\n\nfunction schedulePath(id: string): string {\n return `schedules/${id}.json`;\n}\n\nfunction lockName(id: string): string {\n return `schedule-${id}`;\n}\n\nfunction checkPrepare(request: PrepareScheduleRequest): void {\n if (!YEAR.test(request.year)) {\n throw new InvoiceError([{ path: 'year', message: 'must be YYYY' }]);\n }\n if (!toCents(request.monthlyAmount)) {\n throw new InvoiceError([{ path: 'monthlyAmount', message: 'must look like 2952 or 2952.50 and be more than zero' }]);\n }\n}\n\n/** Prepares 12 drafts with no numbers from a client and a monthly amount; a second call for that year is refused. */\nexport async function prepareYearSchedule(storage: InvoiceStorage, request: PrepareScheduleRequest): Promise<InvoiceSchedule> {\n checkPrepare(request);\n const { client } = await loadParties(storage, request.clientId);\n await ensureFormat(storage);\n const months = Array.from({ length: MONTHS_IN_YEAR }, (_, i): ScheduleMonth => {\n const period = `${request.year}-${String(i + 1).padStart(2, '0')}`;\n return { period, lines: [{ description: expandDescription(client.description, period), amount: request.monthlyAmount }], number: null, issuedOn: null };\n });\n const schedule: InvoiceSchedule = { id: `${request.clientId}-${request.year}`, clientId: request.clientId, year: request.year, months };\n try {\n await storage.writeNew(schedulePath(schedule.id), toJson(schedule));\n } catch (error) {\n if (error instanceof StorageExistsError) {\n throw new InvoiceError([{ path: 'schedule', message: `${schedule.id} is already prepared` }]);\n }\n throw error;\n }\n return schedule;\n}\n\n/** Reads a schedule by id. */\nexport async function readSchedule(storage: InvoiceStorage, id: string): Promise<InvoiceSchedule> {\n if (!SAFE_ID.test(id)) {\n throw new InvoiceError([{ path: 'schedule', message: 'must hold only letters, digits, - and _' }]);\n }\n return readJsonFile<InvoiceSchedule>(storage, schedulePath(id), 'schedule');\n}\n\n/** Changes a draft month's lines; an issued month is refused and named. */\nexport async function editScheduleMonth(storage: InvoiceStorage, id: string, period: string, lines: InvoiceLine[]): Promise<InvoiceSchedule> {\n const errors = validateLines(lines);\n if (errors.length > 0) {\n throw new InvoiceError(errors);\n }\n return storage.withLock(lockName(id), async () => {\n const schedule = await readSchedule(storage, id);\n const month = schedule.months.find((entry) => entry.period === period);\n if (!month || month.number !== null) {\n const message = month ? `is issued as ${String(month.number)} and cannot change` : 'is not in this schedule';\n throw new InvoiceError([{ path: `months.${period}`, message }]);\n }\n const updated = { ...schedule, months: schedule.months.map((entry) => (entry === month ? { ...entry, lines } : entry)) };\n await storage.replace(schedulePath(id), toJson(updated));\n return updated;\n });\n}\n\nasync function reconcile(storage: InvoiceStorage, schedule: InvoiceSchedule, today: string): Promise<InvoiceSchedule> {\n const first = Number(schedule.year);\n const last = Math.max(Number(today.slice(0, 4)), first);\n const years = Array.from({ length: last - first + 1 }, (_, i) => String(first + i));\n const records = (await Promise.all(years.map((year) => listIssued(storage, year)))).flat().filter((record) => record.schedule?.id === schedule.id);\n const months = schedule.months.map((month) => {\n const record = records.find((entry) => entry.schedule?.period === month.period);\n return month.number === null && record ? { ...month, number: record.number, issuedOn: record.request.date } : month;\n });\n const changed = months.some((month, i) => month !== schedule.months[i]);\n const updated = { ...schedule, months };\n if (changed) {\n await storage.replace(schedulePath(schedule.id), toJson(updated));\n }\n return updated;\n}\n\nfunction toFieldErrors(error: unknown): FieldError[] {\n if (error instanceof InvoiceError) {\n return error.errors;\n }\n return [{ path: 'issue', message: error instanceof Error ? error.message : String(error) }];\n}\n\nasync function issueRun(storage: InvoiceStorage, start: InvoiceSchedule, options: IssueDueOptions): Promise<IssueDueResult> {\n const due = start.months.filter((month) => month.number === null && month.period < options.today.slice(0, 7));\n const result: IssueDueResult = { issued: [], failed: null, remaining: due.map((month) => month.period) };\n let schedule = start;\n for (const month of due) {\n try {\n const request = { clientId: start.clientId, period: month.period, date: options.today, amounts: [], lines: month.lines, draft: false };\n const { number } = await issueInvoice(storage, request, { render: options.render, schedule: { id: start.id, period: month.period } });\n result.issued.push({ period: month.period, number });\n result.remaining = result.remaining.filter((period) => period !== month.period);\n schedule = { ...schedule, months: schedule.months.map((entry) => (entry.period === month.period ? { ...entry, number, issuedOn: options.today } : entry)) };\n await storage.replace(schedulePath(start.id), toJson(schedule));\n } catch (error) {\n result.failed = { period: month.period, errors: toFieldErrors(error) };\n break;\n }\n }\n return result;\n}\n\n/** Issues finished months in order, each with its own number, dated today; stops at the first failure. */\nexport async function issueDueMonths(storage: InvoiceStorage, id: string, options: IssueDueOptions): Promise<IssueDueResult> {\n if (!isRealDate(options.today)) {\n throw new InvoiceError([{ path: 'today', message: 'must be a real date as YYYY-MM-DD' }]);\n }\n return storage.withLock(lockName(id), async () => issueRun(storage, await reconcile(storage, await readSchedule(storage, id), options.today), options));\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/storage.ts","../src/types.ts","../src/folder.ts","../src/FolderConflictKind.ts","../src/conflicts.ts","../src/InvoiceKind.ts","../src/LayoutAlign.ts","../src/layouts.ts","../src/money.ts","../src/period.ts","../src/lines.ts","../src/numbering.ts","../src/rules.ts","../src/schema.ts","../src/validate.ts","../src/parties.ts","../src/view.ts","../src/pdfDefinition.ts","../src/pdf.ts","../src/issue.ts","../src/creditNote.ts","../src/exportCsv.ts","../src/FolderOpenState.ts","../src/memoryStorage.ts","../src/openFolder.ts","../src/PaymentState.ts","../src/paymentStatus.ts","../src/schedule.ts"],"names":["value","FolderConflictKind","LEGACY_FILE","InvoiceKind","LayoutAlign","lines","required","totals","YEAR","vatCents","FolderOpenState","toBytes","LEGACY_YEAR","PaymentState","payment","SAFE_ID"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The data folder as the core sees it. Paths are relative, with forward slashes.\n * Browser and Node implementations live outside this package.\n */\nexport interface InvoiceStorage {\n /** Returns the file as text, or null if it does not exist. */\n readText(path: string): Promise<string | null>;\n /** Returns the file as bytes, or null if it does not exist. */\n readBytes(path: string): Promise<Uint8Array | null>;\n /** Returns the names of a folder's direct children; empty if it does not exist. */\n list(dir: string): Promise<string[]>;\n /** Creates a file and its parents; throws StorageExistsError if the file exists. */\n writeNew(path: string, data: string | Uint8Array): Promise<void>;\n /** Creates or overwrites a file; never used on an issued record. */\n replace(path: string, data: string | Uint8Array): Promise<void>;\n /** Deletes a file; does nothing if it does not exist. */\n remove(path: string): Promise<void>;\n /** Runs work while holding the named lock; other holders of that name wait. */\n withLock<T>(name: string, work: () => Promise<T>): Promise<T>;\n}\n\n/** Thrown by writeNew when the file already exists. */\nexport class StorageExistsError extends Error {\n constructor(path: string) {\n super(`already exists: ${path}`);\n this.name = 'StorageExistsError';\n }\n}\n\n/** Whether an error means the file exists; matched by name, so another package's class of this name counts. */\nexport function isStorageExistsError(error: unknown): boolean {\n return typeof error === 'object' && error !== null && (error as { name?: unknown }).name === 'StorageExistsError';\n}\n","import type { InvoiceKind } from './InvoiceKind';\n\n/** One validation problem: a field path and what is wrong with it. */\nexport interface FieldError { path: string; message: string; }\n\n/** The issuing company, read from company.json in the data folder. */\nexport interface Company {\n name: string; addressLines: string[]; regNo: string; vatNumber: string;\n bank: string; iban: string; bic: string; logo?: string; template?: string; layout?: string;\n}\n\n/** A client, read from clients/<id>.json in the data folder. */\nexport interface Client {\n name: string; addressLines: string[]; taxLines: string[]; vatNumber: string;\n vatRule: string; paymentTermsDays: number | null; description: string; template?: string; layout?: string;\n}\n\n/** A VAT treatment, built in or read from a rule file. */\nexport interface VatRule {\n id: string; ratePercent: number; labelEn: string; labelEl: string;\n rateTextEn: string; rateTextEl: string; noteEn: string; noteEl: string; source: string;\n reviewedByAccountant?: boolean;\n}\n\n/** A line as entered: its own description and an amount such as 2952.50. */\nexport interface InvoiceLine { description: string; amount: string; }\n\n/** A line ready to print and total. */\nexport interface ResolvedLine { description: string; cents: number; }\n\n/** Totals in whole cents. */\nexport interface Totals { netCents: number; vatCents: number; totalCents: number; }\n\n/** The per-invoice request. Lines win over amounts, which use the client description. */\nexport interface InvoiceRequest {\n clientId: string; period: string; date: string; amounts: string[]; lines?: InvoiceLine[];\n template?: string; layout?: string; draft: boolean;\n}\n\n/** The three files an invoice is built from. */\nexport interface Parties { company: Company; client: Client; rule: VatRule; }\n\n/** Which schedule month an issued record came from. */\nexport interface ScheduleRef { id: string; period: string; }\n\n/** The immutable record of an issued invoice or credit note. */\nexport interface InvoiceRecord extends Parties {\n kind: InvoiceKind; number: string; request: InvoiceRequest; lines: ResolvedLine[]; totals: Totals;\n schedule?: ScheduleRef; creditFor?: string; reason?: string;\n}\n\n/** Where an issued record and its PDF were saved. */\nexport interface IssuedInvoice { number: string; pdfPath: string; recordPath: string; }\n\n/** Thrown for any refusal; errors name each field. */\nexport class InvoiceError extends Error {\n readonly errors: FieldError[];\n\n constructor(errors: FieldError[]) {\n super(errors.map((e) => `${e.path}: ${e.message}`).join('; '));\n this.name = 'InvoiceError';\n this.errors = errors;\n }\n}\n","import { isStorageExistsError } from './storage';\nimport type { InvoiceStorage } from './storage';\nimport { InvoiceError } from './types';\n\nexport const FORMAT_PATH = 'format.json';\nconst FORMAT_VERSION = 1;\nconst NUMBER_YEAR = /(\\d{4})-\\d+$/;\nconst LEGACY_YEAR = /^\\d{4}$/;\nconst LEGACY_FILE = /^(\\d{4}-\\d+)\\.(json|pdf)$/;\nconst OS_FILES = new Set(['desktop.ini', 'thumbs.db', '.ds_store']);\n\nexport const NUMBER_SHAPE = /^(CN-)?\\d{4}-\\d+$/;\n\n/** Whether a file is one the operating system leaves in any folder. */\nexport function isOsFile(name: string): boolean {\n return OS_FILES.has(name.toLowerCase());\n}\n\n/** Serialises a folder file the one way every writer does. */\nexport function toJson(value: unknown): string {\n return JSON.stringify(value, null, 2);\n}\n\n/** The year folder a number belongs to. */\nexport function numberYear(number: string): string {\n return NUMBER_YEAR.exec(number)?.[1] ?? '';\n}\n\n/** The folder of an issued invoice or credit note. */\nexport function invoiceDir(number: string): string {\n return `invoices/${numberYear(number)}/${number}`;\n}\n\n/** The path of an issued record. */\nexport function recordPath(number: string): string {\n return `${invoiceDir(number)}/invoice.json`;\n}\n\n/** The path of an issued PDF. */\nexport function pdfPath(number: string): string {\n return `${invoiceDir(number)}/${number}.pdf`;\n}\n\n/** Reads a JSON object, refusing a missing file or bad JSON under the given label. */\nexport async function readJsonFile<T>(storage: InvoiceStorage, path: string, label: string): Promise<T> {\n const text = await storage.readText(path);\n if (text === null) {\n throw new InvoiceError([{ path: label, message: `file not found: ${path}` }]);\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(text) as unknown;\n } catch {\n throw new InvoiceError([{ path: label, message: `invalid JSON: ${path}` }]);\n }\n if (typeof parsed !== 'object' || parsed === null) {\n throw new InvoiceError([{ path: label, message: `must be a JSON object: ${path}` }]);\n }\n return parsed as T;\n}\n\n/** Creates format.json in a new folder and refuses a folder newer than this code. */\nexport async function ensureFormat(storage: InvoiceStorage): Promise<void> {\n const text = await storage.readText(FORMAT_PATH);\n if (text === null) {\n await storage.writeNew(FORMAT_PATH, toJson({ version: FORMAT_VERSION })).catch((error: unknown) => {\n if (!isStorageExistsError(error)) {\n throw error;\n }\n });\n return;\n }\n const { version } = await readJsonFile<{ version?: unknown }>(storage, FORMAT_PATH, 'format');\n if (typeof version !== 'number' || version > FORMAT_VERSION) {\n throw new InvoiceError([{ path: 'format', message: `folder format ${String(version)} is not supported; this code reads up to ${FORMAT_VERSION}` }]);\n }\n}\n\nasync function migrateNumber(storage: InvoiceStorage, year: string, number: string): Promise<boolean> {\n const oldRecord = await storage.readBytes(`${year}/${number}.json`);\n const oldPdf = await storage.readBytes(`${year}/${number}.pdf`);\n const taken = (await storage.readBytes(recordPath(number))) !== null || (await storage.readBytes(pdfPath(number))) !== null;\n if (taken) {\n return false;\n }\n if (oldRecord) {\n await storage.writeNew(recordPath(number), oldRecord);\n }\n if (oldPdf) {\n await storage.writeNew(pdfPath(number), oldPdf);\n }\n await storage.remove(`${year}/${number}.json`);\n await storage.remove(`${year}/${number}.pdf`);\n return true;\n}\n\n/** What a migration moved, and the numbers left in place because the target exists. */\nexport interface MigrationResult { moved: string[]; conflicts: string[]; }\n\n/** Moves <year>/<number>.json + .pdf to invoices/<year>/<number>/. Never overwrites. */\nexport async function migrateLegacyFolder(storage: InvoiceStorage): Promise<MigrationResult> {\n await ensureFormat(storage);\n const result: MigrationResult = { moved: [], conflicts: [] };\n const years = (await storage.list('')).filter((name) => LEGACY_YEAR.test(name));\n for (const year of years) {\n const names = await storage.list(year);\n const numbers = [...new Set(names.flatMap((name) => LEGACY_FILE.exec(name)?.[1] ?? []))].sort((a, b) => a.localeCompare(b));\n for (const number of numbers) {\n const moved = await migrateNumber(storage, year, number);\n (moved ? result.moved : result.conflicts).push(number);\n }\n }\n return result;\n}\n","export const enum FolderConflictKind {\n SyncCopy = 'sync copy',\n DuplicateNumber = 'duplicate number',\n UnreadableRecord = 'unreadable record',\n}\n","import { isOsFile, numberYear, NUMBER_SHAPE } from './folder';\nimport { FolderConflictKind } from './FolderConflictKind';\nimport type { InvoiceStorage } from './storage';\nimport { InvoiceError } from './types';\n\nconst RECORD_FILE = 'invoice.json';\nconst STATUS_FILE = 'status.json';\nconst LEGACY_FILE = /^(\\d{4}-\\d+)\\.(json|pdf)$/;\n\nexport interface FolderConflict {\n kind: FolderConflictKind;\n path: string;\n}\n\nfunction seriesKey(number: string): string {\n const separator = number.lastIndexOf('-');\n return `${number.slice(0, separator)}-${Number(number.slice(separator + 1))}`;\n}\n\nasync function recordConflict(storage: InvoiceStorage, dir: string, number: string): Promise<FolderConflict[]> {\n const path = `${dir}/${RECORD_FILE}`;\n const text = await storage.readText(path);\n if (text === null) {\n return [];\n }\n let parsed: { number?: unknown } | null;\n try {\n parsed = JSON.parse(text) as { number?: unknown } | null;\n } catch {\n return [{ kind: FolderConflictKind.UnreadableRecord, path }];\n }\n if (typeof parsed !== 'object' || parsed === null) {\n return [{ kind: FolderConflictKind.UnreadableRecord, path }];\n }\n return parsed.number === number ? [] : [{ kind: FolderConflictKind.DuplicateNumber, path }];\n}\n\nasync function numberFolderConflicts(storage: InvoiceStorage, dir: string, number: string): Promise<FolderConflict[]> {\n const allowed = new Set([RECORD_FILE, STATUS_FILE, `${number}.pdf`]);\n const copies = (await storage.list(dir))\n .filter((name) => !allowed.has(name) && !isOsFile(name))\n .map((name) => ({ kind: FolderConflictKind.SyncCopy, path: `${dir}/${name}` }));\n return [...copies, ...(await recordConflict(storage, dir, number))];\n}\n\nasync function currentLayoutConflicts(storage: InvoiceStorage, year: string): Promise<{ conflicts: FolderConflict[]; numbers: Set<string> }> {\n const conflicts: FolderConflict[] = [];\n const numbers = new Set<string>();\n const keys = new Set<string>();\n const yearDir = `invoices/${year}`;\n for (const name of (await storage.list(yearDir)).filter((entry) => !isOsFile(entry))) {\n const path = `${yearDir}/${name}`;\n if (!NUMBER_SHAPE.test(name) || numberYear(name) !== year) {\n conflicts.push({ kind: FolderConflictKind.SyncCopy, path });\n } else if (keys.has(seriesKey(name))) {\n conflicts.push({ kind: FolderConflictKind.DuplicateNumber, path });\n } else {\n keys.add(seriesKey(name));\n numbers.add(name);\n conflicts.push(...(await numberFolderConflicts(storage, path, name)));\n }\n }\n return { conflicts, numbers };\n}\n\nasync function legacyLayoutConflicts(storage: InvoiceStorage, year: string, numbers: Set<string>): Promise<FolderConflict[]> {\n const names = (await storage.list(year)).filter((name) => !isOsFile(name));\n return names.flatMap((name): FolderConflict[] => {\n const number = LEGACY_FILE.exec(name)?.[1];\n const path = `${year}/${name}`;\n if (number === undefined || numberYear(number) !== year) {\n return [{ kind: FolderConflictKind.SyncCopy, path }];\n }\n return numbers.has(number) ? [{ kind: FolderConflictKind.DuplicateNumber, path }] : [];\n });\n}\n\n/** Finds sync-conflict copies, duplicate numbers and unreadable records in one year, in both layouts. */\nexport async function findFolderConflicts(storage: InvoiceStorage, year: string): Promise<FolderConflict[]> {\n const { conflicts, numbers } = await currentLayoutConflicts(storage, year);\n return [...conflicts, ...(await legacyLayoutConflicts(storage, year, numbers))];\n}\n\n/** Refuses to continue if the year holds a conflict, naming each path. */\nexport async function assertNoConflicts(storage: InvoiceStorage, year: string): Promise<void> {\n const conflicts = await findFolderConflicts(storage, year);\n if (conflicts.length > 0) {\n throw new InvoiceError(conflicts.map(({ kind, path }) => ({ path: 'folder', message: `${kind}: ${path}` })));\n }\n}\n","/** Whether an issued record is an invoice or a credit note. */\nexport const enum InvoiceKind {\n Invoice = 'invoice',\n CreditNote = 'credit-note',\n}\n","/** Where a layout places the document title. */\nexport const enum LayoutAlign {\n Left = 'left',\n Right = 'right',\n}\n","import { LayoutAlign } from './LayoutAlign';\nimport type { InvoiceStorage } from './storage';\nimport { InvoiceError } from './types';\nimport type { FieldError, InvoiceRequest, Parties } from './types';\n\nconst SAFE_NAME = /^[\\w-]+$/;\nconst HEX_COLOUR = /^#[0-9a-fA-F]{6}$/;\nconst NUMBER_RANGES: Record<string, [number, number]> = { pageMargin: [10, 80], bodySize: [6, 14], titleSize: [10, 40], logoWidth: [20, 240] };\nconst COLOUR_KEYS = ['accent', 'muted', 'band'];\nconst ALLOWED_KEYS = new Set(['name', 'titleAlign', ...COLOUR_KEYS, ...Object.keys(NUMBER_RANGES)]);\n\n/** The name a request uses when neither it, the client nor the company picks a layout. */\nexport const DEFAULT_LAYOUT = 'classic';\n\n/** The look of a PDF: plain data only, so a layout cannot run anything. */\nexport interface InvoiceLayout {\n name: string; pageMargin: number; bodySize: number; titleSize: number; logoWidth: number;\n accent: string; muted: string; band: string; titleAlign: LayoutAlign;\n}\n\n/** The layouts every folder can use; a file in layouts/ overrides them by name. */\nexport const BUILT_IN_LAYOUTS = {\n classic: { name: 'classic', pageMargin: 40, bodySize: 9.5, titleSize: 22, logoWidth: 90, accent: '#1F3A5F', muted: '#666666', band: '#E4ECF5', titleAlign: LayoutAlign.Right },\n compact: { name: 'compact', pageMargin: 28, bodySize: 8.5, titleSize: 16, logoWidth: 60, accent: '#2F4F4F', muted: '#5F5F5F', band: '#E8EFEE', titleAlign: LayoutAlign.Left },\n} as const satisfies Record<string, InvoiceLayout>;\n\nconst BUILT_IN_BY_NAME: ReadonlyMap<string, InvoiceLayout> = new Map(Object.entries(BUILT_IN_LAYOUTS));\n\nfunction fieldErrors(data: Record<string, unknown>): FieldError[] {\n const errors: FieldError[] = Object.keys(data).filter((key) => !ALLOWED_KEYS.has(key)).map((key) => ({ path: `layout.${key}`, message: 'unknown field' }));\n if (typeof data.name !== 'string') {\n errors.push({ path: 'layout.name', message: 'must be text' });\n }\n if (data.titleAlign !== LayoutAlign.Left && data.titleAlign !== LayoutAlign.Right) {\n errors.push({ path: 'layout.titleAlign', message: 'must be left or right' });\n }\n COLOUR_KEYS.filter((key) => typeof data[key] !== 'string' || !HEX_COLOUR.test(data[key])).forEach((key) => errors.push({ path: `layout.${key}`, message: 'must be a colour like #1F3A5F' }));\n Object.entries(NUMBER_RANGES).forEach(([key, [min, max]]) => {\n const value = data[key];\n if (typeof value !== 'number' || !(value >= min && value <= max)) {\n errors.push({ path: `layout.${key}`, message: `must be a number from ${min} to ${max}` });\n }\n });\n return errors;\n}\n\n/** Checks a parsed layout file; refuses unknown fields and anything but plain values. */\nexport function parseLayout(raw: unknown): InvoiceLayout {\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n throw new InvoiceError([{ path: 'layout', message: 'must be a JSON object' }]);\n }\n const errors = fieldErrors(raw as Record<string, unknown>);\n if (errors.length > 0) {\n throw new InvoiceError(errors);\n }\n return raw as InvoiceLayout;\n}\n\nfunction parseLayoutText(text: string, name: string): InvoiceLayout {\n let parsed: unknown;\n try {\n parsed = JSON.parse(text) as unknown;\n } catch {\n throw new InvoiceError([{ path: 'layout', message: `invalid JSON in layout \"${name}\"` }]);\n }\n return parseLayout(parsed);\n}\n\n/** Finds a layout in the data folder, then the built-in set; an unknown name is refused and named. */\nexport async function resolveLayout(storage: InvoiceStorage, name: string): Promise<InvoiceLayout> {\n const text = SAFE_NAME.test(name) ? await storage.readText(`layouts/${name}.json`) : null;\n if (text !== null) {\n return parseLayoutText(text, name);\n }\n const builtIn = BUILT_IN_BY_NAME.get(name);\n if (!builtIn) {\n throw new InvoiceError([{ path: 'layout', message: `unknown layout \"${name}\"` }]);\n }\n return builtIn;\n}\n\n/** The layout name in force: request, then client, then company, then the default. */\nexport function selectLayoutName(request: InvoiceRequest, parties: Parties): string {\n return request.layout ?? parties.client.layout ?? parties.company.layout ?? DEFAULT_LAYOUT;\n}\n","const CENTS_PER_UNIT = 100;\nconst GROUP_SIZE = 3;\nconst AMOUNT = /^\\d{1,12}(\\.\\d{1,2})?$/;\n\nfunction groupThousands(digits: string): string {\n const groups: string[] = [];\n for (let end = digits.length; end > 0; end -= GROUP_SIZE) {\n groups.unshift(digits.slice(Math.max(end - GROUP_SIZE, 0), end));\n }\n return groups.join('.');\n}\n\n/** Parses \"2952\" or \"2952.50\" into integer cents; returns null if malformed. */\nexport function toCents(amount: string): number | null {\n if (!AMOUNT.test(amount)) {\n return null;\n }\n const [whole, fraction = ''] = amount.split('.');\n return Number(whole) * CENTS_PER_UNIT + Number(fraction.padEnd(2, '0'));\n}\n\n/** Formats cents in Greek style: 295200 becomes \"2.952,00\". */\nexport function formatCents(cents: number): string {\n const whole = groupThousands(Math.floor(cents / CENTS_PER_UNIT).toString());\n return `${whole},${(cents % CENTS_PER_UNIT).toString().padStart(2, '0')}`;\n}\n\n/** Formats cents as a plain amount: -4000 becomes \"-40.00\". */\nexport function centsToAmount(cents: number): string {\n const size = Math.abs(cents);\n const text = `${Math.floor(size / CENTS_PER_UNIT)}.${(size % CENTS_PER_UNIT).toString().padStart(2, '0')}`;\n return cents < 0 ? `-${text}` : text;\n}\n\n/** Computes VAT in whole cents, rounded half up. */\nexport function vatCents(netCents: number, ratePercent: number): number {\n return Math.round((netCents * ratePercent) / CENTS_PER_UNIT);\n}\n","const MONTHS_EN = ['January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December'];\nconst MONTHS_EL = ['Ιανουάριος', 'Φεβρουάριος', 'Μάρτιος', 'Απρίλιος', 'Μάιος', 'Ιούνιος', 'Ιούλιος', 'Αύγουστος', 'Σεπτέμβριος', 'Οκτώβριος', 'Νοέμβριος', 'Δεκέμβριος'];\nconst MONTHS_EL_ACCUSATIVE = ['Ιανουάριο', 'Φεβρουάριο', 'Μάρτιο', 'Απρίλιο', 'Μάιο', 'Ιούνιο', 'Ιούλιο', 'Αύγουστο', 'Σεπτέμβριο', 'Οκτώβριο', 'Νοέμβριο', 'Δεκέμβριο'];\n\n/** Period texts for a YYYY-MM period. */\nexport function periodTexts(period: string): { en: string; el: string; elAccusative: string } {\n const year = period.slice(0, 4);\n const i = Number(period.slice(5)) - 1;\n return {\n en: `${MONTHS_EN[i] ?? ''} ${year}`,\n el: `${MONTHS_EL[i] ?? ''} ${year}`,\n elAccusative: `${MONTHS_EL_ACCUSATIVE[i] ?? ''} ${year}`,\n };\n}\n\n/** Formats YYYY-MM-DD as DD/MM/YYYY. */\nexport function displayDate(iso: string): string {\n return iso.split('-').reverse().join('/');\n}\n\n/** Adds days to a YYYY-MM-DD date. */\nexport function addDays(iso: string, days: number): string {\n const date = new Date(`${iso}T00:00:00Z`);\n date.setUTCDate(date.getUTCDate() + days);\n return date.toISOString().slice(0, 10);\n}\n","import { toCents, vatCents } from './money';\nimport { periodTexts } from './period';\nimport type { Client, InvoiceRequest, ResolvedLine, Totals } from './types';\n\n/** Fills {periodElAccusative} and {periodEn} in a client description. */\nexport function expandDescription(description: string, period: string): string {\n const texts = periodTexts(period);\n return description.split('{periodElAccusative}').join(texts.elAccusative).split('{periodEn}').join(texts.en);\n}\n\n/** Turns a request into printable lines: its own lines, else amounts with the client description. */\nexport function resolveLines(request: InvoiceRequest, client: Client): ResolvedLine[] {\n if (request.lines && request.lines.length > 0) {\n return request.lines.map((line) => ({ description: line.description, cents: toCents(line.amount) ?? 0 }));\n }\n const description = expandDescription(client.description, request.period);\n return request.amounts.map((amount) => ({ description, cents: toCents(amount) ?? 0 }));\n}\n\n/** Sums lines in whole cents and adds VAT at the given rate. */\nexport function computeTotals(lines: ResolvedLine[], ratePercent: number): Totals {\n const netCents = lines.reduce((sum, line) => sum + line.cents, 0);\n const vat = vatCents(netCents, ratePercent);\n return { netCents, vatCents: vat, totalCents: netCents + vat };\n}\n","import { recordPath, toJson } from './folder';\nimport { InvoiceKind } from './InvoiceKind';\nimport { isStorageExistsError } from './storage';\nimport type { InvoiceStorage } from './storage';\nimport { InvoiceError } from './types';\nimport type { InvoiceRecord } from './types';\n\nconst PAD = 3;\nconst YEAR = /^\\d{4}$/;\nconst CREDIT_PREFIX = 'CN-';\n\nfunction highest(names: string[], pattern: RegExp): number {\n return names.reduce((max, name) => Math.max(max, Number(pattern.exec(name)?.[1] ?? 0)), 0);\n}\n\n/** Returns the next gap-free number for a year, such as 2030-002 or CN-2030-001. */\nexport async function nextNumber(storage: InvoiceStorage, year: string, kind: InvoiceKind = InvoiceKind.Invoice): Promise<string> {\n if (!YEAR.test(year)) {\n throw new InvoiceError([{ path: 'year', message: 'must be YYYY' }]);\n }\n const prefix = kind === InvoiceKind.CreditNote ? CREDIT_PREFIX : '';\n const current = highest(await storage.list(`invoices/${year}`), new RegExp(`^${prefix}${year}-(\\\\d+)$`));\n const legacy = prefix === '' ? highest(await storage.list(year), new RegExp(`^${year}-(\\\\d+)\\\\.(?:json|pdf)$`)) : 0;\n return `${prefix}${year}-${String(Math.max(current, legacy) + 1).padStart(PAD, '0')}`;\n}\n\n/** Writes the record, refusing if that number was already issued. Issued records are never replaced. */\nexport async function claimInvoice(storage: InvoiceStorage, record: InvoiceRecord): Promise<string> {\n const path = recordPath(record.number);\n try {\n await storage.writeNew(path, toJson(record));\n } catch (error) {\n const message = isStorageExistsError(error) ? `${record.number} is already issued` : `could not save ${record.number}: ${(error as Error).message}`;\n throw new InvoiceError([{ path: 'number', message }]);\n }\n return path;\n}\n","import type { VatRule } from './types';\n\nconst CY_DOMESTIC_19: VatRule = {\n id: 'cy-domestic-19',\n ratePercent: 19,\n labelEn: 'VAT',\n labelEl: 'ΦΠΑ',\n rateTextEn: '19%',\n rateTextEl: '19%',\n noteEn: '',\n noteEl: '',\n source: 'Cyprus VAT Law 95(I)/2000, standard rate',\n reviewedByAccountant: false,\n};\n\nconst CY_TO_EU_B2B_SERVICES: VatRule = {\n id: 'cy-to-eu-b2b-services',\n ratePercent: 0,\n labelEn: 'VAT',\n labelEl: 'ΦΠΑ',\n rateTextEn: 'Reverse charge',\n rateTextEl: 'Αντίστροφη επιβάρυνση',\n noteEn: 'Reverse charge: VAT is payable by the recipient, Art. 196 Directive 2006/112/EC.',\n noteEl: 'Αντίστροφη επιβάρυνση: ο ΦΠΑ οφείλεται από τον λήπτη, άρθρο 196 Οδηγίας 2006/112/ΕΚ.',\n source: 'Directive 2006/112/EC Art. 44, 196, 226(11a)',\n reviewedByAccountant: false,\n};\n\n/** The built-in VAT rules by id; a rule file in the data folder overrides them. Not tax advice. */\nexport const BUILT_IN_RULES: ReadonlyMap<string, VatRule> = new Map([\n [CY_DOMESTIC_19.id, CY_DOMESTIC_19],\n [CY_TO_EU_B2B_SERVICES.id, CY_TO_EU_B2B_SERVICES],\n]);\n","import type { FieldError } from './types';\n\nconst MAX_RATE = 100;\n\nfunction strings(prefix: string, data: Record<string, unknown>, keys: string[]): FieldError[] {\n return keys\n .filter((key) => data[key] !== undefined && typeof data[key] !== 'string')\n .map((key) => ({ path: `${prefix}.${key}`, message: 'must be text' }));\n}\n\nfunction required(prefix: string, data: Record<string, unknown>, keys: string[]): FieldError[] {\n return keys\n .filter((key) => typeof data[key] !== 'string')\n .map((key) => ({ path: `${prefix}.${key}`, message: 'must be text' }));\n}\n\nfunction isTextList(value: unknown): boolean {\n return Array.isArray(value) && value.every((line) => typeof line === 'string');\n}\n\nfunction lines(prefix: string, data: Record<string, unknown>, keys: string[]): FieldError[] {\n return keys\n .filter((key) => !isTextList(data[key]))\n .map((key) => ({ path: `${prefix}.${key}`, message: 'must be a list of text lines' }));\n}\n\n/** Checks the shape of company.json. */\nexport function companyShape(company: object): FieldError[] {\n const data = company as Record<string, unknown>;\n return [\n ...required('company', data, ['name', 'regNo', 'vatNumber', 'bank', 'iban', 'bic']),\n ...strings('company', data, ['logo', 'template', 'layout']),\n ...lines('company', data, ['addressLines']),\n ];\n}\n\n/** Checks the shape of a client file. */\nexport function clientShape(client: object): FieldError[] {\n const data = client as Record<string, unknown>;\n const days = data.paymentTermsDays;\n const badDays = days !== null && (!Number.isInteger(days) || (days as number) < 0);\n return [\n ...required('client', data, ['name', 'vatNumber', 'vatRule', 'description']),\n ...strings('client', data, ['template', 'layout']),\n ...lines('client', data, ['addressLines', 'taxLines']),\n ...(badDays ? [{ path: 'client.paymentTermsDays', message: 'must be null or a whole number of days, 0 or more' }] : []),\n ];\n}\n\n/** Checks the shape of a VAT rule file. */\nexport function ruleShape(rule: object): FieldError[] {\n const data = rule as Record<string, unknown>;\n const rate = data.ratePercent;\n const badRate = typeof rate !== 'number' || !Number.isFinite(rate) || rate < 0 || rate > MAX_RATE;\n return [\n ...required('rule', data, ['labelEn', 'labelEl', 'rateTextEn', 'rateTextEl', 'noteEn', 'noteEl']),\n ...(badRate ? [{ path: 'rule.ratePercent', message: 'must be a number from 0 to 100' }] : []),\n ];\n}\n","import { toCents } from './money';\nimport type { Client, Company, FieldError, InvoiceLine, InvoiceRequest } from './types';\n\nconst PERIOD = /^\\d{4}-(0[1-9]|1[0-2])$/;\nconst DATE = /^\\d{4}-\\d{2}-\\d{2}$/;\n\n/** True for an empty value or a placeholder such as CY[____]. */\nexport function isBlank(value: unknown): boolean {\n if (value === undefined || value === null) {\n return true;\n }\n const text = String(value);\n return text.trim() === '' || text.includes('__');\n}\n\n/** True for a real calendar date written as YYYY-MM-DD. */\nexport function isRealDate(date: string): boolean {\n if (!DATE.test(date)) {\n return false;\n }\n const parsed = new Date(`${date}T00:00:00Z`);\n return !Number.isNaN(parsed.getTime()) && parsed.toISOString().slice(0, 10) === date;\n}\n\nfunction amountErrors(amount: string, path: string): FieldError[] {\n const cents = toCents(amount);\n if (cents === null) {\n return [{ path, message: 'must look like 2952 or 2952.50' }];\n }\n return cents === 0 ? [{ path, message: 'must be more than zero' }] : [];\n}\n\n/** Checks each line's amount; a description may stay blank until final. */\nexport function validateLines(lines: InvoiceLine[]): FieldError[] {\n return lines.flatMap((line, i) => amountErrors(line.amount, `lines[${i}].amount`));\n}\n\n/** Checks the request shape; these errors apply to drafts too. */\nexport function validateRequest(req: InvoiceRequest): FieldError[] {\n const errors: FieldError[] = [];\n const lines = req.lines ?? [];\n if (!PERIOD.test(req.period)) {\n errors.push({ path: 'period', message: 'must be YYYY-MM' });\n }\n if (!isRealDate(req.date)) {\n errors.push({ path: 'date', message: 'must be a real date as YYYY-MM-DD' });\n }\n if (req.amounts.length === 0 && lines.length === 0) {\n errors.push({ path: 'amounts', message: 'at least one amount is required' });\n }\n req.amounts.forEach((amount, i) => errors.push(...amountErrors(amount, `amounts[${i}]`)));\n errors.push(...validateLines(lines));\n return errors;\n}\n\n/** Lists required fields still blank; a final invoice is refused if any are. */\nexport function missingForFinal(company: Company, client: Client, lines: InvoiceLine[] = []): FieldError[] {\n const required: [string, unknown][] = [\n ['company.name', company.name], ['company.addressLines', company.addressLines?.join('')],\n ['company.regNo', company.regNo], ['company.vatNumber', company.vatNumber],\n ['company.bank', company.bank], ['company.iban', company.iban], ['company.bic', company.bic],\n ['client.name', client.name], ['client.addressLines', client.addressLines?.join('')],\n ['client.vatNumber', client.vatNumber], ['client.paymentTermsDays', client.paymentTermsDays],\n ...(lines.length === 0 ? [['client.description', client.description] as [string, unknown]] : []),\n ...lines.map((line, i): [string, unknown] => [`lines[${i}].description`, line.description]),\n ];\n const errors = required.filter(([, value]) => isBlank(value)).map(([path]) => ({ path, message: 'required for a final invoice' }));\n const vatShown = isBlank(client.vatNumber) || client.taxLines.some((line) => line.includes(client.vatNumber));\n return vatShown ? errors : [...errors, { path: 'client.taxLines', message: 'must show the client VAT number' }];\n}\n","import { readJsonFile } from './folder';\nimport { BUILT_IN_RULES } from './rules';\nimport { clientShape, companyShape, ruleShape } from './schema';\nimport type { InvoiceStorage } from './storage';\nimport { InvoiceError } from './types';\nimport type { Client, Company, InvoiceRequest, Parties, VatRule } from './types';\nimport { missingForFinal, validateRequest } from './validate';\n\nconst SAFE_ID = /^[\\w-]+$/;\n\nasync function loadRule(storage: InvoiceStorage, id: string): Promise<VatRule> {\n const safe = SAFE_ID.test(id);\n if (safe && (await storage.readText(`rules/${id}.json`)) !== null) {\n return readJsonFile<VatRule>(storage, `rules/${id}.json`, 'rule');\n }\n const builtIn = BUILT_IN_RULES.get(id);\n if (!builtIn) {\n throw new InvoiceError([{ path: 'client.vatRule', message: `unknown VAT rule \"${id}\"` }]);\n }\n return builtIn;\n}\n\n/** Reads the request's company, client and VAT rule, refusing if any is missing. */\nexport async function loadParties(storage: InvoiceStorage, clientId: string): Promise<Parties> {\n if (!SAFE_ID.test(clientId)) {\n throw new InvoiceError([{ path: 'clientId', message: 'must hold only letters, digits, - and _' }]);\n }\n const company = await readJsonFile<Company>(storage, 'company.json', 'company');\n const client = await readJsonFile<Client>(storage, `clients/${clientId}.json`, 'client');\n return { company, client, rule: await loadRule(storage, client.vatRule) };\n}\n\n/** Checks a request and returns its parties; final mode also refuses blank required fields. */\nexport async function checkRequest(storage: InvoiceStorage, request: InvoiceRequest): Promise<Parties> {\n const errors = validateRequest(request);\n if (errors.length > 0) {\n throw new InvoiceError(errors);\n }\n const parties = await loadParties(storage, request.clientId);\n const shape = [...companyShape(parties.company), ...clientShape(parties.client), ...ruleShape(parties.rule)];\n if (shape.length > 0) {\n throw new InvoiceError(shape);\n }\n const missing = request.draft ? [] : missingForFinal(parties.company, parties.client, request.lines);\n if (missing.length > 0) {\n throw new InvoiceError(missing);\n }\n return parties;\n}\n","import { InvoiceKind } from './InvoiceKind';\nimport { computeTotals, resolveLines } from './lines';\nimport { formatCents } from './money';\nimport { addDays, displayDate, periodTexts } from './period';\nimport type { InvoiceRequest, Parties, ResolvedLine } from './types';\nimport { isBlank } from './validate';\n\n/** What a blank required field prints as on a draft. */\nexport const BLANK_MARK = '[________]';\n\nconst DRAFT_NUMBER = 'DRAFT';\n\n/** What a renderer receives. A null number means a draft. */\nexport interface RenderInput {\n request: InvoiceRequest; number: string | null; parties: Parties;\n lines?: ResolvedLine[]; kind?: InvoiceKind; creditFor?: string; reason?: string;\n}\n\n/** Everything a PDF prints, already formatted. */\nexport interface InvoiceView {\n draft: boolean; creditNote: boolean; number: string; date: string; dueDate: string; periodEn: string; periodEl: string;\n company: { name: string; addressLines: string[]; regNo: string; vatNumber: string; bank: string; iban: string; bic: string };\n client: { name: string; addressLines: string[]; taxLines: string[] };\n rows: { description: string; amount: string }[];\n net: string; vat: string; total: string; vatLabel: string; noteEn: string; noteEl: string;\n creditFor?: string; reason?: string;\n}\n\nfunction shown(value: unknown): string {\n return isBlank(value) ? BLANK_MARK : String(value);\n}\n\n/** Formats a request into what the PDF prints. */\nexport function buildInvoiceView(input: RenderInput): InvoiceView {\n const { request, number, parties: { company, client, rule } } = input;\n const lines = input.lines ?? resolveLines(request, client);\n const totals = computeTotals(lines, rule.ratePercent);\n const period = periodTexts(request.period);\n return {\n draft: number === null,\n creditNote: input.kind === InvoiceKind.CreditNote,\n number: number ?? DRAFT_NUMBER,\n date: displayDate(request.date),\n dueDate: typeof client.paymentTermsDays === 'number' ? displayDate(addDays(request.date, client.paymentTermsDays)) : BLANK_MARK,\n periodEn: period.en,\n periodEl: period.el,\n company: {\n name: shown(company.name), addressLines: company.addressLines, regNo: shown(company.regNo), vatNumber: shown(company.vatNumber),\n bank: shown(company.bank), iban: shown(company.iban), bic: shown(company.bic),\n },\n client: { name: shown(client.name), addressLines: client.addressLines, taxLines: client.taxLines },\n rows: lines.map((line) => ({ description: shown(line.description), amount: formatCents(line.cents) })),\n net: formatCents(totals.netCents),\n vat: formatCents(totals.vatCents),\n total: formatCents(totals.totalCents),\n vatLabel: `${rule.labelEn} / ${rule.labelEl} (${rule.rateTextEn} / ${rule.rateTextEl})`,\n noteEn: rule.noteEn,\n noteEl: rule.noteEl,\n creditFor: input.creditFor,\n reason: input.reason,\n };\n}\n","import type { InvoiceLayout } from './layouts';\nimport { BLANK_MARK } from './view';\nimport type { InvoiceView } from './view';\n\nconst WHITE = '#FFFFFF';\nconst BLANK_BACKGROUND = '#FFF2B3';\nconst WATERMARK_COLOUR = '#A00000';\nconst WATERMARK_OPACITY = 0.13;\nconst FOOT_SIZE_DROP = 1.5;\nconst COMPANY_SIZE_GAIN = 3;\nconst GRAND_SIZE_GAIN = 1;\nconst SECTION_GAP = 14;\nconst PAGE_SIZE = 'A4';\n\ntype PdfNode = Record<string, unknown>;\n\n/** The logo a PDF shows: an image data URL or SVG text. */\nexport type PdfLogo = { image: string } | { svg: string };\n\nfunction value(text: string): PdfNode {\n return text === BLANK_MARK ? { text, background: BLANK_BACKGROUND } : { text };\n}\n\nfunction labelled(label: string, text: string): PdfNode {\n return { text: [`${label}: `, value(text)] };\n}\n\nfunction titleBlock(view: InvoiceView, layout: InvoiceLayout): PdfNode {\n const [en, el] = view.creditNote ? ['CREDIT NOTE', 'ΠΙΣΤΩΤΙΚΟ ΣΗΜΕΙΩΜΑ'] : ['INVOICE', 'ΤΙΜΟΛΟΓΙΟ'];\n return {\n width: 'auto',\n alignment: layout.titleAlign,\n color: layout.accent,\n bold: true,\n stack: [{ text: en, fontSize: layout.titleSize }, { text: el, fontSize: layout.bodySize + GRAND_SIZE_GAIN }],\n };\n}\n\nfunction header(view: InvoiceView, layout: InvoiceLayout, logo?: PdfLogo): PdfNode {\n const company = {\n width: '*',\n stack: [\n ...(logo ? [{ ...logo, width: layout.logoWidth, margin: [0, 0, 0, 6] }] : []),\n { ...value(view.company.name), bold: true, fontSize: layout.bodySize + COMPANY_SIZE_GAIN, color: layout.accent },\n ...view.company.addressLines,\n labelled('Reg. No. / Αρ. Εγγραφής', view.company.regNo),\n labelled('VAT No. / Αρ. ΦΠΑ', view.company.vatNumber),\n ],\n };\n return { columns: [company, titleBlock(view, layout)], margin: [0, 0, 0, SECTION_GAP] };\n}\n\nfunction meta(view: InvoiceView, layout: InvoiceLayout): PdfNode {\n const billTo = {\n width: '*',\n stack: [\n { text: 'BILL TO / ΠΕΛΑΤΗΣ', bold: true, color: layout.accent },\n { ...value(view.client.name), bold: true },\n ...view.client.addressLines,\n ...view.client.taxLines,\n ],\n };\n const numberLabel = view.creditNote ? 'Credit Note No. / Αρ. Πιστωτικού' : 'Invoice No. / Αρ. Τιμολογίου';\n const details = {\n width: 'auto',\n stack: [\n labelled(numberLabel, view.number),\n ...(view.creditFor ? [labelled('Credits invoice / Πιστώνει το τιμολόγιο', view.creditFor)] : []),\n labelled('Date / Ημερομηνία', view.date),\n labelled('Period / Περίοδος', `${view.periodEn} / ${view.periodEl}`),\n labelled('Currency / Νόμισμα', 'EUR (€)'),\n ],\n };\n return { columns: [billTo, details], margin: [0, 0, 0, SECTION_GAP] };\n}\n\nfunction items(view: InvoiceView, layout: InvoiceLayout): PdfNode {\n const head = [\n { text: 'DESCRIPTION / ΠΕΡΙΓΡΑΦΗ', bold: true, color: WHITE, fillColor: layout.accent },\n { text: 'AMOUNT / ΠΟΣΟ (€)', bold: true, color: WHITE, fillColor: layout.accent, alignment: 'right' },\n ];\n const rows = view.rows.map((row) => [value(row.description), { text: row.amount, alignment: 'right' }]);\n return { table: { headerRows: 1, widths: ['*', 'auto'], body: [head, ...rows] }, layout: 'lightHorizontalLines', margin: [0, 0, 0, SECTION_GAP] };\n}\n\nfunction totals(view: InvoiceView, layout: InvoiceLayout): PdfNode {\n const grand = { bold: true, color: layout.accent, fillColor: layout.band, fontSize: layout.bodySize + GRAND_SIZE_GAIN };\n const grandLabel = view.creditNote ? 'TOTAL CREDIT / ΣΥΝΟΛΟ ΠΙΣΤΩΣΗΣ' : 'TOTAL DUE / ΣΥΝΟΛΟ ΠΛΗΡΩΤΕΟ';\n const body = [\n ['Net Amount / Καθαρή Αξία', { text: view.net, alignment: 'right' }],\n [view.vatLabel, { text: view.vat, alignment: 'right' }],\n [{ text: grandLabel, ...grand }, { text: `€ ${view.total}`, alignment: 'right', ...grand }],\n ];\n return { table: { widths: ['*', 'auto'], body }, layout: 'noBorders', margin: [0, 0, 0, SECTION_GAP] };\n}\n\nfunction payment(view: InvoiceView, layout: InvoiceLayout): PdfNode[] {\n if (view.creditNote) {\n return view.reason ? [labelled('Reason / Αιτιολογία', view.reason)] : [];\n }\n const rows = [\n ['Bank / Τράπεζα', view.company.bank], ['IBAN', view.company.iban], ['BIC / SWIFT', view.company.bic],\n ['Due date / Ημ. Πληρωμής', view.dueDate], ['Reference / Αιτιολογία', view.number],\n ];\n return [\n { text: 'PAYMENT DETAILS / ΣΤΟΙΧΕΙΑ ΠΛΗΡΩΜΗΣ', bold: true, color: layout.accent },\n { table: { widths: ['auto', '*'], body: rows.map(([label = '', text = '']) => [{ text: label, color: layout.muted }, value(text)]) }, layout: 'noBorders' },\n ];\n}\n\nfunction note(view: InvoiceView, layout: InvoiceLayout): PdfNode[] {\n return view.noteEn === '' && view.noteEl === '' ? [] : [{ stack: [view.noteEn, view.noteEl], color: layout.muted, margin: [0, 0, 0, SECTION_GAP] }];\n}\n\n/** Builds the pdfmake document from plain view data and a layout. */\nexport function buildPdfDefinition(view: InvoiceView, layout: InvoiceLayout, logo?: PdfLogo): PdfNode {\n const foot = `${view.company.name} · Reg. No. ${view.company.regNo} · ${view.company.addressLines.join(', ')}`;\n return {\n pageSize: PAGE_SIZE,\n pageMargins: layout.pageMargin,\n defaultStyle: { fontSize: layout.bodySize },\n ...(view.draft ? { watermark: { text: 'DRAFT', color: WATERMARK_COLOUR, opacity: WATERMARK_OPACITY, bold: true } } : {}),\n footer: { text: foot, alignment: 'center', color: layout.muted, fontSize: layout.bodySize - FOOT_SIZE_DROP },\n content: [header(view, layout, logo), meta(view, layout), items(view, layout), totals(view, layout), ...note(view, layout), ...payment(view, layout)],\n };\n}\n","import { resolveLayout, selectLayoutName } from './layouts';\nimport { buildPdfDefinition } from './pdfDefinition';\nimport type { PdfLogo } from './pdfDefinition';\nimport type { InvoiceStorage } from './storage';\nimport { InvoiceError } from './types';\nimport { buildInvoiceView } from './view';\nimport type { RenderInput } from './view';\n\nconst IMAGE_TYPES: Record<string, string> = { png: 'image/png', jpg: 'image/jpeg', jpeg: 'image/jpeg' };\nconst BASE64_CHUNK = 32768;\n\ninterface PdfDocument { getBuffer(callback: (bytes: Uint8Array) => void): void; }\ninterface PdfMake { createPdf(definition: object, layouts?: unknown, fonts?: unknown, vfs?: unknown): PdfDocument; }\ninterface FontModule { vfs?: unknown; pdfMake?: { vfs?: unknown }; }\n\nfunction unwrap<T>(module: { default?: T } & T): T {\n return module.default ?? module;\n}\n\nasync function loadPdfMake(): Promise<{ pdfMake: PdfMake; vfs: unknown }> {\n const [pdfModule, fontModule] = await Promise.all([\n import('pdfmake/build/pdfmake.js') as Promise<{ default?: PdfMake } & PdfMake>,\n import('pdfmake/build/vfs_fonts.js') as Promise<{ default?: FontModule } & FontModule>,\n ]);\n const fonts = unwrap<FontModule>(fontModule);\n return { pdfMake: unwrap<PdfMake>(pdfModule), vfs: fonts.pdfMake?.vfs ?? fonts.vfs ?? fonts };\n}\n\nfunction toBase64(bytes: Uint8Array): string {\n let binary = '';\n for (let start = 0; start < bytes.length; start += BASE64_CHUNK) {\n binary += String.fromCharCode(...bytes.subarray(start, start + BASE64_CHUNK));\n }\n return btoa(binary);\n}\n\n/** Reads the company logo for a PDF; PNG, JPG or SVG, refusing anything else or a missing file. */\nexport async function loadLogo(storage: InvoiceStorage, logo?: string): Promise<PdfLogo | undefined> {\n if (!logo) {\n return undefined;\n }\n const extension = logo.split('.').pop()?.toLowerCase() ?? '';\n const type = IMAGE_TYPES[extension];\n if (!type && extension !== 'svg') {\n throw new InvoiceError([{ path: 'company.logo', message: 'must be PNG, JPG or SVG' }]);\n }\n const bytes = await storage.readBytes(logo);\n if (!bytes) {\n throw new InvoiceError([{ path: 'company.logo', message: `file not found: ${logo}` }]);\n }\n return type ? { image: `data:${type};base64,${toBase64(bytes)}` } : { svg: new TextDecoder().decode(bytes) };\n}\n\nfunction toBytes(pdfMake: PdfMake, definition: object, vfs: unknown): Promise<Uint8Array> {\n return new Promise((resolve, reject) => {\n try {\n pdfMake.createPdf(definition, undefined, undefined, vfs).getBuffer((bytes) => resolve(new Uint8Array(bytes)));\n } catch (error) {\n reject(error instanceof Error ? error : new Error(String(error)));\n }\n });\n}\n\n/** Renders an invoice or credit note to PDF bytes with selectable Greek text. Works in browsers and Node. */\nexport async function renderInvoicePdf(storage: InvoiceStorage, input: RenderInput): Promise<Uint8Array> {\n const layout = await resolveLayout(storage, selectLayoutName(input.request, input.parties));\n const logo = await loadLogo(storage, input.parties.company.logo);\n const { pdfMake, vfs } = await loadPdfMake();\n return toBytes(pdfMake, buildPdfDefinition(buildInvoiceView(input), layout, logo), vfs);\n}\n","import { assertNoConflicts } from './conflicts';\nimport { ensureFormat, NUMBER_SHAPE, numberYear, pdfPath, readJsonFile, recordPath } from './folder';\nimport { InvoiceKind } from './InvoiceKind';\nimport { resolveLayout, selectLayoutName } from './layouts';\nimport { computeTotals, resolveLines } from './lines';\nimport { claimInvoice, nextNumber } from './numbering';\nimport { checkRequest } from './parties';\nimport { renderInvoicePdf } from './pdf';\nimport type { InvoiceStorage } from './storage';\nimport { InvoiceError } from './types';\nimport type { InvoiceRecord, InvoiceRequest, IssuedInvoice, ScheduleRef } from './types';\nimport type { RenderInput } from './view';\n\n/** The lock every number claim holds, so two tabs never take one number. */\nexport const NUMBER_LOCK = 'invoice-number';\n\n/** Renders PDF bytes; the default is renderInvoicePdf. */\nexport type PdfRender = (input: RenderInput) => Promise<Uint8Array>;\n\n/** Options for issuing; schedule marks which schedule month this came from. */\nexport interface IssueOptions { render?: PdfRender; schedule?: ScheduleRef; }\n\n/** The renderer in force for these options. */\nexport function rendererFor(storage: InvoiceStorage, options: IssueOptions): PdfRender {\n return options.render ?? ((input): Promise<Uint8Array> => renderInvoicePdf(storage, input));\n}\n\n/** Saves the record first, then its PDF; a failed PDF leaves a record that reprintInvoice can finish. */\nexport async function commitRecord(storage: InvoiceStorage, record: InvoiceRecord, pdf: Uint8Array): Promise<IssuedInvoice> {\n const savedRecord = await claimInvoice(storage, record);\n const savedPdf = pdfPath(record.number);\n try {\n await storage.writeNew(savedPdf, pdf);\n } catch {\n throw new InvoiceError([{ path: 'number', message: `${record.number} is issued but its PDF could not be saved; run: reprint --number ${record.number}` }]);\n }\n return { number: record.number, pdfPath: savedPdf, recordPath: savedRecord };\n}\n\n/** Issues a final invoice: renders first, then claims the number, so a failed render uses none. */\nexport async function issueInvoice(storage: InvoiceStorage, request: InvoiceRequest, options: IssueOptions = {}): Promise<IssuedInvoice> {\n const final = { ...request, draft: false };\n const parties = await checkRequest(storage, final);\n await resolveLayout(storage, selectLayoutName(final, parties));\n await ensureFormat(storage);\n const render = rendererFor(storage, options);\n return storage.withLock(NUMBER_LOCK, async () => {\n await assertNoConflicts(storage, final.date.slice(0, 4));\n const number = await nextNumber(storage, final.date.slice(0, 4));\n const lines = resolveLines(final, parties.client);\n const pdf = await render({ request: final, number, parties, lines });\n const totals = computeTotals(lines, parties.rule.ratePercent);\n const record: InvoiceRecord = { kind: InvoiceKind.Invoice, number, request: final, ...parties, lines, totals, ...(options.schedule ? { schedule: options.schedule } : {}) };\n return commitRecord(storage, record, pdf);\n });\n}\n\n/** Renders a draft PDF that takes no number. */\nexport async function renderDraftPdf(storage: InvoiceStorage, request: InvoiceRequest, options: IssueOptions = {}): Promise<Uint8Array> {\n const draft = { ...request, draft: true };\n const parties = await checkRequest(storage, draft);\n return rendererFor(storage, options)({ request: draft, number: null, parties });\n}\n\nfunction completeRecord(raw: Partial<InvoiceRecord> & Pick<InvoiceRecord, 'number' | 'request' | 'company' | 'client' | 'rule'>): InvoiceRecord {\n const lines = raw.lines ?? resolveLines(raw.request, raw.client);\n return { ...raw, kind: raw.kind ?? InvoiceKind.Invoice, lines, totals: raw.totals ?? computeTotals(lines, raw.rule.ratePercent) };\n}\n\n/** Reads an issued record; a record from the old layout's shape gets its kind, lines and totals. */\nexport async function readInvoice(storage: InvoiceStorage, number: string): Promise<InvoiceRecord> {\n if (!NUMBER_SHAPE.test(number)) {\n throw new InvoiceError([{ path: 'invoiceNumber', message: 'must look like 2030-001 or CN-2030-001' }]);\n }\n return completeRecord(await readJsonFile<InvoiceRecord>(storage, recordPath(number), 'invoiceNumber'));\n}\n\n/** Lists a year's issued invoices and credit notes; folders with no record are skipped. */\nexport async function listIssued(storage: InvoiceStorage, year: string): Promise<InvoiceRecord[]> {\n const names = (await storage.list(`invoices/${year}`)).filter((name) => NUMBER_SHAPE.test(name) && numberYear(name) === year);\n const present = await Promise.all(names.map(async (name) => ((await storage.readText(recordPath(name))) === null ? null : name)));\n return Promise.all(present.flatMap((name) => name ?? []).map((name) => readInvoice(storage, name)));\n}\n\n/** Recreates the missing PDF of an issued record; never replaces an existing PDF. */\nexport async function reprintInvoice(storage: InvoiceStorage, number: string, options: IssueOptions = {}): Promise<{ number: string; pdfPath: string }> {\n const record = await readInvoice(storage, number);\n const path = pdfPath(number);\n if ((await storage.readBytes(path)) !== null) {\n throw new InvoiceError([{ path: 'number', message: `${number} already has a PDF` }]);\n }\n const { company, client, rule } = record;\n const pdf = await rendererFor(storage, options)({\n request: record.request, number, parties: { company, client, rule }, lines: record.lines, kind: record.kind, creditFor: record.creditFor, reason: record.reason,\n });\n await storage.writeNew(path, pdf);\n return { number, pdfPath: path };\n}\n","import { assertNoConflicts } from './conflicts';\nimport { ensureFormat, numberYear } from './folder';\nimport { InvoiceKind } from './InvoiceKind';\nimport { commitRecord, listIssued, NUMBER_LOCK, readInvoice, rendererFor } from './issue';\nimport type { IssueOptions } from './issue';\nimport { computeTotals } from './lines';\nimport { centsToAmount, toCents } from './money';\nimport { nextNumber } from './numbering';\nimport type { InvoiceStorage } from './storage';\nimport { InvoiceError } from './types';\nimport type { InvoiceRecord, IssuedInvoice } from './types';\nimport { isBlank, isRealDate } from './validate';\n\n/** What to credit. Without an amount the credit note covers all the invoice has left. */\nexport interface CreditNoteRequest { invoiceNumber: string; date: string; reason: string; amount?: string; }\n\nfunction checkInput(input: CreditNoteRequest): void {\n if (isBlank(input.reason)) {\n throw new InvoiceError([{ path: 'reason', message: 'required for a credit note' }]);\n }\n if (!isRealDate(input.date)) {\n throw new InvoiceError([{ path: 'date', message: 'must be a real date as YYYY-MM-DD' }]);\n }\n}\n\nasync function creditedSoFar(storage: InvoiceStorage, invoice: InvoiceRecord, date: string): Promise<number> {\n const first = Number(numberYear(invoice.number));\n const last = Number(date.slice(0, 4));\n const years = Array.from({ length: Math.max(last - first + 1, 0) }, (_, i) => String(first + i));\n const records = (await Promise.all(years.map((year) => listIssued(storage, year)))).flat();\n return records.filter((record) => record.creditFor === invoice.number).reduce((sum, record) => sum + record.totals.netCents, 0);\n}\n\nfunction creditCents(input: CreditNoteRequest, remaining: number): number {\n const cents = input.amount === undefined ? remaining : toCents(input.amount);\n if (cents === null || cents <= 0 || cents > remaining) {\n throw new InvoiceError([{ path: 'amount', message: `must be more than zero and at most ${centsToAmount(remaining)}` }]);\n }\n return cents;\n}\n\nfunction checkTarget(invoice: InvoiceRecord, input: CreditNoteRequest): void {\n if (invoice.kind !== InvoiceKind.Invoice) {\n throw new InvoiceError([{ path: 'invoiceNumber', message: `${invoice.number} is a credit note; only an invoice can be credited` }]);\n }\n if (input.date < invoice.request.date) {\n throw new InvoiceError([{ path: 'date', message: `must not be before the invoice date ${invoice.request.date}` }]);\n }\n}\n\n/** Issues a credit note that references its invoice and takes its own gap-free CN- number. */\nexport async function issueCreditNote(storage: InvoiceStorage, input: CreditNoteRequest, options: IssueOptions = {}): Promise<IssuedInvoice> {\n checkInput(input);\n await ensureFormat(storage);\n const invoice = await readInvoice(storage, input.invoiceNumber);\n checkTarget(invoice, input);\n const render = rendererFor(storage, options);\n return storage.withLock(NUMBER_LOCK, async () => {\n await assertNoConflicts(storage, input.date.slice(0, 4));\n const remaining = invoice.totals.netCents - (await creditedSoFar(storage, invoice, input.date));\n const cents = creditCents(input, remaining);\n const number = await nextNumber(storage, input.date.slice(0, 4), InvoiceKind.CreditNote);\n const description = `Credit for invoice ${invoice.number}: ${input.reason}`;\n const lines = [{ description, cents }];\n const { company, client, rule } = invoice;\n const request = { ...invoice.request, date: input.date, amounts: [], lines: [{ description, amount: centsToAmount(cents) }], draft: false };\n const shared = { kind: InvoiceKind.CreditNote, creditFor: invoice.number, reason: input.reason, lines } as const;\n const pdf = await render({ request, number, parties: { company, client, rule }, ...shared, lines });\n return commitRecord(storage, { number, request, company, client, rule, ...shared, lines, totals: computeTotals(lines, rule.ratePercent) }, pdf);\n });\n}\n","import { listIssued } from './issue';\nimport { InvoiceKind } from './InvoiceKind';\nimport { centsToAmount } from './money';\nimport type { InvoiceStorage } from './storage';\nimport { InvoiceError } from './types';\nimport type { InvoiceRecord } from './types';\n\nconst BOM = '';\nconst NEWLINE = '\\r\\n';\nconst MONTHS_PER_QUARTER = 3;\nconst LAST_QUARTER = 4;\nconst YEAR = /^\\d{4}$/;\nconst FORMULA_START = /^[=+\\-@\\t\\r]/;\nconst NEEDS_QUOTES = /[\",\\r\\n]/;\nconst HEADER = ['number', 'kind', 'date', 'period', 'client', 'client_vat', 'net', 'vat', 'total', 'currency', 'vat_rule', 'credit_for', 'reason'];\nconst CURRENCY = 'EUR';\n\nfunction textCell(value: string): string {\n const safe = FORMULA_START.test(value) ? `'${value}` : value;\n return NEEDS_QUOTES.test(safe) ? `\"${safe.split('\"').join('\"\"')}\"` : safe;\n}\n\nfunction toRow(record: InvoiceRecord): string {\n const sign = record.kind === InvoiceKind.CreditNote ? -1 : 1;\n const { netCents, vatCents, totalCents } = record.totals;\n return [\n record.number, record.kind, record.request.date, record.request.period, textCell(record.client.name), textCell(record.client.vatNumber),\n centsToAmount(sign * netCents), centsToAmount(sign * vatCents), centsToAmount(sign * totalCents), CURRENCY,\n textCell(record.rule.id), record.creditFor ?? '', textCell(record.reason ?? ''),\n ].join(',');\n}\n\nfunction inQuarter(record: InvoiceRecord, quarter: number): boolean {\n const month = Number(record.request.date.slice(5, 7));\n return Math.ceil(month / MONTHS_PER_QUARTER) === quarter;\n}\n\nfunction byDateThenNumber(a: InvoiceRecord, b: InvoiceRecord): number {\n return a.request.date.localeCompare(b.request.date) || a.number.localeCompare(b.number);\n}\n\n/** The accountant's CSV of one quarter's invoices and credit notes, by date; credit notes are negative. */\nexport async function exportQuarterCsv(storage: InvoiceStorage, year: string, quarter: number): Promise<string> {\n if (!Number.isInteger(quarter) || quarter < 1 || quarter > LAST_QUARTER) {\n throw new InvoiceError([{ path: 'quarter', message: 'must be 1, 2, 3 or 4' }]);\n }\n if (!YEAR.test(year)) {\n throw new InvoiceError([{ path: 'year', message: 'must be YYYY' }]);\n }\n const records = (await listIssued(storage, year)).filter((record) => inQuarter(record, quarter)).sort(byDateThenNumber);\n return `${BOM}${[HEADER.join(','), ...records.map(toRow)].join(NEWLINE)}${NEWLINE}`;\n}\n","export const enum FolderOpenState {\n New = 'new',\n Existing = 'existing',\n Legacy = 'legacy',\n Foreign = 'foreign',\n}\n","import { StorageExistsError } from './storage';\nimport type { InvoiceStorage } from './storage';\n\nfunction toBytes(data: string | Uint8Array): Uint8Array {\n return typeof data === 'string' ? new TextEncoder().encode(data) : data;\n}\n\nfunction childName(path: string, prefix: string): string[] {\n return path.startsWith(prefix) ? [path.slice(prefix.length).split('/')[0] ?? ''] : [];\n}\n\n/** Creates an in-memory storage, for tests and previews. */\nexport function createMemoryStorage(initial: Record<string, string | Uint8Array> = {}): InvoiceStorage {\n const files = new Map(Object.entries(initial).map(([path, data]) => [path, toBytes(data)]));\n const queues = new Map<string, Promise<unknown>>();\n return {\n readText: (path): Promise<string | null> => {\n const bytes = files.get(path);\n return Promise.resolve(bytes ? new TextDecoder().decode(bytes) : null);\n },\n readBytes: (path): Promise<Uint8Array | null> => Promise.resolve(files.get(path) ?? null),\n list: (dir): Promise<string[]> => {\n const prefix = dir === '' ? '' : `${dir}/`;\n return Promise.resolve([...new Set([...files.keys()].flatMap((path) => childName(path, prefix)))].sort((a, b) => a.localeCompare(b)));\n },\n writeNew: (path, data): Promise<void> => {\n if (files.has(path)) {\n return Promise.reject(new StorageExistsError(path));\n }\n files.set(path, toBytes(data));\n return Promise.resolve();\n },\n replace: (path, data): Promise<void> => {\n files.set(path, toBytes(data));\n return Promise.resolve();\n },\n remove: (path): Promise<void> => {\n files.delete(path);\n return Promise.resolve();\n },\n withLock: <T>(name: string, work: () => Promise<T>): Promise<T> => {\n const run = (queues.get(name) ?? Promise.resolve()).then(work, work);\n queues.set(name, run.catch(() => undefined));\n return run;\n },\n };\n}\n","import { ensureFormat, FORMAT_PATH, isOsFile } from './folder';\nimport { FolderOpenState } from './FolderOpenState';\nimport type { InvoiceStorage } from './storage';\n\nconst DATA_ENTRIES = new Set(['company.json', 'clients', 'invoices', 'rules', 'layouts', 'schedules']);\nconst LEGACY_YEAR = /^\\d{4}$/;\n\n/** Opens a picked folder: an empty one gets the format, anything else unrecognised is left untouched. */\nexport async function openDataFolder(storage: InvoiceStorage): Promise<FolderOpenState> {\n const names = (await storage.list('')).filter((name) => !isOsFile(name));\n if (names.includes(FORMAT_PATH)) {\n await ensureFormat(storage);\n return FolderOpenState.Existing;\n }\n if (names.length === 0) {\n await ensureFormat(storage);\n return FolderOpenState.New;\n }\n return names.some((name) => DATA_ENTRIES.has(name) || LEGACY_YEAR.test(name)) ? FolderOpenState.Legacy : FolderOpenState.Foreign;\n}\n","export const enum PaymentState {\n Paid = 'paid',\n Unpaid = 'unpaid',\n Overdue = 'overdue',\n}\n","import { invoiceDir, readJsonFile, toJson } from './folder';\nimport { InvoiceKind } from './InvoiceKind';\nimport { readInvoice } from './issue';\nimport { PaymentState } from './PaymentState';\nimport { addDays } from './period';\nimport type { InvoiceStorage } from './storage';\nimport { InvoiceError } from './types';\nimport type { InvoiceRecord } from './types';\nimport { isRealDate } from './validate';\n\nconst STATUS_LOCK = 'invoice-status';\n\nexport interface PaymentStatus {\n paidOn: string | null;\n}\n\nfunction statusPath(number: string): string {\n return `${invoiceDir(number)}/status.json`;\n}\n\n/** Reads an invoice's payment status from its status.json; no file means unpaid. */\nexport async function readPaymentStatus(storage: InvoiceStorage, number: string): Promise<PaymentStatus> {\n const path = statusPath(number);\n if ((await storage.readText(path)) === null) {\n return { paidOn: null };\n }\n const { paidOn } = await readJsonFile<{ paidOn?: unknown }>(storage, path, 'status');\n return { paidOn: typeof paidOn === 'string' ? paidOn : null };\n}\n\n/** Records a payment date in status.json; the issued record is never touched. */\nexport async function markPaid(storage: InvoiceStorage, number: string, paidOn: string): Promise<void> {\n if (!isRealDate(paidOn)) {\n throw new InvoiceError([{ path: 'paidOn', message: 'must be a real date as YYYY-MM-DD' }]);\n }\n const record = await readInvoice(storage, number);\n if (record.kind !== InvoiceKind.Invoice) {\n throw new InvoiceError([{ path: 'number', message: `${number} is a credit note; only an invoice can be paid` }]);\n }\n if (paidOn < record.request.date) {\n throw new InvoiceError([{ path: 'paidOn', message: `must not be before the invoice date ${record.request.date}` }]);\n }\n const payment: PaymentStatus = { paidOn };\n await storage.withLock(STATUS_LOCK, () => storage.replace(statusPath(number), toJson(payment)));\n}\n\n/** Removes a recorded payment; the issued record is never touched. */\nexport async function markUnpaid(storage: InvoiceStorage, number: string): Promise<void> {\n await storage.withLock(STATUS_LOCK, () => storage.remove(statusPath(number)));\n}\n\n/** Says whether an invoice is paid, unpaid or overdue today; overdue starts the day after the due date. */\nexport function paymentStateOf(record: InvoiceRecord, status: PaymentStatus, today: string): PaymentState {\n if (status.paidOn !== null) {\n return PaymentState.Paid;\n }\n const terms = record.client.paymentTermsDays;\n const overdue = typeof terms === 'number' && today > addDays(record.request.date, terms);\n return overdue ? PaymentState.Overdue : PaymentState.Unpaid;\n}\n","import { ensureFormat, readJsonFile, toJson } from './folder';\nimport { issueInvoice, listIssued } from './issue';\nimport type { PdfRender } from './issue';\nimport { expandDescription } from './lines';\nimport { toCents } from './money';\nimport { loadParties } from './parties';\nimport { isStorageExistsError } from './storage';\nimport type { InvoiceStorage } from './storage';\nimport { InvoiceError } from './types';\nimport type { FieldError, InvoiceLine } from './types';\nimport { isRealDate, validateLines } from './validate';\n\nconst MONTHS_IN_YEAR = 12;\nconst YEAR = /^\\d{4}$/;\nconst SAFE_ID = /^[\\w-]+$/;\n\n/** One month of a schedule: a draft until number is set. */\nexport interface ScheduleMonth { period: string; lines: InvoiceLine[]; number: string | null; issuedOn: string | null; }\n\n/** A client's yearly schedule, stored in schedules/<id>.json. */\nexport interface InvoiceSchedule { id: string; clientId: string; year: string; months: ScheduleMonth[]; }\n\n/** What to prepare: a client and the amount each month starts with. */\nexport interface PrepareScheduleRequest { clientId: string; year: string; monthlyAmount: string; }\n\n/** The clock and renderer for issuing due months. */\nexport interface IssueDueOptions { today: string; render?: PdfRender; }\n\n/** What issuing due months did; a failure stops the run and leaves the rest as drafts. */\nexport interface IssueDueResult {\n issued: { period: string; number: string }[];\n failed: { period: string; errors: FieldError[] } | null;\n remaining: string[];\n}\n\nfunction schedulePath(id: string): string {\n return `schedules/${id}.json`;\n}\n\nfunction lockName(id: string): string {\n return `schedule-${id}`;\n}\n\nfunction checkPrepare(request: PrepareScheduleRequest): void {\n if (!YEAR.test(request.year)) {\n throw new InvoiceError([{ path: 'year', message: 'must be YYYY' }]);\n }\n if (!toCents(request.monthlyAmount)) {\n throw new InvoiceError([{ path: 'monthlyAmount', message: 'must look like 2952 or 2952.50 and be more than zero' }]);\n }\n}\n\n/** Prepares 12 drafts with no numbers from a client and a monthly amount; a second call for that year is refused. */\nexport async function prepareYearSchedule(storage: InvoiceStorage, request: PrepareScheduleRequest): Promise<InvoiceSchedule> {\n checkPrepare(request);\n const { client } = await loadParties(storage, request.clientId);\n await ensureFormat(storage);\n const months = Array.from({ length: MONTHS_IN_YEAR }, (_, i): ScheduleMonth => {\n const period = `${request.year}-${String(i + 1).padStart(2, '0')}`;\n return { period, lines: [{ description: expandDescription(client.description, period), amount: request.monthlyAmount }], number: null, issuedOn: null };\n });\n const schedule: InvoiceSchedule = { id: `${request.clientId}-${request.year}`, clientId: request.clientId, year: request.year, months };\n try {\n await storage.writeNew(schedulePath(schedule.id), toJson(schedule));\n } catch (error) {\n if (isStorageExistsError(error)) {\n throw new InvoiceError([{ path: 'schedule', message: `${schedule.id} is already prepared` }]);\n }\n throw error;\n }\n return schedule;\n}\n\n/** Reads a schedule by id. */\nexport async function readSchedule(storage: InvoiceStorage, id: string): Promise<InvoiceSchedule> {\n if (!SAFE_ID.test(id)) {\n throw new InvoiceError([{ path: 'schedule', message: 'must hold only letters, digits, - and _' }]);\n }\n return readJsonFile<InvoiceSchedule>(storage, schedulePath(id), 'schedule');\n}\n\n/** Changes a draft month's lines; an issued month is refused and named. */\nexport async function editScheduleMonth(storage: InvoiceStorage, id: string, period: string, lines: InvoiceLine[]): Promise<InvoiceSchedule> {\n const errors = validateLines(lines);\n if (errors.length > 0) {\n throw new InvoiceError(errors);\n }\n return storage.withLock(lockName(id), async () => {\n const schedule = await readSchedule(storage, id);\n const month = schedule.months.find((entry) => entry.period === period);\n if (!month || month.number !== null) {\n const message = month ? `is issued as ${String(month.number)} and cannot change` : 'is not in this schedule';\n throw new InvoiceError([{ path: `months.${period}`, message }]);\n }\n const updated = { ...schedule, months: schedule.months.map((entry) => (entry === month ? { ...entry, lines } : entry)) };\n await storage.replace(schedulePath(id), toJson(updated));\n return updated;\n });\n}\n\nasync function reconcile(storage: InvoiceStorage, schedule: InvoiceSchedule, today: string): Promise<InvoiceSchedule> {\n const first = Number(schedule.year);\n const last = Math.max(Number(today.slice(0, 4)), first);\n const years = Array.from({ length: last - first + 1 }, (_, i) => String(first + i));\n const records = (await Promise.all(years.map((year) => listIssued(storage, year)))).flat().filter((record) => record.schedule?.id === schedule.id);\n const months = schedule.months.map((month) => {\n const record = records.find((entry) => entry.schedule?.period === month.period);\n return month.number === null && record ? { ...month, number: record.number, issuedOn: record.request.date } : month;\n });\n const changed = months.some((month, i) => month !== schedule.months[i]);\n const updated = { ...schedule, months };\n if (changed) {\n await storage.replace(schedulePath(schedule.id), toJson(updated));\n }\n return updated;\n}\n\nfunction toFieldErrors(error: unknown): FieldError[] {\n if (error instanceof InvoiceError) {\n return error.errors;\n }\n return [{ path: 'issue', message: error instanceof Error ? error.message : String(error) }];\n}\n\nasync function issueRun(storage: InvoiceStorage, start: InvoiceSchedule, options: IssueDueOptions): Promise<IssueDueResult> {\n const due = start.months.filter((month) => month.number === null && month.period < options.today.slice(0, 7));\n const result: IssueDueResult = { issued: [], failed: null, remaining: due.map((month) => month.period) };\n let schedule = start;\n for (const month of due) {\n try {\n const request = { clientId: start.clientId, period: month.period, date: options.today, amounts: [], lines: month.lines, draft: false };\n const { number } = await issueInvoice(storage, request, { render: options.render, schedule: { id: start.id, period: month.period } });\n result.issued.push({ period: month.period, number });\n result.remaining = result.remaining.filter((period) => period !== month.period);\n schedule = { ...schedule, months: schedule.months.map((entry) => (entry.period === month.period ? { ...entry, number, issuedOn: options.today } : entry)) };\n await storage.replace(schedulePath(start.id), toJson(schedule));\n } catch (error) {\n result.failed = { period: month.period, errors: toFieldErrors(error) };\n break;\n }\n }\n return result;\n}\n\n/** Issues finished months in order, each with its own number, dated today; stops at the first failure. */\nexport async function issueDueMonths(storage: InvoiceStorage, id: string, options: IssueDueOptions): Promise<IssueDueResult> {\n if (!isRealDate(options.today)) {\n throw new InvoiceError([{ path: 'today', message: 'must be a real date as YYYY-MM-DD' }]);\n }\n return storage.withLock(lockName(id), async () => issueRun(storage, await reconcile(storage, await readSchedule(storage, id), options.today), options));\n}\n"]}
|