{"version":3,"sources":["../src/value-objects/Money.ts","../src/value-objects/CustomerInfo.ts","../src/value-objects/OrderItem.ts","../src/types/errors.ts","../src/types/shared.ts","../src/types/index.ts","../src/value-objects/ShippingCost.ts","../src/events/InvoiceEvents.ts","../src/events/index.ts","../src/services/InvoiceIdGenerator.default.ts","../src/entities/aggregate-root.ts","../src/entities/InvoiceDraft.ts","../src/entities/Invoice.ts","../src/value-objects/index.ts","../src/value-objects/Financials.ts","../src/index.ts","../src/entities/index.ts","../src/services/InvoiceNumberValidator.ts","../src/services/PDFRenderer.ts","../src/services/InvoiceNumberGenerator.ts"],"sourcesContent":["import type { Currency } from \"./Currency\";\n\nexport type MoneyPlainObject = { amount: number; currency: string };\n\n/**\n * Money value object representing monetary amounts with currency\n * Stores amounts in cents to avoid floating point precision issues\n */\nexport class Money {\n  private static readonly EUR_RATES: Record<Currency, number> = {\n    EUR: 1,\n    USD: 0.92,\n  };\n\n  /**\n   * Constructs a new Money value with 0 amount.\n   * @param currency The currency to create the menu in.\n   */\n  static zero(currency: Currency): Money {\n    return new Money(0, currency);\n  }\n\n  constructor(\n    public readonly amount: number, // in cents\n    public readonly currency: Currency\n  ) {\n    if (amount < 0) {\n      throw new Error(\"Money amount cannot be negative\");\n    }\n    if (!currency || currency.length !== 3) {\n      throw new Error(\"Currency must be a valid 3-letter code\");\n    }\n    if (!Number.isInteger(amount)) {\n      throw new Error(\"Money amount must be an integer (cents)\");\n    }\n  }\n\n  /**\n   * Convert this money amount to EUR\n   */\n  toEUR(): number {\n    const rate = Money.EUR_RATES[this.currency];\n    if (!rate) {\n      throw new Error(`Unsupported currency: ${this.currency}`);\n    }\n    return Math.round(this.amount * rate);\n  }\n\n  /**\n   * Create Money from EUR amount\n   */\n  static fromEUR(amount: number, targetCurrency: Currency): Money {\n    const rate = Money.EUR_RATES[targetCurrency];\n    if (!rate) {\n      throw new Error(`Unsupported currency: ${targetCurrency}`);\n    }\n    const convertedAmount = Math.round(amount / rate);\n    return new Money(convertedAmount, targetCurrency);\n  }\n\n  /**\n   * Add two money amounts (must be same currency)\n   */\n  add(...others: Money[]): Money {\n    const currency = this.currency;\n    let total: number = this.amount;\n    for (const other of others) {\n      if (this.currency !== other.currency) {\n        throw new Error(\"Cannot add money with different currencies\");\n      }\n      total += other.amount;\n    }\n    return new Money(total, currency);\n  }\n\n  /**\n   * Subtract two money amounts (must be same currency)\n   */\n  subtract(other: Money): Money {\n    if (this.currency !== other.currency) {\n      throw new Error(\"Cannot subtract money with different currencies\");\n    }\n    const result = this.amount - other.amount;\n    if (result < 0) {\n      throw new Error(\"Subtraction would result in negative amount\");\n    }\n    return new Money(result, this.currency);\n  }\n\n  /**\n   * Multiply money by a factor\n   */\n  multiply(factor: number): Money {\n    if (factor < 0) {\n      throw new Error(\"Cannot multiply money by negative factor\");\n    }\n    return new Money(Math.round(this.amount * factor), this.currency);\n  }\n\n  /**\n   * Check if two money amounts are equal\n   */\n  equals(other: Money): boolean {\n    return this.amount === other.amount && this.currency === other.currency;\n  }\n\n  /**\n   * Get the amount in the major currency unit (e.g., euros instead of cents)\n   */\n  toMajorUnit(): number {\n    return this.amount / 100;\n  }\n\n  /**\n   * Create Money from major currency unit\n   */\n  static fromMajorUnit(amount: number, currency: Currency): Money {\n    return new Money(Math.round(amount * 100), currency);\n  }\n\n  /**\n   * String representation\n   */\n  toString(): string {\n    return `${this.toMajorUnit().toFixed(2)} ${this.currency}`;\n  }\n\n  /**\n   * Convert to plain object for serialization\n   */\n  toPlainObject(): { amount: number; currency: string } {\n    return {\n      amount: this.amount,\n      currency: this.currency,\n    };\n  }\n}\n","/**\n * CustomerInfo value object representing customer data snapshot\n * Immutable snapshot of customer information at invoice creation time\n */\nexport class CustomerInfo {\n  constructor(\n    public readonly firstName: string,\n    public readonly lastName: string,\n    public readonly street: string,\n    public readonly zip: string,\n    public readonly city: string,\n    public readonly country: string,\n    public readonly email: string,\n    public readonly phone?: string\n  ) {\n    this.validate();\n  }\n\n  private validate(): void {\n    if (!this.firstName?.trim()) {\n      throw new Error('First name is required');\n    }\n    if (!this.lastName?.trim()) {\n      throw new Error('Last name is required');\n    }\n    if (!this.street?.trim()) {\n      throw new Error('Street address is required');\n    }\n    if (!this.zip?.trim()) {\n      throw new Error('ZIP code is required');\n    }\n    if (!this.city?.trim()) {\n      throw new Error('City is required');\n    }\n    if (!this.country?.trim()) {\n      throw new Error('Country is required');\n    }\n    if (!this.email?.trim()) {\n      throw new Error('Email is required');\n    }\n\n    // Validate email format\n    const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\n    if (!emailRegex.test(this.email)) {\n      throw new Error('Invalid email format');\n    }\n\n    // Validate phone format if provided\n    if (this.phone && this.phone.trim()) {\n      const phoneRegex = /^[\\+]?[0-9\\s\\-\\(\\)]{7,20}$/;\n      if (!phoneRegex.test(this.phone.trim())) {\n        throw new Error('Invalid phone format');\n      }\n    }\n\n    // Validate ZIP code format (basic validation)\n    if (this.zip.length < 3 || this.zip.length > 10) {\n      throw new Error('ZIP code must be between 3 and 10 characters');\n    }\n\n    // Validate country code (ISO 3166-1 alpha-2 or full name)\n    if (this.country.length < 2) {\n      throw new Error('Country must be at least 2 characters');\n    }\n  }\n\n  /**\n   * Get full name\n   */\n  getFullName(): string {\n    return `${this.firstName} ${this.lastName}`;\n  }\n\n  /**\n   * Get formatted address\n   */\n  getFormattedAddress(): string {\n    return `${this.street}\\n${this.zip} ${this.city}\\n${this.country}`;\n  }\n\n  /**\n   * Check if two customer info objects are equal\n   */\n  equals(other: CustomerInfo): boolean {\n    return (\n      this.firstName === other.firstName &&\n      this.lastName === other.lastName &&\n      this.street === other.street &&\n      this.zip === other.zip &&\n      this.city === other.city &&\n      this.country === other.country &&\n      this.email === other.email &&\n      this.phone === other.phone\n    );\n  }\n\n  /**\n   * Create a copy with updated fields\n   */\n  update(updates: Partial<Omit<CustomerInfo, 'validate' | 'getFullName' | 'getFormattedAddress' | 'equals' | 'update'>>): CustomerInfo {\n    return new CustomerInfo(\n      updates.firstName ?? this.firstName,\n      updates.lastName ?? this.lastName,\n      updates.street ?? this.street,\n      updates.zip ?? this.zip,\n      updates.city ?? this.city,\n      updates.country ?? this.country,\n      updates.email ?? this.email,\n      updates.phone ?? this.phone\n    );\n  }\n\n  /**\n   * Convert to plain object for serialization\n   */\n  toPlainObject(): {\n    firstName: string;\n    lastName: string;\n    street: string;\n    zip: string;\n    city: string;\n    country: string;\n    email: string;\n    phone?: string;\n  } {\n    const result: {\n      firstName: string;\n      lastName: string;\n      street: string;\n      zip: string;\n      city: string;\n      country: string;\n      email: string;\n      phone?: string;\n    } = {\n      firstName: this.firstName,\n      lastName: this.lastName,\n      street: this.street,\n      zip: this.zip,\n      city: this.city,\n      country: this.country,\n      email: this.email,\n    };\n    \n    if (this.phone !== undefined) {\n      result.phone = this.phone;\n    }\n    \n    return result;\n  }\n\n  /**\n   * Create from plain object\n   */\n  static fromPlainObject(data: {\n    firstName: string;\n    lastName: string;\n    street: string;\n    zip: string;\n    city: string;\n    country: string;\n    email: string;\n    phone?: string;\n  }): CustomerInfo {\n    return new CustomerInfo(\n      data.firstName,\n      data.lastName,\n      data.street,\n      data.zip,\n      data.city,\n      data.country,\n      data.email,\n      data.phone\n    );\n  }\n}","import type { Currency } from \"./Currency.js\";\nimport { Money, type MoneyPlainObject } from \"./Money.js\";\n\n/**\n * OrderItem value object representing a line item in an order/invoice\n * Immutable snapshot of order item data with price calculations\n */\nexport class OrderItem {\n  public readonly linePrice: Money;\n\n  constructor(\n    public readonly unitPrice: Money,\n    public readonly quantity: number,\n    public readonly name: string,\n    public readonly variant?: string | undefined,\n    public readonly productNumber?: string | undefined\n  ) {\n    this.validate();\n    this.linePrice = this.calculateLinePrice();\n  }\n\n  private validate(): void {\n    if (!this.name?.trim()) {\n      throw new Error(\"Item name is required\");\n    }\n    if (!Number.isInteger(this.quantity) || this.quantity <= 0) {\n      throw new Error(\"Quantity must be a positive integer\");\n    }\n    if (this.unitPrice.amount <= 0) {\n      throw new Error(\"Unit price must be positive\");\n    }\n    if (this.productNumber !== undefined && !this.productNumber.trim()) {\n      throw new Error(\"Product number cannot be empty string\");\n    }\n    if (this.variant !== undefined && !this.variant.trim()) {\n      throw new Error(\"Variant cannot be empty string\");\n    }\n  }\n\n  private calculateLinePrice(): Money {\n    return this.unitPrice.multiply(this.quantity);\n  }\n\n  /**\n   * Get the total price for this line item\n   */\n  getTotalPrice(): Money {\n    return this.linePrice;\n  }\n\n  /**\n   * Get display name including variant if present\n   */\n  getDisplayName(): string {\n    if (this.variant) {\n      return `${this.name} (${this.variant})`;\n    }\n    return this.name;\n  }\n\n  /**\n   * Get full item description including product number\n   */\n  getFullDescription(): string {\n    let description = this.getDisplayName();\n    if (this.productNumber) {\n      description = `${this.productNumber} - ${description}`;\n    }\n    return description;\n  }\n\n  /**\n   * Check if two order items are equal\n   */\n  equals(other: OrderItem): boolean {\n    return (\n      this.unitPrice.equals(other.unitPrice) &&\n      this.quantity === other.quantity &&\n      this.name === other.name &&\n      this.variant === other.variant &&\n      this.productNumber === other.productNumber\n    );\n  }\n\n  /**\n   * Create a copy with updated quantity\n   */\n  withQuantity(newQuantity: number): OrderItem {\n    return new OrderItem(\n      this.unitPrice,\n      newQuantity,\n      this.name,\n      this.variant,\n      this.productNumber\n    );\n  }\n\n  /**\n   * Create a copy with updated unit price\n   */\n  withUnitPrice(newUnitPrice: Money): OrderItem {\n    return new OrderItem(\n      newUnitPrice,\n      this.quantity,\n      this.name,\n      this.variant,\n      this.productNumber\n    );\n  }\n\n  /**\n   * Convert to plain object for serialization\n   */\n  toPlainObject(): {\n    unitPrice: { amount: number; currency: string };\n    quantity: number;\n    linePrice: { amount: number; currency: string };\n    name: string;\n    variant?: string;\n    productNumber?: string;\n  } {\n    const result: {\n      unitPrice: { amount: number; currency: string };\n      quantity: number;\n      linePrice: { amount: number; currency: string };\n      name: string;\n      variant?: string;\n      productNumber?: string;\n    } = {\n      unitPrice: {\n        amount: this.unitPrice.amount,\n        currency: this.unitPrice.currency,\n      },\n      quantity: this.quantity,\n      linePrice: {\n        amount: this.linePrice.amount,\n        currency: this.linePrice.currency,\n      },\n      name: this.name,\n    };\n\n    if (this.variant !== undefined) {\n      result.variant = this.variant;\n    }\n\n    if (this.productNumber !== undefined) {\n      result.productNumber = this.productNumber;\n    }\n\n    return result;\n  }\n\n  /**\n   * Create from plain object\n   */\n  static fromPlainObject(data: {\n    unitPrice: MoneyPlainObject;\n    quantity: number;\n    name: string;\n    variant?: string;\n    productNumber?: string;\n  }): OrderItem {\n    const unitPrice = new Money(\n      data.unitPrice.amount,\n      data.unitPrice.currency as Currency\n    );\n    return new OrderItem(\n      unitPrice,\n      data.quantity,\n      data.name,\n      data.variant,\n      data.productNumber\n    );\n  }\n}\n","import { InvoiceFinancials, Money } from \"../value-objects\";\nimport { InvoiceStatus } from \"./shared\";\n\n/**\n * Base domain error class\n */\nexport abstract class DomainError extends Error {\n  constructor(\n    message: string,\n    public readonly code: ErrorCode,\n    public readonly details?: Record<string, any>\n  ) {\n    super(message);\n    this.name = this.constructor.name;\n  }\n}\n\n/**\n * Invoice-specific domain errors\n */\nexport class InvalidInvoiceNumberError extends DomainError {\n  constructor(invoiceNumber: string, reason?: string) {\n    super(\n      `Invalid invoice number: ${invoiceNumber}${reason ? ` - ${reason}` : \"\"}`,\n      ErrorCode.INVALID_INVOICE_NUMBER,\n      { invoiceNumber, reason }\n    );\n  }\n}\n\nexport class DuplicateInvoiceNumberError extends DomainError {\n  constructor(invoiceNumber: string) {\n    super(\n      `Invoice number already exists: ${invoiceNumber}`,\n      ErrorCode.DUPLICATE_INVOICE_NUMBER,\n      { invoiceNumber }\n    );\n  }\n}\n\nexport class InvoiceTotalMismatchError extends DomainError {\n  constructor(\n    expected: Money,\n    actual: Money,\n    because?: Omit<InvoiceFinancials, \"grandTotal\">\n  ) {\n    super(\n      `Invoice totals do not match: expected ${expected.toString()}, got ${actual.toString()}`,\n      ErrorCode.TOTAL_MISMATCH,\n      {\n        expected: expected.toString(),\n        actual: actual.toString(),\n        because: because\n          ? JSON.stringify(\n              {\n                subtotal: because.subtotal.toString(),\n                taxes: because.taxes.toString(),\n                shippingCost: because.shippingCost.toString(),\n                discount: because.discount.toString(),\n              },\n              null,\n              2\n            )\n          : undefined,\n      }\n    );\n  }\n}\n\n/**\n * Error thrown when an invoice draft cannot be found for a given order.\n *\n * @remarks\n * This error is typically used in scenarios where an operation expects an existing invoice draft\n * associated with a specific order, but none is found in the system, e.g. when issuing an invoice.\n *\n * @extends DomainError\n *\n * @param orderId - The identifier of the order for which the invoice draft was not found.\n *\n * @example\n * ```typescript\n * throw new InvoiceDraftNotFoundError('order-123');\n * ```\n */\nexport class InvoiceDraftNotFoundError extends DomainError {\n  constructor(orderId: string) {\n    super(\n      `Invoice draft not found for order: ${orderId}`,\n      ErrorCode.INVOICE_DRAFT_NOT_FOUND,\n      { orderId }\n    );\n  }\n}\n\n/**\n * @deprecated An invoice that already exists is likely an invoice with the same invoice number.\n * Therefore, use {@link DuplicateInvoiceNumberError} instead.\n * This error will be removed in the next major version.\n */\nexport class InvoiceAlreadyExistsError extends DomainError {\n  constructor(orderId: string) {\n    super(\n      `Invoice already exists for order: ${orderId}`,\n      ErrorCode.INVOICE_ALREADY_EXISTS,\n      { orderId }\n    );\n  }\n}\n\nexport class InvoiceIntegrityCheckError extends DomainError {\n  constructor(\n    readonly invoiceId: string,\n    readonly reason: \"INVOICE_NUMBER_MISMATCH\",\n    readonly reasonDetails?: string | Record<string, string | number>\n  ) {\n    super(\n      `Invoice ${invoiceId} is not in a valid state! ${reason}${\n        reasonDetails ? ` - ${JSON.stringify(reasonDetails)}` : \"\"\n      }`,\n      ErrorCode.INVOICE_STATE_VIOLATION,\n      { invoiceId, reason, reasonDetails }\n    );\n  }\n}\n\nexport class InvoiceStateViolationError extends DomainError {\n  constructor(\n    invoiceId: string,\n    expected: InvoiceStatus,\n    received: InvoiceStatus\n  ) {\n    super(\n      `Invoice ${invoiceId} has unexpected state: Expected ${expected} but received ${received}`,\n      ErrorCode.INVOICE_STATE_VIOLATION,\n      { invoiceId, expected, received }\n    );\n  }\n}\n\nexport class InvoiceTransitionFailedError extends DomainError {\n  constructor(\n    invoiceId: string,\n    fromStatus: InvoiceStatus,\n    toStatus: InvoiceStatus\n  ) {\n    super(\n      `Invoice ${invoiceId} cannot transition from ${fromStatus} to ${toStatus}`,\n      ErrorCode.TRANSITION_VIOLATION,\n      { invoiceId, fromStatus, toStatus }\n    );\n  }\n}\n\nexport class OrderNotFoundError extends DomainError {\n  constructor(orderId: string) {\n    super(`Order not found: ${orderId}`, ErrorCode.ORDER_NOT_FOUND, {\n      orderId,\n    });\n  }\n}\n\n/**\n * Error codes for domain errors\n */\nexport enum ErrorCode {\n  INVALID_INVOICE_NUMBER = \"INVALID_INVOICE_NUMBER\",\n  DUPLICATE_INVOICE_NUMBER = \"DUPLICATE_INVOICE_NUMBER\",\n  TOTAL_MISMATCH = \"TOTAL_MISMATCH\",\n  ORDER_NOT_FOUND = \"ORDER_NOT_FOUND\",\n  INVOICE_ALREADY_EXISTS = \"INVOICE_ALREADY_EXISTS\",\n  INVALID_CUSTOMER_DATA = \"INVALID_CUSTOMER_DATA\",\n  INVALID_ORDER_ITEMS = \"INVALID_ORDER_ITEMS\",\n  PDF_GENERATION_FAILED = \"PDF_GENERATION_FAILED\",\n  SHIPPING_COST_NEGATIVE = \"SHIPPING_COST_NEGATIVE\",\n  TRANSITION_VIOLATION = \"TRANSITION_VIOLATION\",\n  INVOICE_STATE_VIOLATION = \"INVOICE_STATE_VIOLATION\",\n  INVOICE_DRAFT_NOT_FOUND = \"INVOICE_DRAFT_NOT_FOUND\",\n}\n","import type { InvoiceDraft } from \"../entities/InvoiceDraft.js\";\nimport { CustomerInfo } from \"../value-objects/CustomerInfo.js\";\nimport { Money } from \"../value-objects/Money.js\";\nimport { OrderItem } from \"../value-objects/OrderItem.js\";\nimport type { ShippingCost } from \"../value-objects/ShippingCost.js\";\n\n/**\n * Unique identifier type for entities\n */\nexport type UUID = string;\n\n/**\n * Represents the data required to issue a new invoice.\n *\n * This type includes only the fields of {@link InvoiceDraft}, omitting any methods\n * and some fields that are not relevant for the issuance process.\n *\n * The alias exists just to provide clarity to the meaning in the domain model.\n */\nexport type IssueInvoiceData = Omit<\n  {\n    [K in keyof InvoiceDraft as InvoiceDraft[K] extends Function\n      ? never\n      : K]: InvoiceDraft[K];\n  },\n  \"invoiceId\" | \"createdOn\" | \"pdfBytes\"\n> & { status: InvoiceStatus.DRAFT };\n\n/**\n * Represents the data required to create a new invoice.\n *\n * @deprecated Use {@link IssueInvoiceData} instead. \"Issue Invoice\" is the preferred terminology\n * as it aligns with real-world accounting language where invoices are issued to customers.\n * This alias will be removed in the next major version.\n *\n * This type includes only the fields of {@link InvoiceDraft}, omitting any methods\n * and some fields that are not relevant for the creation process.\n *\n * The alias exists just to provide clarity to the meaning in the domain model.\n */\nexport type CreateInvoiceData = IssueInvoiceData;\n\n/**\n * Order entity interface (read-only reference)\n */\nexport interface Order {\n  readonly orderId: string;\n  readonly customer: CustomerInfo;\n  readonly items: OrderItem[];\n  readonly subtotal: Money;\n  readonly taxes: Money;\n  /**\n   * @deprecated This value is ignored and exists for migration purposes only. The domain enforces its own Shipping policies. **Expected version of removal: 0.2.0**\n   */\n  readonly shippingCost: ShippingCost;\n  readonly discount: Money;\n  readonly status: OrderStatus;\n  readonly createdAt: Date;\n}\n\n/**\n * Order status enumeration\n */\nexport enum OrderStatus {\n  PENDING = \"pending\",\n  CONFIRMED = \"confirmed\",\n  SHIPPED = \"shipped\",\n  DELIVERED = \"delivered\",\n  CANCELLED = \"cancelled\",\n}\n\n/**\n * Invoice status enumeration\n */\nexport enum InvoiceStatus {\n  DRAFT = \"draft\",\n  FINALIZED = \"finalized\",\n}\n\n/**\n * Pagination result wrapper\n */\nexport interface PaginatedResult<T> {\n  readonly items: T[];\n  readonly totalCount: number;\n  readonly page: number;\n  readonly limit: number;\n  readonly hasNextPage: boolean;\n  readonly hasPreviousPage: boolean;\n}\n\n/**\n * Base domain event interface\n */\nexport interface DomainEvent {\n  readonly eventId: UUID;\n  readonly eventType: string;\n  readonly aggregateId: UUID;\n  readonly occurredOn: Date;\n  readonly version: 1;\n}\n\n/**\n * Utility type for making properties optional\n */\nexport type Optional<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>;\n\n/**\n * Utility type for making properties required\n */\nexport type Required<T, K extends keyof T> = T & { [P in K]-?: T[P] };\n\n/**\n * An interface that contains functions to make a {@link DomainEvent}\n * serializable.\n */\nexport interface SerializableEvent<T extends DomainEvent> {\n  toPlainObject(): PlainEvent<T>;\n}\n\n/**\n * Utility type for serializing a DomainEvent to a plain object.\n *\n * For example, it requires `occurredOn` to be a string instead of a Date.\n */\nexport type PlainEvent<T extends DomainEvent> = Omit<\n  T,\n  \"occurredOn\" | \"toPlainObject\"\n> & {\n  occurredOn: string;\n};\n","export * from \"./errors\";\nexport * from \"./shared.js\";\n","import type {\n  ShippingCostPolicy,\n  ShippingRateProvider,\n} from \"../policies/Shipping.js\";\nimport { DomainError, ErrorCode } from \"../types/index.js\";\nimport { Money, type MoneyPlainObject } from \"./Money.js\";\n\nexport type ShippingCostRule = \"NON_NEGATIVE\";\n\nexport class ShippingCostValidationError extends DomainError {\n  constructor(rule: ShippingCostRule) {\n    let message = \"Validation failed\";\n    switch (rule) {\n      case \"NON_NEGATIVE\":\n        message = \"Shipping cost must be non-negative\";\n        break;\n    }\n\n    super(\n      `Shipping costs are not valid: ${message}`,\n      ErrorCode.SHIPPING_COST_NEGATIVE\n    );\n  }\n}\n\n/**\n * Shipping cost extends Money and enforces special business rules,\n * namely custom shipping policies and dynamic shipping rates.\n *\n * It has to extend Money so that it can be used in combination\n * with the Money arithmetics, e.g. for grand total calculation.\n */\nexport class ShippingCost extends Money {\n    /**\n     * Determines the shipping cost based on an order's grand total value.\n     * Due to business rules, shipping is applied (or not applied) based on the grand total.\n     * @param grandTotal The order's grand total value\n     * @param shippingRates Shipping rates provider that provides the costs\n     * @param shippingPolicy Policy that influences the way costs are calculated\n     * @returns Shipping costs based on business rules, policies and rates.\n     */\n  static determine(\n    grandTotal: Money,\n    shippingRates: ShippingRateProvider,\n    shippingPolicy: ShippingCostPolicy\n  ): ShippingCost {\n    if (shippingPolicy.isFreeShippingAllowed(grandTotal)) {\n      return new ShippingCost(Money.zero(\"EUR\"));\n    }\n\n    return new ShippingCost(shippingRates.getStandardShippingRate());\n  }\n\n  constructor(readonly cost: Money) {\n    super(cost.amount, cost.currency);\n    if (!this.#validate()) {\n      throw new ShippingCostValidationError(\"NON_NEGATIVE\");\n    }\n  }\n\n  /**\n   * Validates the shipping cost. It doesn't allow the amount to be less than 0.\n   */\n  #validate(): boolean {\n    return this.cost.amount >= 0;\n  }\n}\n","import { v4 as uuidv4 } from \"uuid\";\nimport {\n  PlainEvent,\n  SerializableEvent,\n  type DomainEvent,\n  type UUID,\n} from \"../types/index.js\";\nimport { Money } from \"../value-objects/Money.js\";\n\n/**\n * Base class for invoice-related domain events\n */\nabstract class InvoiceEvent implements DomainEvent {\n  constructor(\n    public readonly eventId: UUID,\n    public readonly eventType: string,\n    public readonly aggregateId: UUID,\n    public readonly occurredOn: Date,\n    public readonly version: 1,\n    public readonly invoiceId: UUID\n  ) {}\n}\n\n/**\n * Domain event published when an invoice is issued\n * Contains essential information for downstream processing\n */\nexport class InvoiceIssuedEvent extends InvoiceEvent {\n  public override readonly eventType = \"InvoiceIssued\" as const;\n\n  constructor(\n    eventId: UUID,\n    aggregateId: UUID,\n    occurredOn: Date,\n    version: 1,\n    public override readonly invoiceId: UUID,\n    public readonly orderId: string,\n    public readonly invoiceNumber: string,\n    public readonly grandTotal: Money,\n    public readonly pdfBytes: Uint8Array,\n    public readonly issuedBy: string\n  ) {\n    super(\n      eventId,\n      \"InvoiceIssued\",\n      aggregateId,\n      occurredOn,\n      version,\n      invoiceId\n    );\n  }\n\n  /**\n   * Convert to plain object for serialization\n   */\n  toPlainObject(): {\n    eventId: string;\n    eventType: \"InvoiceIssued\";\n    aggregateId: string;\n    occurredOn: string;\n    version: 1;\n    invoiceId: string;\n    orderId: string;\n    invoiceNumber: string;\n    grandTotal: { amount: number; currency: string };\n    issuedBy: string;\n    // Note: pdfBytes excluded from serialization for size reasons\n  } {\n    return {\n      eventId: this.eventId,\n      eventType: this.eventType,\n      aggregateId: this.aggregateId,\n      occurredOn: this.occurredOn.toISOString(),\n      version: this.version,\n      invoiceId: this.invoiceId,\n      orderId: this.orderId,\n      invoiceNumber: this.invoiceNumber,\n      grandTotal: this.grandTotal.toPlainObject(),\n      issuedBy: this.issuedBy,\n    };\n  }\n}\n\n/**\n * Domain event published when an invoice is created\n * Contains essential information for downstream processing\n * \n * @deprecated Use {@link InvoiceIssuedEvent} instead. \"Issue Invoice\" is the preferred terminology\n * as it aligns with real-world accounting language where invoices are issued to customers.\n * This event will be removed in the next major version.\n */\nexport class InvoiceCreatedEvent extends InvoiceEvent {\n  public override readonly eventType = \"InvoiceCreated\" as const;\n\n  constructor(\n    eventId: UUID,\n    aggregateId: UUID,\n    occurredOn: Date,\n    version: 1,\n    public override readonly invoiceId: UUID,\n    public readonly orderId: string,\n    public readonly invoiceNumber: string,\n    public readonly grandTotal: Money,\n    public readonly pdfBytes: Uint8Array,\n    public readonly createdBy: string\n  ) {\n    super(\n      eventId,\n      \"InvoiceCreated\",\n      aggregateId,\n      occurredOn,\n      version,\n      invoiceId\n    );\n  }\n\n  /**\n   * Convert to plain object for serialization\n   */\n  toPlainObject(): {\n    eventId: string;\n    eventType: \"InvoiceCreated\";\n    aggregateId: string;\n    occurredOn: string;\n    version: 1;\n    invoiceId: string;\n    orderId: string;\n    invoiceNumber: string;\n    grandTotal: { amount: number; currency: string };\n    createdBy: string;\n    // Note: pdfBytes excluded from serialization for size reasons\n  } {\n    return {\n      eventId: this.eventId,\n      eventType: this.eventType,\n      aggregateId: this.aggregateId,\n      occurredOn: this.occurredOn.toISOString(),\n      version: this.version,\n      invoiceId: this.invoiceId,\n      orderId: this.orderId,\n      invoiceNumber: this.invoiceNumber,\n      grandTotal: this.grandTotal.toPlainObject(),\n      createdBy: this.createdBy,\n    };\n  }\n}\n\n/**\n * Domain event published when an invoice is requested.\n *\n * Contains essential information for downstream processing.\n */\nexport class InvoiceRequested\n  implements DomainEvent, SerializableEvent<InvoiceRequested>\n{\n  readonly eventType: string = \"InvoiceRequested\";\n  constructor(\n    public eventId: UUID,\n    public aggregateId: UUID,\n    public occurredOn: Date,\n    public version: 1,\n    public readonly orderId: string,\n    public readonly requestedBy: string,\n    public readonly invoiceNumber: string\n  ) {}\n\n  /**\n   * Convert to plain object for serialization\n   */\n  toPlainObject(): PlainEvent<InvoiceRequested> {\n    return {\n      eventId: this.eventId,\n      eventType: this.eventType,\n      aggregateId: this.aggregateId,\n      occurredOn: this.occurredOn.toISOString(),\n      version: this.version,\n      orderId: this.orderId,\n      requestedBy: this.requestedBy,\n      invoiceNumber: this.invoiceNumber,\n    };\n  }\n}\n\n/**\n * Domain event published when an invoice PDF is generated\n * Separate from creation to handle PDF generation failures\n */\nexport class InvoicePdfGeneratedEvent extends InvoiceEvent {\n  public override readonly eventType = \"InvoicePdfGenerated\" as const;\n\n  constructor(\n    eventId: UUID,\n    aggregateId: UUID,\n    occurredOn: Date,\n    version: 1,\n    public override readonly invoiceId: UUID,\n    public readonly invoiceNumber: string,\n    public readonly pdfSize: number,\n    public readonly pdfBytes: Uint8Array\n  ) {\n    super(\n      eventId,\n      \"InvoicePdfGenerated\",\n      aggregateId,\n      occurredOn,\n      version,\n      invoiceId\n    );\n  }\n\n  /**\n   * Convert to plain object for serialization\n   */\n  toPlainObject(): {\n    eventId: string;\n    eventType: \"InvoicePdfGenerated\";\n    aggregateId: string;\n    occurredOn: string;\n    version: 1;\n    invoiceId: string;\n    invoiceNumber: string;\n    pdfSize: number;\n    // Note: pdfBytes excluded from serialization for size reasons\n  } {\n    return {\n      eventId: this.eventId,\n      eventType: this.eventType,\n      aggregateId: this.aggregateId,\n      occurredOn: this.occurredOn.toISOString(),\n      version: this.version,\n      invoiceId: this.invoiceId,\n      invoiceNumber: this.invoiceNumber,\n      pdfSize: this.pdfSize,\n    };\n  }\n}\n\n/**\n * Domain event published when an invoice validation fails\n * Used for monitoring and alerting purposes\n */\nexport class InvoiceValidationFailedEvent extends InvoiceEvent {\n  public override readonly eventType = \"InvoiceValidationFailed\" as const;\n\n  constructor(\n    eventId: UUID,\n    aggregateId: UUID,\n    occurredOn: Date,\n    version: 1,\n    public override readonly invoiceId: UUID,\n    public readonly orderId: string,\n    public readonly invoiceNumber: string,\n    public readonly validationErrors: string[],\n    public readonly attemptedBy: string\n  ) {\n    super(\n      eventId,\n      \"InvoiceValidationFailed\",\n      aggregateId,\n      occurredOn,\n      version,\n      invoiceId\n    );\n  }\n\n  /**\n   * Convert to plain object for serialization\n   */\n  toPlainObject(): {\n    eventId: string;\n    eventType: \"InvoiceValidationFailed\";\n    aggregateId: string;\n    occurredOn: string;\n    version: 1;\n    invoiceId: string;\n    orderId: string;\n    invoiceNumber: string;\n    validationErrors: string[];\n    attemptedBy: string;\n  } {\n    return {\n      eventId: this.eventId,\n      eventType: this.eventType,\n      aggregateId: this.aggregateId,\n      occurredOn: this.occurredOn.toISOString(),\n      version: this.version,\n      invoiceId: this.invoiceId,\n      orderId: this.orderId,\n      invoiceNumber: this.invoiceNumber,\n      validationErrors: [...this.validationErrors],\n      attemptedBy: this.attemptedBy,\n    };\n  }\n}\n\n/**\n * Generates a new event ID as a uuidv4 string.\n * @returns A UUID string\n */\nexport function generateEventId(): string {\n  return uuidv4();\n}\n","export {\n  InvoiceIssuedEvent,\n  InvoiceCreatedEvent,\n  InvoicePdfGeneratedEvent,\n  InvoiceValidationFailedEvent,\n  InvoiceRequested,\n  generateEventId,\n} from \"./InvoiceEvents.js\";\nexport { DomainEventPublisher } from \"./DomainEventPublisher.js\";\n","// You could come up with \"But doesn't it break the rule that the domain should not depend on external packages?\"\n// And yes, true. As long as it doesn't meet strict business rule enforcement needs.\n// And one important business rule we define is: uuidv4 ids for invoices.\nimport { v4 as uuidv4 } from \"uuid\";\nimport { InvoiceIdGenerator } from \"./InvoiceIdGenerator\";\n\n/**\n * Default implementation of InvoiceIdGenerator that uses `uuid` with UUIDv4 IDs.\n *\n * @see {@link InvoiceIdGenerator}\n * @since 0.4.0\n */\nexport class InvoiceIdGeneratorDefault implements InvoiceIdGenerator {\n  generate(): Promise<string> {\n    return Promise.resolve(uuidv4());\n  }\n}\n","import { DomainEventPublisher } from \"../events/DomainEventPublisher\";\nimport { DomainEvent } from \"../types\";\n\n/**\n * Aggregate root base class that supports domain event collection\n */\nexport abstract class AggregateRoot {\n  private _domainEvents: DomainEvent[] = [];\n\n  /**\n   * Adds a domain event to the aggregate's list of domain events.\n   *\n   * @typeParam T - The type of the domain event, extending `DomainEvent`.\n   * @param event - The domain event to add. Must include an `eventType` property.\n   */\n  protected addDomainEvent<T extends DomainEvent>(\n    event: T & { eventType: T[\"eventType\"] }\n  ): void {\n    this._domainEvents.push(event);\n  }\n\n  /**\n   * Get all unpublished domain events\n   */\n  getUncommittedEvents(): DomainEvent[] {\n    return [...this._domainEvents];\n  }\n\n  /**\n   * Clear all domain events (called after publishing)\n   */\n  markEventsAsCommitted(): void {\n    this._domainEvents = [];\n  }\n\n  /**\n   * Check if there are unpublished events\n   */\n  hasUncommittedEvents(): boolean {\n    return this._domainEvents.length > 0;\n  }\n\n  /**\n   * Publishes all uncommitted events using the provided publisher,\n   * and marks all domains as commited.\n   *\n   * It is a convenience wrapper around:\n   *\n   * ```typescript\n   * const publisher =  //...;\n   * const uncommitted = this.getUncommittedEvents();\n   * publisher.publishAll(uncommitted);\n   * this.markEventsAsCommitted();\n   * ```\n   */\n  publishAllUncommitted(publisher: DomainEventPublisher) {\n    const uncommitted = this.getUncommittedEvents();\n    publisher.publishAll(uncommitted);\n    this.markEventsAsCommitted();\n  }\n}\n","import { InvoiceCreatedEvent, DomainEventPublisher } from \"../events\";\nimport { InvoiceStatus, DomainEvent } from \"../types\";\nimport {\n  CustomerInfo,\n  OrderItem,\n  MoneyPlainObject,\n  InvoiceFinancials,\n} from \"../value-objects\";\nimport { Invoice } from \"./Invoice.js\";\n\n/**\n * Represents a draft version of an invoice, extending the base `Invoice` class.\n *\n * The `InvoiceDraft` class is used to create invoices that are in the draft state,\n * allowing for further modifications before finalization. It initializes the invoice\n * with the provided details and sets its status to `DRAFT`.\n *\n * @remarks\n * This class is typically used when an invoice is being prepared but has not yet been issued.\n *\n * @param invoiceId - The unique identifier for the invoice.\n * @param orderId - The identifier of the associated order.\n * @param invoiceNumber - The invoice number assigned to this draft.\n * @param customerSnapshot - A snapshot of the customer information at the time of draft creation.\n * @param itemsSnapshot - A readonly array of order items included in the invoice.\n * @param financials - The financial details associated with the invoice.\n * @param createdBy - The identifier of the user who created the draft.\n */\nexport class InvoiceDraft extends Invoice {\n  constructor(\n    invoiceId: string,\n    orderId: string,\n    invoiceNumber: string,\n    customerSnapshot: CustomerInfo,\n    itemsSnapshot: readonly OrderItem[],\n    financials: InvoiceFinancials,\n    createdBy: string\n  ) {\n    super(\n      invoiceId,\n      orderId,\n      invoiceNumber,\n      customerSnapshot,\n      itemsSnapshot,\n      financials,\n      new Date(),\n      createdBy,\n      new Uint8Array(),\n      InvoiceStatus.DRAFT\n    );\n  }\n}\n","import {\n  InvoiceCreatedEvent,\n  InvoiceIssuedEvent,\n  InvoiceRequested,\n  generateEventId,\n} from \"../events/index.js\";\nimport { InvoiceIdGeneratorDefault } from \"../services/InvoiceIdGenerator.default.js\";\nimport { InvoiceIdGenerator } from \"../services/InvoiceIdGenerator.js\";\nimport { InvoiceNumberGenerator } from \"../services/InvoiceNumberGenerator.js\";\nimport type { InvoiceNumberValidator } from \"../services/InvoiceNumberValidator.js\";\nimport {\n  InvoiceStateViolationError,\n  InvoiceStatus,\n  InvoiceTotalMismatchError,\n  InvoiceTransitionFailedError,\n  type CreateInvoiceData,\n  type IssueInvoiceData,\n  type UUID,\n} from \"../types/index.js\";\nimport type { Currency } from \"../value-objects/Currency.js\";\nimport { CustomerInfo } from \"../value-objects/CustomerInfo.js\";\nimport type {\n  InvoiceFinancials,\n  MoneyPlainObject,\n} from \"../value-objects/index.js\";\nimport { Money } from \"../value-objects/Money.js\";\nimport { OrderItem } from \"../value-objects/OrderItem.js\";\nimport { ShippingCost } from \"../value-objects/ShippingCost.js\";\nimport { AggregateRoot } from \"./aggregate-root.js\";\nimport type { InvoiceDraft } from \"./InvoiceDraft.js\";\n\nexport type InvoiceAggregateDependencies = {\n  invoiceNumberValidator: InvoiceNumberValidator;\n  /**\n   * The invoice ID generator.\n   * If not provided, it will use {@link InvoiceIdGeneratorDefault}.\n   */\n  invoiceIdGenerator?: InvoiceIdGenerator;\n};\n\n/**\n * Invoice aggregate root\n * Manages invoice lifecycle, validation, and business rules\n * Immutable once created to ensure data integrity\n */\nexport class Invoice extends AggregateRoot {\n  constructor(\n    public readonly invoiceId: UUID,\n    public readonly orderId: string,\n    public readonly invoiceNumber: string,\n    public readonly customerSnapshot: CustomerInfo,\n    public readonly itemsSnapshot: readonly OrderItem[],\n    public readonly financials: InvoiceFinancials,\n    public readonly createdOn: Date,\n    public readonly createdBy: string,\n    public readonly pdfBytes: Uint8Array,\n    private readonly status: InvoiceStatus\n  ) {\n    super();\n    // Validate totals on construction\n    this.validateTotals();\n  }\n\n  /**\n   * Validates invoice number uniqueness\n   */\n  static async #validateInvoiceNumber(\n    invoiceNumber: string,\n    validator: InvoiceNumberValidator\n  ) {\n    // it will throw if not unique. this may be not ideal, should return a bool instead.\n    // But for now, OK.\n    await validator.validateUniqueness(invoiceNumber);\n  }\n\n  /**\n   * Factory method to create a new invoice.\n   *\n   * Validates business rules and calculates totals.\n   *\n   * **NOTE**: The invoice information you pass must be in `DRAFT` status.\n   * If that's not the case, a `InvoiceTransitionViolationError` will be thrown.\n   *\n   * Requires dependencies, such as the invoice number validator,\n   * because it's a core business rule that they are unique.\n   *\n   * @deprecated Use {@link issue} instead.\n   * It provides a more aligned naming convention and,\n   * under the hood, this method work the same way.\n   * Will be removed in the next major version.\n   *\n   * @see https://github.com/benjamin-kraatz/invoicing-sdk/issues/14\n   */\n  static async create(\n    data: CreateInvoiceData,\n    pdfBytes: Uint8Array,\n    deps: InvoiceAggregateDependencies\n  ): Promise<Invoice> {\n    // until removal, just call `issue`\n    return Invoice.issue(data, pdfBytes, deps);\n  }\n\n  /**\n   * Factory method to issue a new invoice.\n   *\n   * Validates business rules and calculates totals.\n   *\n   * **NOTE**: The invoice information you pass must be in `DRAFT` status.\n   * If that's not the case, a `InvoiceTransitionViolationError` will be thrown.\n   *\n   * Requires dependencies, such as the invoice number validator,\n   * because it's a core business rule that they are unique.\n   *\n   * This is the preferred method for issuing invoices as it aligns with real-world\n   * accounting terminology where invoices are \"issued\" to customers.\n   *\n   * @see {@link InvoiceNumberValidator}\n   * @see {@link InvoiceStateViolationError}\n   * @see {@link InvoiceAggregateDependencies}\n   */\n  static async issue(\n    data: IssueInvoiceData,\n    pdfBytes: Uint8Array,\n    deps: InvoiceAggregateDependencies\n  ): Promise<Invoice> {\n    // Validate the status. It must be DRAFT. Because it's all typed, this should never happen.\n    if (data.status !== InvoiceStatus.DRAFT) {\n      throw new InvoiceStateViolationError(\n        data.invoiceNumber,\n        InvoiceStatus.DRAFT,\n        data.status\n      );\n    }\n\n    // First, validate the invoice number. If that fails, we can just skip all the heavy logic.\n    await Invoice.#validateInvoiceNumber(\n      data.invoiceNumber,\n      deps.invoiceNumberValidator\n    );\n\n    const issuedOn = new Date();\n\n    // Create immutable snapshots\n    const customerSnapshot = new CustomerInfo(\n      data.customerSnapshot.firstName,\n      data.customerSnapshot.lastName,\n      data.customerSnapshot.street,\n      data.customerSnapshot.zip,\n      data.customerSnapshot.city,\n      data.customerSnapshot.country,\n      data.customerSnapshot.email,\n      data.customerSnapshot.phone\n    );\n\n    const itemsSnapshot = data.itemsSnapshot.map(\n      (item) =>\n        new OrderItem(\n          item.unitPrice,\n          item.quantity,\n          item.name,\n          item.variant,\n          item.productNumber\n        )\n    );\n\n    const invoiceId = await Invoice.generateId(deps.invoiceIdGenerator);\n\n    const invoice = new Invoice(\n      invoiceId,\n      data.orderId,\n      data.invoiceNumber,\n      customerSnapshot,\n      itemsSnapshot,\n      data.financials,\n      issuedOn,\n      data.createdBy,\n      pdfBytes,\n      InvoiceStatus.FINALIZED\n    );\n\n    // Add domain event for invoice issuing\n    const issuedEvent = new InvoiceIssuedEvent(\n      generateEventId(),\n      invoiceId,\n      issuedOn,\n      1,\n      invoiceId,\n      data.orderId,\n      data.invoiceNumber,\n      data.financials.grandTotal,\n      pdfBytes,\n      data.createdBy\n    );\n    invoice.addDomainEvent(issuedEvent);\n\n    return invoice;\n  }\n\n  /**\n   * Creates a new draft invoice and emits an `InvoiceRequested` domain event.\n   *\n   * It creates a new invoice number (without reservation).\n   * The returned invoice can be used for actual issuing.\n   *\n   * A draft is required before issuing an invoice.\n   * @param data - The data required to create the invoice draft.\n   * @param deps - The dependencies required for invoice creation, including optional `invoiceIdGenerator` and required `invoiceNumberGenerator`.\n   * @returns A promise that resolves to the invoice draft when the draft invoice is created and the domain event is added.\n   *\n   * @see {@link InvoiceIdGenerator}\n   * @see {@link InvoiceNumberGenerator}\n   */\n  static async createDraft(\n    // We don't need the status, as this is always DRAFT\n    data: Omit<IssueInvoiceData, \"invoiceNumber\" | \"status\">,\n    deps: {\n      invoiceIdGenerator?: InvoiceIdGenerator;\n      invoiceNumberGenerator: InvoiceNumberGenerator;\n    }\n  ): Promise<InvoiceDraft> {\n    // Dynamic import to avoid circular dependency at module initialization time\n    const { InvoiceDraft } = await import(\"./InvoiceDraft.js\");\n    const id = await Invoice.generateId(deps.invoiceIdGenerator);\n    // Don't generateAndReserve; just generate to not persist. A draft invoice nbr must not be persisted yet.\n    const invoiceNumber = await deps.invoiceNumberGenerator.generate();\n    const invoiceDraft = new InvoiceDraft(\n      id,\n      data.orderId,\n      invoiceNumber,\n      data.customerSnapshot,\n      data.itemsSnapshot,\n      data.financials,\n      data.createdBy\n    );\n\n    const aggregateId = id;\n    const requestedEvent = new InvoiceRequested(\n      generateEventId(),\n      aggregateId,\n      new Date(),\n      1,\n      data.orderId,\n      data.createdBy,\n      invoiceNumber\n    );\n    invoiceDraft.addDomainEvent(requestedEvent);\n\n    return invoiceDraft;\n  }\n\n  private static async generateId(\n    invoiceIdGenerator?: InvoiceIdGenerator\n  ): Promise<string> {\n    return (invoiceIdGenerator ?? new InvoiceIdGeneratorDefault()).generate();\n  }\n\n  /**\n   * Transitions the invoice to the given status in a type-safe way.\n   *\n   * - To transition to FINALIZED, you must provide PDF bytes.\n   * - To transition to DRAFT, you must not provide PDF bytes.\n   *\n   * @param args - Discriminated union for status and pdfBytes.\n   * @returns A new invoice instance with the updated status.\n   * @throws InvoiceTransitionFailedError when the transition is not allowed\n   *\n   * @deprecated In preparation to an upcoming issue fix, the {@link Invoice.create}\n   * method will be renamed and makes the `transitionTo` function obsolete.\n   * Consider calling {@link Invoice.create} directly.\n   * This function will be removed in the next major release.\n   */\n  transitionTo(\n    args:\n      | { status: InvoiceStatus.FINALIZED; pdfBytes: Uint8Array }\n      | { status: InvoiceStatus.DRAFT }\n  ): Invoice {\n    const current = this.status;\n    const { status } = args;\n\n    if (current === InvoiceStatus.FINALIZED && status === InvoiceStatus.DRAFT) {\n      throw new InvoiceTransitionFailedError(this.invoiceId, current, status);\n    } else if (current === status) {\n      throw new InvoiceTransitionFailedError(this.invoiceId, current, status);\n    }\n\n    if (status === InvoiceStatus.FINALIZED) {\n      // TypeScript ensures pdfBytes is present here\n      return new Invoice(\n        this.invoiceId,\n        this.orderId,\n        this.invoiceNumber,\n        this.customerSnapshot,\n        this.itemsSnapshot,\n        this.financials,\n        this.createdOn,\n        this.createdBy,\n        args.pdfBytes,\n        status\n      );\n    } else if (status === InvoiceStatus.DRAFT) {\n      // No pdfBytes allowed in this branch\n      return new Invoice(\n        this.invoiceId,\n        this.orderId,\n        this.invoiceNumber,\n        this.customerSnapshot,\n        this.itemsSnapshot,\n        this.financials,\n        this.createdOn,\n        this.createdBy,\n        this.pdfBytes,\n        status\n      );\n    } else {\n      throw new InvoiceTransitionFailedError(this.invoiceId, current, status);\n    }\n  }\n\n  /**\n   * Checks if the current invoice status matches the specified status.\n   *\n   * @param status - The status to compare with the invoice's current status.\n   * @returns `true` if the invoice's status matches the specified status, otherwise `false`.\n   */\n  requireStatus(status: InvoiceStatus): boolean {\n    return this.status === status;\n  }\n\n  /**\n   * Returns the current status of the invoice.\n   *\n   * @returns {InvoiceStatus} The status of the invoice.\n   */\n  getStatus(): InvoiceStatus {\n    return this.status;\n  }\n\n  /**\n   * Validates that invoice totals are mathematically correct\n   * Business rule: grandTotal = subtotal + taxes + shippingCost - discount\n   */\n  validateTotals(): void {\n    const { subtotal, taxes, shippingCost, discount, grandTotal } =\n      this.financials;\n\n    // Ensure all amounts are in the same currency\n    const currency = subtotal.currency;\n    if (\n      taxes.currency !== currency ||\n      shippingCost.currency !== currency ||\n      discount.currency !== currency ||\n      grandTotal.currency !== currency\n    ) {\n      throw new Error(\"All financial amounts must be in the same currency\");\n    }\n\n    // Calculate expected grand total\n    const calculatedTotal = subtotal\n      .add(taxes)\n      .add(shippingCost)\n      .subtract(discount);\n\n    if (!calculatedTotal.equals(grandTotal)) {\n      throw new InvoiceTotalMismatchError(calculatedTotal, grandTotal, {\n        subtotal,\n        taxes,\n        shippingCost,\n        discount,\n      });\n    }\n\n    // Validate that subtotal matches sum of line items\n    const itemsTotal = this.itemsSnapshot.reduce(\n      (total, item) => total.add(item.linePrice),\n      new Money(0, currency)\n    );\n\n    if (!itemsTotal.equals(subtotal)) {\n      throw new InvoiceTotalMismatchError(itemsTotal, subtotal);\n    }\n  }\n\n  /**\n   * Creates the InvoiceIssuedEvent domain event\n   */\n  toDomainEvent(): InvoiceIssuedEvent {\n    return new InvoiceIssuedEvent(\n      generateEventId(),\n      this.invoiceId,\n      new Date(),\n      1,\n      this.invoiceId,\n      this.orderId,\n      this.invoiceNumber,\n      this.financials.grandTotal,\n      this.pdfBytes,\n      this.createdBy\n    );\n  }\n\n  /**\n   * Get the total number of items in the invoice\n   */\n  getTotalItemCount(): number {\n    return this.itemsSnapshot.reduce((total, item) => total + item.quantity, 0);\n  }\n\n  /**\n   * Get the currency used in this invoice\n   */\n  getCurrency(): string {\n    return this.financials.grandTotal.currency;\n  }\n\n  /**\n   * Check if the invoice contains a specific product\n   */\n  containsProduct(productNumber: string): boolean {\n    return this.itemsSnapshot.some(\n      (item) => item.productNumber === productNumber\n    );\n  }\n\n  /**\n   * Get formatted invoice summary for display\n   */\n  getSummary(): string {\n    const itemCount = this.getTotalItemCount();\n    const total = this.financials.grandTotal.toString();\n    return `Invoice ${this.invoiceNumber}: ${itemCount} items, Total: ${total}`;\n  }\n\n  /**\n   * Convert to plain object for serialization\n   */\n  toPlainObject(): {\n    invoiceId: string;\n    orderId: string;\n    invoiceNumber: string;\n    customerSnapshot: ReturnType<CustomerInfo[\"toPlainObject\"]>;\n    itemsSnapshot: ReturnType<OrderItem[\"toPlainObject\"]>[];\n    financials: {\n      subtotal: MoneyPlainObject;\n      taxes: MoneyPlainObject;\n      shippingCost: MoneyPlainObject;\n      discount: MoneyPlainObject;\n      grandTotal: MoneyPlainObject;\n    };\n    createdOn: string;\n    createdBy: string;\n  } {\n    return {\n      invoiceId: this.invoiceId,\n      orderId: this.orderId,\n      invoiceNumber: this.invoiceNumber,\n      customerSnapshot: this.customerSnapshot.toPlainObject(),\n      itemsSnapshot: this.itemsSnapshot.map((item) => item.toPlainObject()),\n      financials: {\n        subtotal: this.financials.subtotal.toPlainObject(),\n        taxes: this.financials.taxes.toPlainObject(),\n        shippingCost: this.financials.shippingCost.toPlainObject(),\n        discount: this.financials.discount.toPlainObject(),\n        grandTotal: this.financials.grandTotal.toPlainObject(),\n      },\n      createdOn: this.createdOn.toISOString(),\n      createdBy: this.createdBy,\n    };\n  }\n\n  /**\n   * Reconstruct Invoice from plain object (for repository loading)\n   */\n  static fromPlainObject(data: {\n    invoiceId: string;\n    orderId: string;\n    invoiceNumber: string;\n    customerSnapshot: Parameters<typeof CustomerInfo.fromPlainObject>[0];\n    itemsSnapshot: Parameters<typeof OrderItem.fromPlainObject>[0][];\n    financials: {\n      subtotal: MoneyPlainObject;\n      taxes: MoneyPlainObject;\n      shippingCost: MoneyPlainObject;\n      discount: MoneyPlainObject;\n      grandTotal: MoneyPlainObject;\n    };\n    createdOn: string;\n    createdBy: string;\n    pdfBytes: Uint8Array;\n    status: InvoiceStatus;\n  }): Invoice {\n    const customerSnapshot = CustomerInfo.fromPlainObject(\n      data.customerSnapshot\n    );\n    const itemsSnapshot = data.itemsSnapshot.map((item) =>\n      OrderItem.fromPlainObject(item)\n    );\n\n    const financials: InvoiceFinancials = {\n      subtotal: new Money(\n        data.financials.subtotal.amount,\n        data.financials.subtotal.currency as Currency\n      ),\n      taxes: new Money(\n        data.financials.taxes.amount,\n        data.financials.taxes.currency as Currency\n      ),\n      shippingCost: new ShippingCost(\n        new Money(\n          data.financials.shippingCost.amount,\n          data.financials.shippingCost.currency as Currency\n        )\n      ),\n      discount: new Money(\n        data.financials.discount.amount,\n        data.financials.discount.currency as Currency\n      ),\n      grandTotal: new Money(\n        data.financials.grandTotal.amount,\n        data.financials.grandTotal.currency as Currency\n      ),\n    };\n\n    const invoice = new Invoice(\n      data.invoiceId,\n      data.orderId,\n      data.invoiceNumber,\n      customerSnapshot,\n      itemsSnapshot,\n      financials,\n      new Date(data.createdOn),\n      data.createdBy,\n      data.pdfBytes,\n      data.status\n    );\n\n    // Don't add domain events when reconstructing from persistence\n    return invoice;\n  }\n}\n","export { Money, type MoneyPlainObject } from \"./Money.js\";\nexport { CustomerInfo } from \"./CustomerInfo.js\";\nexport { OrderItem } from \"./OrderItem.js\";\nexport { InvoiceFinancials } from \"./Financials.js\";\nexport { ShippingCost } from './ShippingCost.js';","import { InvoiceTotalMismatchError } from \"../types/index.js\";\nimport type { Money } from \"./Money.js\";\nimport type { ShippingCost } from \"./ShippingCost.js\";\n\n/**\n * Represents the financial breakdown of an invoice, including subtotal, taxes, shipping cost, discount, and grand total.\n *\n * @remarks\n * The grand total is validated to ensure it equals the sum of the subtotal, taxes, and shipping cost, minus the discount.\n * If the calculated grand total does not match the provided value, an {@link InvoiceTotalMismatchError} is thrown.\n *\n * @param subtotal - The total amount before taxes, shipping, and discounts.\n * @param taxes - The total tax amount applied to the invoice.\n * @param shippingCost - The cost associated with shipping.\n * @param discount - The total discount applied to the invoice.\n * @param grandTotal - The final total amount after applying taxes, shipping, and discounts.\n *\n * @throws InvoiceTotalMismatchError - Thrown if the calculated grand total does not match the provided grand total.\n */\nexport class InvoiceFinancials {\n  constructor(\n    readonly subtotal: Money,\n    readonly taxes: Money,\n    readonly shippingCost: ShippingCost,\n    readonly discount: Money,\n    readonly grandTotal: Money\n  ) {\n    // invariant: grand total = subtotal + taxes + shipping - discount\n    const calculated = subtotal.add(taxes).add(shippingCost).subtract(discount);\n    if (!calculated.equals(grandTotal)) {\n      throw new InvoiceTotalMismatchError(calculated, grandTotal);\n    }\n  }\n}\n","export * from './value-objects/index.js';\nexport * from './types/index.js';\nexport * from './entities/index.js';\nexport * from './events/index.js';\nexport * from './services/index.js';\nexport * from './policies/index.js';","export { Invoice } from \"./Invoice.js\";\nexport { InvoiceDraft } from \"./InvoiceDraft.js\";\nexport { AggregateRoot } from \"./aggregate-root.js\";\n","import {\n  InvalidInvoiceNumberError,\n  DuplicateInvoiceNumberError,\n} from \"../types/index.js\";\n\n/**\n * Configuration for invoice number validation\n */\nexport interface InvoiceNumberConfig {\n  readonly pattern: RegExp;\n  readonly prefix?: string;\n  readonly suffix?: string;\n  readonly minLength: number;\n  readonly maxLength: number;\n  readonly requireSequential: boolean;\n}\n\n/**\n * Default German invoice number configuration\n * Format: YYYY-NNNN (e.g., 2024-0001)\n */\nexport const DEFAULT_INVOICE_NUMBER_CONFIG: InvoiceNumberConfig = {\n  pattern: /^\\d{4}-\\d{4}$/,\n  minLength: 9,\n  maxLength: 9,\n  requireSequential: true,\n};\n\n/**\n * Repository interface for checking invoice number uniqueness\n */\nexport interface InvoiceNumberRepository {\n  exists(invoiceNumber: string): Promise<boolean>;\n  getLastSequenceNumber(prefix?: string): Promise<number>;\n}\n\n/**\n * Domain service for validating invoice numbers\n * Handles format validation and uniqueness checking\n */\nexport interface InvoiceNumberValidator {\n  /**\n   * Validates an invoice number against format and uniqueness rules\n   * @param invoiceNumber The invoice number to validate\n   * @throws InvalidInvoiceNumberError if format is invalid\n   * @throws DuplicateInvoiceNumberError if number already exists\n   *\n   * @deprecated Use {@link validateUniqueness} and {@link validateFormat} instead\n   */\n  validate(invoiceNumber: string): Promise<void>;\n\n  /**\n   * Validates just the format without checking uniqueness\n   * @param invoiceNumber The invoice number to validate\n   * @throws InvalidInvoiceNumberError if format is invalid\n   */\n  validateFormat(invoiceNumber: string): void;\n\n  /**\n   * Checks if an invoice number is unique\n   * @param invoiceNumber The invoice number to check\n   * @throws DuplicateInvoiceNumberError if number already exists\n   */\n  validateUniqueness(invoiceNumber: string): Promise<void>;\n}\n\n/**\n * Implementation of InvoiceNumberValidator\n */\nexport class InvoiceNumberValidatorImpl implements InvoiceNumberValidator {\n  constructor(\n    private readonly repository: InvoiceNumberRepository,\n    private readonly config: InvoiceNumberConfig = DEFAULT_INVOICE_NUMBER_CONFIG\n  ) {}\n\n  async validate(invoiceNumber: string): Promise<void> {\n    this.validateFormat(invoiceNumber);\n    await this.validateUniqueness(invoiceNumber);\n\n    if (this.config.requireSequential) {\n      await this.validateSequential(invoiceNumber);\n    }\n  }\n\n  validateFormat(invoiceNumber: string): void {\n    if (!invoiceNumber || typeof invoiceNumber !== \"string\") {\n      throw new InvalidInvoiceNumberError(\n        invoiceNumber,\n        \"Invoice number must be a non-empty string\"\n      );\n    }\n\n    if (\n      invoiceNumber.length < this.config.minLength ||\n      invoiceNumber.length > this.config.maxLength\n    ) {\n      throw new InvalidInvoiceNumberError(\n        invoiceNumber,\n        `Length must be between ${this.config.minLength} and ${this.config.maxLength} characters`\n      );\n    }\n\n    if (!this.config.pattern.test(invoiceNumber)) {\n      throw new InvalidInvoiceNumberError(\n        invoiceNumber,\n        `Must match pattern: ${this.config.pattern.source}`\n      );\n    }\n\n    if (this.config.prefix && !invoiceNumber.startsWith(this.config.prefix)) {\n      throw new InvalidInvoiceNumberError(\n        invoiceNumber,\n        `Must start with prefix: ${this.config.prefix}`\n      );\n    }\n\n    if (this.config.suffix && !invoiceNumber.endsWith(this.config.suffix)) {\n      throw new InvalidInvoiceNumberError(\n        invoiceNumber,\n        `Must end with suffix: ${this.config.suffix}`\n      );\n    }\n  }\n\n  async validateUniqueness(invoiceNumber: string): Promise<void> {\n    const exists = await this.repository.exists(invoiceNumber);\n    if (exists) {\n      throw new DuplicateInvoiceNumberError(invoiceNumber);\n    }\n  }\n\n  /**\n   * Validates that the invoice number follows sequential numbering\n   * For format YYYY-NNNN, ensures NNNN is the next expected sequence number\n   */\n  private async validateSequential(invoiceNumber: string): Promise<void> {\n    // Extract year and sequence number from format YYYY-NNNN\n    const match = invoiceNumber.match(/^(\\d{4})-(\\d{4})$/);\n    if (!match) {\n      return; // Format validation will catch this\n    }\n\n    const [, year, sequenceStr] = match;\n    if (!year || !sequenceStr) {\n      return;\n    }\n    const sequence = parseInt(sequenceStr, 10);\n    const currentYear = new Date().getFullYear().toString();\n\n    // For current year, check if sequence is next expected number\n    if (year === currentYear) {\n      const lastSequence = await this.repository.getLastSequenceNumber(year);\n      const expectedSequence = lastSequence + 1;\n\n      if (sequence !== expectedSequence) {\n        throw new InvalidInvoiceNumberError(\n          invoiceNumber,\n          `Expected sequence number ${expectedSequence\n            .toString()\n            .padStart(4, \"0\")}, got ${sequenceStr}`\n        );\n      }\n    }\n    // For past years, allow any sequence (for historical data)\n    // For future years, reject\n    else if (parseInt(year, 10) > parseInt(currentYear, 10)) {\n      throw new InvalidInvoiceNumberError(\n        invoiceNumber,\n        `Cannot create invoice numbers for future year: ${year}`\n      );\n    }\n  }\n}\n","import type { InvoiceFinancials } from \"../index.js\";\nimport { CustomerInfo } from \"../value-objects/CustomerInfo.js\";\nimport { OrderItem } from \"../value-objects/OrderItem.js\";\n\n/**\n * German legal information required on invoices\n */\nexport interface GermanLegalInfo {\n  readonly companyName: string;\n  readonly companyAddress: {\n    readonly street: string;\n    readonly zip: string;\n    readonly city: string;\n    readonly country: string;\n  };\n  readonly contactInfo: {\n    readonly phone: string;\n    readonly email: string;\n    readonly website?: string;\n  };\n  readonly legalInfo: {\n    readonly vatNumber: string; // USt-IdNr.\n    readonly taxNumber: string; // Steuernummer\n    readonly commercialRegister?: string; // Handelsregister\n    readonly managingDirector?: string; // Geschäftsführer\n  };\n  readonly bankInfo: {\n    readonly bankName: string;\n    readonly iban: string;\n    readonly bic: string;\n  };\n}\n\n/**\n * Complete invoice data for PDF generation\n */\nexport interface InvoiceData {\n  readonly invoiceId: string;\n  readonly invoiceNumber: string;\n  readonly orderId: string;\n  readonly customer: CustomerInfo;\n  readonly items: readonly OrderItem[];\n  readonly financials: InvoiceFinancials;\n  readonly createdOn: Date;\n  readonly createdBy: string;\n  readonly legalInfo: GermanLegalInfo;\n}\n\n/**\n * PDF generation options\n */\nexport interface PDFOptions {\n  readonly format: \"A4\" | \"Letter\";\n  readonly language: \"de\" | \"en\";\n  readonly includeZUGfERD: boolean; // PDF/A-3 with embedded XML\n  readonly watermark?: string;\n  readonly logoUrl?: string;\n}\n\n/**\n * Default PDF options for German invoices\n */\nexport const DEFAULT_PDF_OPTIONS: PDFOptions = {\n  format: \"A4\",\n  language: \"de\",\n  includeZUGfERD: true,\n};\n\n/**\n * Domain service interface for PDF generation\n * Handles creation of legally compliant German invoice PDFs\n */\nexport interface PDFRenderer {\n  /**\n   * Renders an invoice as PDF bytes\n   * @param invoiceData Complete invoice data\n   * @param options PDF generation options\n   * @returns Promise resolving to PDF bytes\n   * @throws PDFGenerationError if rendering fails\n   */\n  render(invoiceData: InvoiceData, options?: PDFOptions): Promise<Uint8Array>;\n\n  /**\n   * Validates that all required legal information is present\n   * @param legalInfo German legal information\n   * @throws InvalidLegalInfoError if required information is missing\n   */\n  validateLegalInfo(legalInfo: GermanLegalInfo): void;\n\n  /**\n   * Generates ZUGfERD XML data for PDF/A-3 compliance\n   * @param invoiceData Invoice data\n   * @returns XML string for embedding\n   */\n  generateZUGfERDXML(invoiceData: InvoiceData): string;\n}\n\n/**\n * Error thrown when PDF generation fails\n */\nexport class PDFGenerationError extends Error {\n  constructor(message: string, public override readonly cause?: Error) {\n    super(message);\n    this.name = \"PDFGenerationError\";\n  }\n}\n\n/**\n * Error thrown when legal information is invalid or incomplete\n */\nexport class InvalidLegalInfoError extends Error {\n  constructor(message: string, public readonly missingFields: string[]) {\n    super(message);\n    this.name = \"InvalidLegalInfoError\";\n  }\n}\n\n/**\n * Base implementation of PDFRenderer with validation logic\n * Concrete implementations should extend this class\n */\nexport abstract class BasePDFRenderer implements PDFRenderer {\n  abstract render(\n    invoiceData: InvoiceData,\n    options?: PDFOptions\n  ): Promise<Uint8Array>;\n\n  validateLegalInfo(legalInfo: GermanLegalInfo): void {\n    const missingFields: string[] = [];\n\n    // Company information\n    if (!legalInfo.companyName?.trim()) {\n      missingFields.push(\"companyName\");\n    }\n    if (!legalInfo.companyAddress?.street?.trim()) {\n      missingFields.push(\"companyAddress.street\");\n    }\n    if (!legalInfo.companyAddress?.zip?.trim()) {\n      missingFields.push(\"companyAddress.zip\");\n    }\n    if (!legalInfo.companyAddress?.city?.trim()) {\n      missingFields.push(\"companyAddress.city\");\n    }\n\n    // Contact information\n    if (!legalInfo.contactInfo?.phone?.trim()) {\n      missingFields.push(\"contactInfo.phone\");\n    }\n    if (!legalInfo.contactInfo?.email?.trim()) {\n      missingFields.push(\"contactInfo.email\");\n    }\n\n    // Legal information (required for German invoices)\n    if (!legalInfo.legalInfo?.vatNumber?.trim()) {\n      missingFields.push(\"legalInfo.vatNumber\");\n    }\n    if (!legalInfo.legalInfo?.taxNumber?.trim()) {\n      missingFields.push(\"legalInfo.taxNumber\");\n    }\n\n    // Bank information\n    if (!legalInfo.bankInfo?.bankName?.trim()) {\n      missingFields.push(\"bankInfo.bankName\");\n    }\n    if (!legalInfo.bankInfo?.iban?.trim()) {\n      missingFields.push(\"bankInfo.iban\");\n    }\n    if (!legalInfo.bankInfo?.bic?.trim()) {\n      missingFields.push(\"bankInfo.bic\");\n    }\n\n    // Validate IBAN format (basic check)\n    if (\n      legalInfo.bankInfo?.iban &&\n      !this.isValidIBAN(legalInfo.bankInfo.iban)\n    ) {\n      missingFields.push(\"bankInfo.iban (invalid format)\");\n    }\n\n    // Validate VAT number format (basic check for German format)\n    if (\n      legalInfo.legalInfo?.vatNumber &&\n      !this.isValidGermanVATNumber(legalInfo.legalInfo.vatNumber)\n    ) {\n      missingFields.push(\"legalInfo.vatNumber (invalid format)\");\n    }\n\n    if (missingFields.length > 0) {\n      throw new InvalidLegalInfoError(\n        `Missing or invalid required legal information: ${missingFields.join(\n          \", \"\n        )}`,\n        missingFields\n      );\n    }\n  }\n\n  generateZUGfERDXML(invoiceData: InvoiceData): string {\n    // Simplified ZUGfERD XML structure\n    // In a real implementation, this would generate proper ZUGfERD 2.0 XML\n    const xml = `<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<rsm:CrossIndustryInvoice xmlns:rsm=\"urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100\">\n  <rsm:ExchangedDocumentContext>\n    <ram:GuidelineSpecifiedDocumentContextParameter>\n      <ram:ID>urn:cen.eu:en16931:2017#compliant#urn:zugferd.de:2p0:basic</ram:ID>\n    </ram:GuidelineSpecifiedDocumentContextParameter>\n  </rsm:ExchangedDocumentContext>\n  <rsm:ExchangedDocument>\n    <ram:ID>${invoiceData.invoiceNumber}</ram:ID>\n    <ram:TypeCode>380</ram:TypeCode>\n    <ram:IssueDateTime>\n      <udt:DateTimeString format=\"102\">${this.formatDateForXML(\n        invoiceData.createdOn\n      )}</udt:DateTimeString>\n    </ram:IssueDateTime>\n  </rsm:ExchangedDocument>\n  <rsm:SupplyChainTradeTransaction>\n    <ram:ApplicableHeaderTradeAgreement>\n      <ram:BuyerReference>${invoiceData.orderId}</ram:BuyerReference>\n      <ram:SellerTradeParty>\n        <ram:Name>${invoiceData.legalInfo.companyName}</ram:Name>\n        <ram:PostalTradeAddress>\n          <ram:LineOne>${\n            invoiceData.legalInfo.companyAddress.street\n          }</ram:LineOne>\n          <ram:CityName>${\n            invoiceData.legalInfo.companyAddress.city\n          }</ram:CityName>\n          <ram:PostcodeCode>${\n            invoiceData.legalInfo.companyAddress.zip\n          }</ram:PostcodeCode>\n          <ram:CountryID>${\n            invoiceData.legalInfo.companyAddress.country\n          }</ram:CountryID>\n        </ram:PostalTradeAddress>\n        <ram:SpecifiedTaxRegistration>\n          <ram:ID schemeID=\"VA\">${\n            invoiceData.legalInfo.legalInfo.vatNumber\n          }</ram:ID>\n        </ram:SpecifiedTaxRegistration>\n      </ram:SellerTradeParty>\n      <ram:BuyerTradeParty>\n        <ram:Name>${invoiceData.customer.firstName} ${\n      invoiceData.customer.lastName\n    }</ram:Name>\n        <ram:PostalTradeAddress>\n          <ram:LineOne>${invoiceData.customer.street}</ram:LineOne>\n          <ram:CityName>${invoiceData.customer.city}</ram:CityName>\n          <ram:PostcodeCode>${invoiceData.customer.zip}</ram:PostcodeCode>\n          <ram:CountryID>${invoiceData.customer.country}</ram:CountryID>\n        </ram:PostalTradeAddress>\n      </ram:BuyerTradeParty>\n    </ram:ApplicableHeaderTradeAgreement>\n    <ram:ApplicableHeaderTradeSettlement>\n      <ram:InvoiceCurrencyCode>${\n        invoiceData.financials.grandTotal.currency\n      }</ram:InvoiceCurrencyCode>\n      <ram:SpecifiedTradeSettlementHeaderMonetarySummation>\n        <ram:LineTotalAmount>${invoiceData.financials.subtotal.toMajorUnit()}</ram:LineTotalAmount>\n        <ram:TaxBasisTotalAmount>${invoiceData.financials.subtotal.toMajorUnit()}</ram:TaxBasisTotalAmount>\n        <ram:TaxTotalAmount currencyID=\"${\n          invoiceData.financials.taxes.currency\n        }\">${invoiceData.financials.taxes.toMajorUnit()}</ram:TaxTotalAmount>\n        <ram:GrandTotalAmount>${invoiceData.financials.grandTotal.toMajorUnit()}</ram:GrandTotalAmount>\n      </ram:SpecifiedTradeSettlementHeaderMonetarySummation>\n    </ram:ApplicableHeaderTradeSettlement>\n  </rsm:SupplyChainTradeTransaction>\n</rsm:CrossIndustryInvoice>`;\n\n    return xml;\n  }\n\n  /**\n   * Robust IBAN validation (ISO 13616 + MOD 97-10)\n   * - Strips spaces\n   * - Checks basic structure\n   * - Validates country-specific length\n   * - Performs modulo 97 check\n   */\n  private isValidIBAN(iban: string): boolean {\n    if (!iban) return false;\n\n    const clean = iban.replace(/\\s+/g, \"\").toUpperCase();\n\n    // Basic structure: 2 letters country, 2 check digits, then alphanumerics\n    if (!/^[A-Z]{2}\\d{2}[A-Z0-9]+$/.test(clean)) return false;\n\n    // Country-specific IBAN lengths (subset covering common countries, incl. DE)\n    const lengths: Record<string, number> = {\n      AT: 20,\n      FR: 27,\n      DE: 22,\n    };\n\n    const country = clean.slice(0, 2);\n    const expectedLength = lengths[country];\n    if (!expectedLength || clean.length !== expectedLength) return false;\n\n    // Rearrange: move first 4 chars to the end\n    const rearranged = clean.slice(4) + clean.slice(0, 4);\n\n    // Replace letters A=10 ... Z=35\n    let numeric = \"\";\n    for (const ch of rearranged) {\n      const code = ch.charCodeAt(0);\n      if (code >= 65 && code <= 90) {\n        numeric += String(code - 55);\n      } else if (code >= 48 && code <= 57) {\n        numeric += ch;\n      } else {\n        return false;\n      }\n    }\n\n    // Mod 97 check (streaming to avoid big integers)\n    let remainder = 0;\n    for (const d of numeric) {\n      remainder = (remainder * 10 + (d.charCodeAt(0) - 48)) % 97;\n    }\n    return remainder === 1;\n  }\n\n  /**\n   * Basic German VAT number validation\n   */\n  private isValidGermanVATNumber(vatNumber: string): boolean {\n    const cleanVat = vatNumber.replace(/\\s/g, \"\").toUpperCase();\n    return /^DE\\d{9}$/.test(cleanVat);\n  }\n\n  /**\n   * Format date for XML (YYYYMMDD)\n   */\n  private formatDateForXML(date: Date): string {\n    return date.toISOString().slice(0, 10).replace(/-/g, \"\");\n  }\n}\n","import type { InvoiceNumberRepository } from \"./InvoiceNumberValidator.js\";\n\n/**\n * Configuration for invoice number generation\n */\nexport interface InvoiceNumberGeneratorConfig {\n  readonly format: \"YYYY-NNNN\" | \"YYYYNNNN\" | \"PREFIX-YYYY-NNNN\" | \"custom\";\n  readonly prefix?: string;\n  readonly suffix?: string;\n  readonly sequenceLength: number; // Number of digits for sequence (e.g., 4 for 0001)\n  readonly startSequence: number; // Starting sequence number (default: 1)\n  readonly customFormatter?: (\n    year: number,\n    sequence: number,\n    prefix?: string,\n    suffix?: string\n  ) => string;\n}\n\n/**\n * Default German invoice number generator configuration\n */\nexport const DEFAULT_GENERATOR_CONFIG: InvoiceNumberGeneratorConfig = {\n  format: \"YYYY-NNNN\",\n  sequenceLength: 4,\n  startSequence: 1,\n};\n\n/**\n * Domain service for generating invoice numbers\n * Handles automatic generation with configurable formats and sequences\n */\nexport interface InvoiceNumberGenerator {\n  /**\n   * Generates the next invoice number in sequence (preview only - doesn't reserve)\n   * @param year Optional year (defaults to current year)\n   * @returns Promise resolving to the generated invoice number\n   */\n  generate(year?: number): Promise<string>;\n\n  /**\n   * Generates a preview of what the next invoice number would be\n   * without actually reserving it\n   * @param year Optional year (defaults to current year)\n   * @returns Promise resolving to the preview invoice number\n   */\n  preview(year?: number): Promise<string>;\n\n  /**\n   * Generates and reserves the next invoice number in sequence\n   * This method should be used when actually creating an invoice\n   * @param year Optional year (defaults to current year)\n   * @returns Promise resolving to the generated and reserved invoice number\n   */\n  generateAndReserve(year?: number): Promise<string>;\n\n  /**\n   * Resets the sequence for a given year (admin function)\n   * @param year The year to reset\n   * @param startFrom The sequence number to start from\n   */\n  resetSequence(year: number, startFrom: number): Promise<void>;\n}\n\n/**\n * Implementation of InvoiceNumberGenerator\n */\nexport class InvoiceNumberGeneratorImpl implements InvoiceNumberGenerator {\n  constructor(\n    private readonly repository: InvoiceNumberRepository,\n    private readonly config: InvoiceNumberGeneratorConfig = DEFAULT_GENERATOR_CONFIG\n  ) {}\n\n  async generate(year?: number): Promise<string> {\n    const targetYear = year ?? new Date().getFullYear();\n    const sequence = await this.getNextSequence(targetYear);\n    return this.formatInvoiceNumber(targetYear, sequence);\n  }\n\n  async preview(year?: number): Promise<string> {\n    const targetYear = year ?? new Date().getFullYear();\n    const lastSequence = await this.repository.getLastSequenceNumber(\n      targetYear.toString()\n    );\n    const nextSequence = lastSequence + 1;\n    return this.formatInvoiceNumber(targetYear, nextSequence);\n  }\n\n  async resetSequence(year: number, startFrom: number): Promise<void> {\n    if (startFrom < 1) {\n      throw new Error(\"Sequence must start from 1 or higher\");\n    }\n\n    // Check if repository supports sequence reset\n    if (\n      \"resetSequence\" in this.repository &&\n      typeof this.repository.resetSequence === \"function\"\n    ) {\n      await (this.repository as any).resetSequence(year.toString(), startFrom);\n    } else {\n      throw new Error(\n        \"resetSequence not supported by repository implementation\"\n      );\n    }\n  }\n\n  /**\n   * Generates and reserves the next invoice number in sequence\n   * This method should be used when actually creating an invoice as it increments the sequence\n   * @param year Optional year (defaults to current year)\n   * @returns Promise resolving to the generated and reserved invoice number\n   */\n  async generateAndReserve(year?: number): Promise<string> {\n    const targetYear = year ?? new Date().getFullYear();\n\n    // Check if repository supports sequence reservation\n    if (\n      \"getNextSequenceNumber\" in this.repository &&\n      typeof this.repository.getNextSequenceNumber === \"function\"\n    ) {\n      const sequence = await (this.repository as any).getNextSequenceNumber(\n        targetYear.toString()\n      );\n      return this.formatInvoiceNumber(targetYear, sequence);\n    }\n\n    // Fallback to regular generation (not recommended for production)\n    return this.generate(targetYear);\n  }\n\n  /**\n   * Gets the next sequence number for the given year (for preview only)\n   */\n  private async getNextSequence(year: number): Promise<number> {\n    const lastSequence = await this.repository.getLastSequenceNumber(\n      year.toString()\n    );\n    return lastSequence + 1;\n  }\n\n  /**\n   * Formats the invoice number according to the configured format\n   */\n  private formatInvoiceNumber(year: number, sequence: number): string {\n    const paddedSequence = sequence\n      .toString()\n      .padStart(this.config.sequenceLength, \"0\");\n\n    switch (this.config.format) {\n      case \"YYYY-NNNN\":\n        return `${year}-${paddedSequence}`;\n\n      case \"YYYYNNNN\":\n        return `${year}${paddedSequence}`;\n\n      case \"PREFIX-YYYY-NNNN\":\n        const prefix = this.config.prefix || \"INV\";\n        return `${prefix}-${year}-${paddedSequence}`;\n\n      case \"custom\":\n        if (!this.config.customFormatter) {\n          throw new Error(\"Custom format requires customFormatter function\");\n        }\n        return this.config.customFormatter(\n          year,\n          sequence,\n          this.config.prefix,\n          this.config.suffix\n        );\n\n      default:\n        throw new Error(`Unsupported format: ${this.config.format}`);\n    }\n  }\n}\n\n/**\n * Predefined generator configurations for common formats\n */\nexport const GENERATOR_PRESETS = {\n  /**\n   * German standard: 2024-0001\n   */\n  GERMAN_STANDARD: {\n    format: \"YYYY-NNNN\" as const,\n    sequenceLength: 4,\n    startSequence: 1,\n  },\n\n  /**\n   * Compact format: 20240001\n   */\n  COMPACT: {\n    format: \"YYYYNNNN\" as const,\n    sequenceLength: 4,\n    startSequence: 1,\n  },\n\n  /**\n   * Prefixed format: INV-2024-0001\n   */\n  PREFIXED: {\n    format: \"PREFIX-YYYY-NNNN\" as const,\n    prefix: \"INV\",\n    sequenceLength: 4,\n    startSequence: 1,\n  },\n\n  /**\n   * Monthly format: 2024-01-001 (custom)\n   */\n  MONTHLY: {\n    format: \"custom\" as const,\n    sequenceLength: 3,\n    startSequence: 1,\n    customFormatter: (year: number, sequence: number) => {\n      const month = new Date().getMonth() + 1;\n      const paddedMonth = month.toString().padStart(2, \"0\");\n      const paddedSequence = sequence.toString().padStart(3, \"0\");\n      return `${year}-${paddedMonth}-${paddedSequence}`;\n    },\n  },\n} as const;\n\n/**\n * Factory function to create generator with preset configuration\n */\nexport function createInvoiceNumberGenerator(\n  repository: InvoiceNumberRepository,\n  preset: keyof typeof GENERATOR_PRESETS = \"GERMAN_STANDARD\"\n): InvoiceNumberGenerator {\n  return new InvoiceNumberGeneratorImpl(repository, GENERATOR_PRESETS[preset]);\n}\n\n/**\n * Utility function to validate generated invoice numbers\n */\nexport function validateGeneratedNumber(\n  invoiceNumber: string,\n  config: InvoiceNumberGeneratorConfig\n): boolean {\n  switch (config.format) {\n    case \"YYYY-NNNN\":\n      return /^\\d{4}-\\d{4}$/.test(invoiceNumber);\n\n    case \"YYYYNNNN\":\n      return /^\\d{8}$/.test(invoiceNumber);\n\n    case \"PREFIX-YYYY-NNNN\":\n      const prefix = config.prefix || \"INV\";\n      const pattern = new RegExp(`^${prefix}-\\\\d{4}-\\\\d{4}$`);\n      return pattern.test(invoiceNumber);\n\n    case \"custom\":\n      // Custom validation would need to be provided\n      return true;\n\n    default:\n      return false;\n  }\n}\n"],"mappings":"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","names":["ErrorCode","OrderStatus","InvoiceStatus","uuidv4","InvoiceDraft"]}