351 lines
7.4 KiB
TypeScript
351 lines
7.4 KiB
TypeScript
|
import type { TSKRType } from './skr.types.js';
|
||
|
|
||
|
/**
|
||
|
* Invoice direction
|
||
|
*/
|
||
|
export type TInvoiceDirection = 'inbound' | 'outbound';
|
||
|
|
||
|
/**
|
||
|
* Supported e-invoice formats
|
||
|
*/
|
||
|
export type TInvoiceFormat = 'xrechnung' | 'zugferd' | 'facturx' | 'peppol' | 'ubl';
|
||
|
|
||
|
/**
|
||
|
* Invoice status in the system
|
||
|
*/
|
||
|
export type TInvoiceStatus = 'draft' | 'validated' | 'posted' | 'partially_paid' | 'paid' | 'cancelled' | 'error';
|
||
|
|
||
|
/**
|
||
|
* Tax scenario classification
|
||
|
*/
|
||
|
export type TTaxScenario =
|
||
|
| 'domestic_taxed' // Standard domestic with VAT
|
||
|
| 'domestic_exempt' // Domestic tax-exempt
|
||
|
| 'reverse_charge' // §13b UStG
|
||
|
| 'intra_eu_supply' // Intra-EU supply
|
||
|
| 'intra_eu_acquisition' // Intra-EU acquisition
|
||
|
| 'export' // Export outside EU
|
||
|
| 'small_business'; // §19 UStG small business
|
||
|
|
||
|
/**
|
||
|
* VAT rate categories
|
||
|
*/
|
||
|
export interface IVATCategory {
|
||
|
code: string; // S (Standard), Z (Zero), E (Exempt), AE (Reverse charge), etc.
|
||
|
rate: number; // Tax rate percentage
|
||
|
exemptionReason?: string;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Party information (supplier/customer)
|
||
|
*/
|
||
|
export interface IInvoiceParty {
|
||
|
id: string;
|
||
|
name: string;
|
||
|
address: {
|
||
|
street?: string;
|
||
|
city?: string;
|
||
|
postalCode?: string;
|
||
|
countryCode: string;
|
||
|
};
|
||
|
vatId?: string;
|
||
|
taxId?: string;
|
||
|
email?: string;
|
||
|
phone?: string;
|
||
|
bankAccount?: {
|
||
|
iban: string;
|
||
|
bic?: string;
|
||
|
accountHolder?: string;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Invoice line item
|
||
|
*/
|
||
|
export interface IInvoiceLine {
|
||
|
lineNumber: number;
|
||
|
description: string;
|
||
|
quantity: number;
|
||
|
unitPrice: number;
|
||
|
netAmount: number;
|
||
|
vatCategory: IVATCategory;
|
||
|
vatAmount: number;
|
||
|
grossAmount: number;
|
||
|
accountNumber?: string; // SKR account for booking
|
||
|
costCenter?: string;
|
||
|
productCode?: string;
|
||
|
allowances?: IAllowanceCharge[];
|
||
|
charges?: IAllowanceCharge[];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Allowance or charge
|
||
|
*/
|
||
|
export interface IAllowanceCharge {
|
||
|
reason: string;
|
||
|
amount: number;
|
||
|
percentage?: number;
|
||
|
vatCategory?: IVATCategory;
|
||
|
vatAmount?: number;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Payment terms
|
||
|
*/
|
||
|
export interface IPaymentTerms {
|
||
|
dueDate: Date;
|
||
|
paymentTermsNote?: string;
|
||
|
skonto?: {
|
||
|
percentage: number;
|
||
|
days: number;
|
||
|
baseAmount: number;
|
||
|
}[];
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Validation result
|
||
|
*/
|
||
|
export interface IValidationResult {
|
||
|
isValid: boolean;
|
||
|
syntax: {
|
||
|
valid: boolean;
|
||
|
errors: string[];
|
||
|
warnings: string[];
|
||
|
};
|
||
|
semantic: {
|
||
|
valid: boolean;
|
||
|
errors: string[];
|
||
|
warnings: string[];
|
||
|
};
|
||
|
businessRules: {
|
||
|
valid: boolean;
|
||
|
errors: string[];
|
||
|
warnings: string[];
|
||
|
};
|
||
|
countrySpecific?: {
|
||
|
valid: boolean;
|
||
|
errors: string[];
|
||
|
warnings: string[];
|
||
|
};
|
||
|
validatedAt: Date;
|
||
|
validatorVersion: string;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Booking information
|
||
|
*/
|
||
|
export interface IBookingInfo {
|
||
|
journalEntryId: string;
|
||
|
transactionIds: string[];
|
||
|
bookedAt: Date;
|
||
|
bookedBy: string;
|
||
|
bookingRules: {
|
||
|
vendorAccount?: string;
|
||
|
customerAccount?: string;
|
||
|
expenseAccounts?: string[];
|
||
|
revenueAccounts?: string[];
|
||
|
vatAccounts?: string[];
|
||
|
};
|
||
|
confidence: number; // 0-100
|
||
|
autoBooked: boolean;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Payment information
|
||
|
*/
|
||
|
export interface IPaymentInfo {
|
||
|
paymentId: string;
|
||
|
paymentDate: Date;
|
||
|
amount: number;
|
||
|
currency: string;
|
||
|
bankTransactionId?: string;
|
||
|
endToEndId?: string;
|
||
|
remittanceInfo?: string;
|
||
|
skontoTaken?: number;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Main invoice entity
|
||
|
*/
|
||
|
export interface IInvoice {
|
||
|
// Identity
|
||
|
id: string;
|
||
|
direction: TInvoiceDirection;
|
||
|
format: TInvoiceFormat;
|
||
|
|
||
|
// EN16931 Business Terms
|
||
|
invoiceNumber: string; // BT-1
|
||
|
issueDate: Date; // BT-2
|
||
|
invoiceTypeCode?: string; // BT-3 (380=Invoice, 381=Credit note)
|
||
|
currencyCode: string; // BT-5
|
||
|
taxCurrencyCode?: string; // BT-6
|
||
|
taxPointDate?: Date; // BT-7 (Leistungsdatum)
|
||
|
paymentDueDate?: Date; // BT-9
|
||
|
buyerReference?: string; // BT-10
|
||
|
projectReference?: string; // BT-11
|
||
|
contractReference?: string; // BT-12
|
||
|
orderReference?: string; // BT-13
|
||
|
sellerOrderReference?: string; // BT-14
|
||
|
|
||
|
// Parties
|
||
|
supplier: IInvoiceParty;
|
||
|
customer: IInvoiceParty;
|
||
|
payee?: IInvoiceParty; // If different from supplier
|
||
|
|
||
|
// Line items
|
||
|
lines: IInvoiceLine[];
|
||
|
|
||
|
// Document level allowances/charges
|
||
|
allowances?: IAllowanceCharge[];
|
||
|
charges?: IAllowanceCharge[];
|
||
|
|
||
|
// Amounts
|
||
|
lineNetAmount: number; // Sum of line net amounts
|
||
|
allowanceTotalAmount?: number;
|
||
|
chargeTotalAmount?: number;
|
||
|
taxExclusiveAmount: number; // BT-109
|
||
|
taxInclusiveAmount: number; // BT-112
|
||
|
prepaidAmount?: number; // BT-113
|
||
|
payableAmount: number; // BT-115
|
||
|
|
||
|
// VAT breakdown
|
||
|
vatBreakdown: {
|
||
|
vatCategory: IVATCategory;
|
||
|
taxableAmount: number; // BT-116
|
||
|
taxAmount: number; // BT-117
|
||
|
}[];
|
||
|
totalVATAmount: number; // BT-110
|
||
|
|
||
|
// Payment
|
||
|
paymentTerms?: IPaymentTerms;
|
||
|
paymentMeans?: {
|
||
|
code: string; // 30=Bank transfer, 48=Card, etc.
|
||
|
account?: IInvoiceParty['bankAccount'];
|
||
|
};
|
||
|
payments?: IPaymentInfo[];
|
||
|
|
||
|
// Notes
|
||
|
invoiceNote?: string; // BT-22
|
||
|
|
||
|
// Processing metadata
|
||
|
status: TInvoiceStatus;
|
||
|
taxScenario?: TTaxScenario;
|
||
|
skrType?: TSKRType;
|
||
|
|
||
|
// Storage
|
||
|
contentHash: string; // SHA-256 of normalized XML
|
||
|
xmlContent?: string;
|
||
|
pdfHash?: string;
|
||
|
pdfContent?: Buffer;
|
||
|
|
||
|
// Validation
|
||
|
validationResult?: IValidationResult;
|
||
|
|
||
|
// Booking
|
||
|
bookingInfo?: IBookingInfo;
|
||
|
|
||
|
// Audit trail
|
||
|
createdAt: Date;
|
||
|
createdBy: string;
|
||
|
modifiedAt?: Date;
|
||
|
modifiedBy?: string;
|
||
|
|
||
|
// Additional metadata
|
||
|
metadata?: {
|
||
|
importSource?: string;
|
||
|
importedAt?: Date;
|
||
|
parserVersion?: string;
|
||
|
originalFilename?: string;
|
||
|
originalFormat?: string;
|
||
|
[key: string]: any;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Invoice import options
|
||
|
*/
|
||
|
export interface IInvoiceImportOptions {
|
||
|
autoBook?: boolean;
|
||
|
confidenceThreshold?: number;
|
||
|
validateOnly?: boolean;
|
||
|
skipDuplicateCheck?: boolean;
|
||
|
bookingRules?: {
|
||
|
vendorDefaults?: Record<string, string>;
|
||
|
customerDefaults?: Record<string, string>;
|
||
|
productCategoryMapping?: Record<string, string>;
|
||
|
};
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Invoice export options
|
||
|
*/
|
||
|
export interface IInvoiceExportOptions {
|
||
|
format: TInvoiceFormat;
|
||
|
embedInPdf?: boolean;
|
||
|
sign?: boolean;
|
||
|
validate?: boolean;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Invoice search filter
|
||
|
*/
|
||
|
export interface IInvoiceFilter {
|
||
|
direction?: TInvoiceDirection;
|
||
|
status?: TInvoiceStatus;
|
||
|
format?: TInvoiceFormat;
|
||
|
dateFrom?: Date;
|
||
|
dateTo?: Date;
|
||
|
supplierId?: string;
|
||
|
customerId?: string;
|
||
|
minAmount?: number;
|
||
|
maxAmount?: number;
|
||
|
invoiceNumber?: string;
|
||
|
reference?: string;
|
||
|
isPaid?: boolean;
|
||
|
isOverdue?: boolean;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Duplicate check result
|
||
|
*/
|
||
|
export interface IDuplicateCheckResult {
|
||
|
isDuplicate: boolean;
|
||
|
matchedInvoiceId?: string;
|
||
|
matchedContentHash?: string;
|
||
|
matchedFields?: string[];
|
||
|
confidence: number;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Booking rules configuration
|
||
|
*/
|
||
|
export interface IBookingRules {
|
||
|
skrType: TSKRType;
|
||
|
|
||
|
// Control accounts
|
||
|
vendorControlAccount: string;
|
||
|
customerControlAccount: string;
|
||
|
|
||
|
// VAT accounts
|
||
|
vatAccounts: {
|
||
|
inputVAT19: string;
|
||
|
inputVAT7: string;
|
||
|
outputVAT19: string;
|
||
|
outputVAT7: string;
|
||
|
reverseChargeVAT: string;
|
||
|
};
|
||
|
|
||
|
// Default accounts
|
||
|
defaultExpenseAccount: string;
|
||
|
defaultRevenueAccount: string;
|
||
|
|
||
|
// Mappings
|
||
|
productCategoryMapping?: Record<string, string>;
|
||
|
vendorMapping?: Record<string, string>;
|
||
|
customerMapping?: Record<string, string>;
|
||
|
|
||
|
// Skonto
|
||
|
skontoMethod?: 'net' | 'gross';
|
||
|
skontoExpenseAccount?: string;
|
||
|
skontoRevenueAccount?: string;
|
||
|
}
|