Skip to content

Data Model

All model classes live under Zugpferd::Model and map to EN 16931 Business Groups (BGs) and Business Terms (BTs) as used by XRechnung and ZUGFeRD. Monetary values are BigDecimal, dates are Date objects.

BillingDocument Module

All document types include the BillingDocument module which provides the shared attributes and initialization logic. Each class defines a TYPE_CODE constant that serves as the default for type_code.

ClassTYPE_CODEDescription
Model::Invoice"380"Commercial Invoice
Model::CreditNote"381"Credit Note
Model::CorrectedInvoice"384"Corrected Invoice
Model::SelfBilledInvoice"389"Self-billed Invoice
Model::PartialInvoice"326"Partial Invoice
Model::PrepaymentInvoice"386"Prepayment Invoice

Invoice (BG-0)

Commercial Invoice, type code 380.

ruby
invoice = Zugpferd::Model::Invoice.new(
  number: "INV-001",       # BT-1 (required)
  issue_date: Date.today,  # BT-2 (required)
  currency_code: "EUR"     # BT-5 (default: "EUR")
)
AttributeBTTypeDescription
numberBT-1StringInvoice number
issue_dateBT-2DateIssue date
due_dateBT-9DatePayment due date
type_codeBT-3StringInvoice type code (see supported types)
currency_codeBT-5StringDocument currency
buyer_referenceBT-10StringBuyer reference
customization_idBT-24StringSpecification identifier
profile_idBT-23StringBusiness process type
noteBT-22StringInvoice note
sellerBG-4TradePartySeller party
buyerBG-7TradePartyBuyer party
line_itemsBG-25Array<LineItem>Invoice lines
allowance_chargesBG-20/21Array<AllowanceCharge>Document-level allowances/charges
tax_breakdownBG-23TaxBreakdownVAT breakdown
monetary_totalsBG-22MonetaryTotalsDocument totals
payment_instructionsBG-16PaymentInstructionsPayment information

Other Document Types

ruby
credit_note = Zugpferd::Model::CreditNote.new(number: "CN-001", issue_date: Date.today)
corrected   = Zugpferd::Model::CorrectedInvoice.new(number: "C-001", issue_date: Date.today)
self_billed = Zugpferd::Model::SelfBilledInvoice.new(number: "SB-001", issue_date: Date.today)
partial     = Zugpferd::Model::PartialInvoice.new(number: "P-001", issue_date: Date.today)
prepayment  = Zugpferd::Model::PrepaymentInvoice.new(number: "PP-001", issue_date: Date.today)

All document types share the same attributes (see table above). When using UBL, CreditNote produces a <CreditNote> root element with its own namespace. All other types use the standard <Invoice> element. In CII, the structure is identical for all type codes.

TradeParty (BG-4 / BG-7)

Seller or buyer party.

ruby
party = Zugpferd::Model::TradeParty.new(name: "Company GmbH")
AttributeBTTypeDescription
nameBT-27/44StringLegal name (required)
trading_nameBT-28/45StringTrading name
identifierBT-29/46StringParty identifier
legal_registration_idBT-30/47StringLegal registration ID
legal_formBT-33StringCompany legal form
vat_identifierBT-31/48StringVAT identifier
electronic_addressBT-34/49StringElectronic address
electronic_address_schemeBT-34-1/49-1StringScheme ID (e.g. "EM")
postal_addressBG-5/8PostalAddressPostal address
contactBG-6/9ContactContact information

PostalAddress (BG-5 / BG-8)

ruby
addr = Zugpferd::Model::PostalAddress.new(country_code: "DE")
AttributeBTTypeDescription
country_codeBT-40/55StringCountry code (required)
street_nameBT-35/50StringStreet
city_nameBT-37/52StringCity
postal_zoneBT-38/53StringPostal code

Contact (BG-6 / BG-9)

ruby
contact = Zugpferd::Model::Contact.new
contact.name = "Max Mustermann"
contact.telephone = "+49 30 12345"
contact.email = "max@example.com"
AttributeBTTypeDescription
nameBT-41/56StringContact name
telephoneBT-42/57StringTelephone
emailBT-43/58StringEmail

LineItem (BG-25)

ruby
line = Zugpferd::Model::LineItem.new(
  id: "1",
  invoiced_quantity: "10",
  unit_code: "C62",
  line_extension_amount: "1000.00"
)
AttributeBTTypeDescription
idBT-126StringLine identifier (required)
invoiced_quantityBT-129StringQuantity (required)
unit_codeBT-130StringUnit code (required)
line_extension_amountBT-131StringLine total (required)
noteBT-127StringLine note
itemBG-31ItemItem information
priceBG-29PricePrice details

Item (BG-31)

ruby
item = Zugpferd::Model::Item.new(name: "Widget")
item.tax_category = "S"
item.tax_percent = BigDecimal("19")
AttributeBTTypeDescription
nameBT-153StringItem name (required)
descriptionBT-154StringItem description
sellers_identifierBT-155StringSeller's item ID
tax_categoryBT-151StringTax category code
tax_percentBT-152BigDecimalTax rate

Price (BG-29)

ruby
price = Zugpferd::Model::Price.new(amount: "100.00")
AttributeBTTypeDescription
amountBT-146StringItem net price (required)

MonetaryTotals (BG-22)

ruby
totals = Zugpferd::Model::MonetaryTotals.new(
  line_extension_amount: "1000.00",
  tax_exclusive_amount: "1000.00",
  tax_inclusive_amount: "1190.00",
  payable_amount: "1190.00"
)
AttributeBTTypeDescription
line_extension_amountBT-106StringSum of line totals (required)
tax_exclusive_amountBT-109StringTotal without VAT (required)
tax_inclusive_amountBT-112StringTotal with VAT (required)
payable_amountBT-115StringAmount due (required)
prepaid_amountBT-113BigDecimalPrepaid amount
payable_rounding_amountBT-114BigDecimalRounding amount
allowance_total_amountBT-107BigDecimalTotal allowances
charge_total_amountBT-108BigDecimalTotal charges

TaxBreakdown (BG-23)

ruby
breakdown = Zugpferd::Model::TaxBreakdown.new(
  tax_amount: "190.00",
  currency_code: "EUR"
)
breakdown.subtotals << Zugpferd::Model::TaxSubtotal.new(...)
AttributeBTTypeDescription
tax_amountBT-110StringTotal tax amount (required)
currency_codeBT-110-1StringTax currency (required)
subtotalsArray<TaxSubtotal>Tax subtotals

TaxSubtotal

ruby
sub = Zugpferd::Model::TaxSubtotal.new(
  taxable_amount: "1000.00",
  tax_amount: "190.00",
  category_code: "S",
  currency_code: "EUR",
  percent: BigDecimal("19")
)
AttributeBTTypeDescription
taxable_amountBT-116StringTax base (required)
tax_amountBT-117StringTax amount (required)
category_codeBT-118StringTax category code (required)
currency_codeStringCurrency (required)
percentBT-119BigDecimalTax rate
exemption_reasonBT-120StringExemption reason
exemption_reason_codeBT-121StringExemption reason code

PaymentInstructions (BG-16)

ruby
payment = Zugpferd::Model::PaymentInstructions.new(
  payment_means_code: "58"
)
payment.account_id = "DE89370400440532013000"
AttributeBTTypeDescription
payment_means_codeBT-81StringPayment means code (required)
payment_idBT-83StringPayment reference
account_idBT-84StringIBAN
noteBT-82StringPayment terms note
card_account_idBT-87StringPayment card number
card_holder_nameBT-88StringCard holder name
card_network_idStringCard network (UBL only)
mandate_referenceBT-89StringDirect debit mandate reference
creditor_reference_idBT-90StringBank assigned creditor ID
debited_account_idBT-91StringDebited account IBAN

AllowanceCharge (BG-20 / BG-21)

ruby
charge = Zugpferd::Model::AllowanceCharge.new(
  charge_indicator: true,
  amount: "50.00"
)
charge.reason = "Service charge"
charge.tax_category_code = "S"
charge.tax_percent = BigDecimal("19")
AttributeBTTypeDescription
charge_indicatorBT-92/95Booleantrue = charge, false = allowance (required)
amountBT-92/99BigDecimalAmount (required)
reasonBT-97/104StringReason
reason_codeBT-98/105StringReason code
base_amountBT-93/100BigDecimalBase amount
multiplier_factorBT-94/101BigDecimalPercentage
tax_category_codeBT-95/102StringTax category
tax_percentBT-96/103BigDecimalTax rate