Model kanoniczny: Invoice, InvoicePosition, InvoiceTaxLine i InvoiceCostLink
Dokument zawiera analizę porównawczą (KSeF, systemy ERP, UBL/CDM) oraz definicję dedykowanych zasobów kanonicznych Invoice i InvoicePosition – obok uniwersalnego Document i Profilu Faktura (KSeF). Profil pozostaje odniesieniem do Document; niniejszy model określa osobne obiekty z jawnymi polami faktury i wiersza.
1. Cel: Invoice i InvoicePosition jako zasoby dedykowane
- Document – dokument uniwersalny (FK, WHS, CRM, EOD, HR) z
position[](DocumentPosition) iattribute[]; typ przeztype(np. invoice). - Profil Faktura – konwencja użycia Document dla faktur (mapowanie KSeF, art. 106e); zob. Profil Faktura (KSeF).
- Invoice (niniejszy model) – dedykowany zasób tylko dla faktur: nagłówek z polami wprost (seller, buyer, issueDate, dueDate, paymentAccount, currency, totalNet, totalVat, totalGross); pozycje w tablicy
lines[](InvoicePosition), zgodnie z kontraktem kanonicznym (Invoice.schema.json). Document z profilem faktury używaposition[](DocumentPosition). Ułatwia walidację, API i mapowanie 1:1 na KSeF/ERP bez przechodzenia przez warstwę Document + profil.
InvoicePosition – jedna pozycja faktury (wiersz): positionNo, description, quantity (Quantity), unitPriceNet, netAmount, vatRate (CodeableConcept), vatAmount, exciseAmount, exciseType, productReference, discount (Money), discountCodeableConcept. Zagnieżdżony w Invoice.lines (rekomendacja) lub osobny zasób z referencją do Invoice. InvoiceTaxLine – podsumowanie wartości faktury per stawka VAT, osadzone w Invoice.taxLine[] (sekcja 6). InvoiceCostLink – powiązanie kosztowe pozycji z dokumentem PZ per magazyn, osadzone w InvoicePosition.costLink[] (sekcja 7). Żaden z tych typów nie jest samodzielnym zasobem ani nie rozszerza DomainResource.
2. Analiza porównawcza: nagłówek faktury
| Źródło | Encja / obiekt | Kluczowe pola nagłówka |
|---|---|---|
| KSeF FA(2)/FA(3) | Naglowek, Podmiot1/2/3, Fa | P_1 (numer), P_2_1 (data wystawienia), Podmiot1 (wystawca), Podmiot2 (nabywca), Fa (wiersze, płatność), DataSprzedazy, TerminPlatnosci, WarunkiPlatnosci, NrKontaBankowego, NumerKSeF |
| UBL 2.3 | Invoice | ID, IssueDate, AccountingSupplierParty, AccountingCustomerParty, PaymentMeans, LegalMonetaryTotal (LineExtensionAmount, TaxExclusiveAmount, TaxInclusiveAmount, PayableAmount), InvoiceLine[] |
| SAP SD | VBRK (Billing Doc) | VBELN, FKART, FKDAT (data), KUNAG (nabywca), VKORG, WAERK (waluta), NETWR, MWSKZ (VAT) |
| SAP FI | BKPF + BSEG / RSEG | Dokument księgowy: nagłówek (daty, waluta) + pozycje (konto, kwota Wn/Ma) |
| Oracle AR | RA_CUSTOMER_TRX | trx_number, trx_date, bill_to_customer_id, currency_code, term_id (termin płatności), status; lines w RA_CUSTOMER_TRX_LINES |
| D365 F&O | CustInvoiceTable (FreeText) | InvoiceId, InvoiceDate, CustomerAccount, DueDate, CurrencyCode, Payment; CustInvoiceTrans (wiersze) |
| Microsoft CDM | Invoice (CRM), FreeTextInvoiceHeaderEntity | InvoiceNumber, InvoiceDate, DueDate, CustomerId, TotalAmount, Currency; CDM CustInvoiceTrans: Amount, Quantity, LineNumber |
| Nasz Document + profil | Document + attribute/profile | identifier (w tym system KSeF, value = numer KSeF), issueDate, participant (seller/buyer), attribute (total-net, total-vat, total-gross), profil: saleDate, dueDate, paymentMethod, paymentAccount, splitPayment |
Wnioski dla kanonicznego Invoice (nagłówek):
- Identyfikacja: identifier[] (numer faktury, KSeF, origin) – jak Document.
- Daty: issueDate (1..1), saleDate (0..1), dueDate (0..1), ksefAcquisitionDate (0..1).
- Strony: seller (1..1 Reference PartyRole), buyer (1..1 Reference PartyRole) – zamiast participant[]; ewentualnie payer (0..1 Reference PartyRole).
- Kwoty zagregowane: totalNet, totalVat, totalGross (Money) – jawnie, nie tylko w attribute[].
- Płatność: paymentMethod (CodeableConcept), paymentAccount (Reference BankAccount), splitPayment (boolean).
- KSeF: numer KSeF = identifier (element z Identifier.system wskazującym na KSeF, np.
https://ksef.mf.gov.pl/, Identifier.value = numer nadany przez KSeF); ksefAcquisitionDate (data otrzymania w KSeF). - Waluta: currency (string ISO 4217) – wspólna dla nagłówka i pozycji.
- Powiązania: relatedDocument (Reference Invoice/Document) – korekta, zamówienie.
- Pozostałe: status, type (invoice, correction, proforma), attachment[].
3. Analiza porównawcza: wiersz faktury (pozycja)
| Źródło | Encja / obiekt | Kluczowe pola wiersza |
|---|---|---|
| KSeF FA | FaWiersz | P_7 (nazwa), P_8A (ilość), P_8B (jednostka), P_9 (cena jedn. netto), P_11 (wartość netto), P_12 (stawka VAT), P_13_1 (kwota VAT), P_14_1 (GTU), odniesienie do towaru/usługi |
| UBL 2.3 | InvoiceLine | ID, InvoicedQuantity, LineExtensionAmount, Item (Description, SellersItemIdentification), Price (PriceAmount), TaxTotal per line |
| SAP SD | VBRP | POSNR, MATNR (materiał), FKIMG (ilość), NETWR (netto), MWSKZ (VAT), WAERK |
| Oracle AR | RA_CUSTOMER_TRX_LINES | line_number, description, quantity, unit_selling_price, extended_amount, tax_code |
| D365 | CustInvoiceTrans | LineNum, ItemId, Qty, SalesPrice, LineAmount, TaxGroup, TaxAmount |
| CDM | CustInvoiceTrans | LineNumber, Amount, Quantity, Description, ProductId |
| Nasz DocumentPosition | position (invoice-line) | code, positionNo, valueItem (quantity, unit-price, net-amount, vat-amount), valueCodeableConcept (vat-rate), valueReference (Product), valueString (opis) |
Wnioski dla kanonicznego InvoicePosition:
- positionNo (integer, 1..1) – numer wiersza od 1.
- description (string, 0..1) – opis towaru/usługi (P_7, UBL Item/Description).
- quantity (Quantity, 0..1) – ilość + jednostka (P_8A, P_8B).
- unitPriceNet (Money, 0..1) – cena jedn. netto (P_9).
- netAmount (Money, 1..1) – wartość netto pozycji (P_11).
- vatRate (CodeableConcept, 0..1) – stawka VAT (P_12; system vat-rate).
- vatAmount (Money, 0..1) – kwota VAT (P_13_1).
- productReference (Reference ProductDefinition | Product, 0..1) – towar/usługa (nie pełny obiekt).
- discount (Money, 0..1) – rabat/opust jako kwota.
- discountCodeableConcept (CodeableConcept, 0..1) – rabat/opust jako wartość kodowana (np. kod rodzaju ulgi).
- Rozszerzenia wierszowe (indeks, GTU, kraj pochodzenia itd.) — typ InvoicePosition nie zawiera tablicy
attribute; wyraża się je przezInvoice.attribute(wspólne pole z DomainResource) według konwencji profilu integracji (np. osobny Attribute z code + valueItem wiążącym numer wiersza z wartością), albo przez zasób Document z DocumentPosition i polami valueItem / valueCodeableConcept na pozycji — patrz Invoice-Examples.
4. Proponowana struktura Invoice (zasób kanoniczny)
Invoice rozszerza DomainResource. Pola:
| Pole | Kard. | Typ | Opis |
|---|---|---|---|
| identifier | 1..* | Identifier | Identyfikatory faktury: numer (system np. company); opcjonalnie element z system wskazującym na KSeF (np. https://ksef.mf.gov.pl/), value = numer nadany przez KSeF |
| issueDate | 1..1 | date | Data wystawienia |
| saleDate | 0..1 | date | Data sprzedaży (gdy inna niż issueDate) |
| dueDate | 0..1 | date | Termin płatności |
| seller | 1..1 | Reference(PartyRole) | Wystawca (PartyRole, role=seller) |
| buyer | 1..1 | Reference(PartyRole) | Nabywca (PartyRole, role=buyer) |
| payer | 0..1 | Reference(PartyRole) | Płatnik (gdy inny niż buyer) |
| totalNet | 0..1 | Money | Suma netto (dokument) |
| totalVat | 0..1 | Money | Suma VAT |
| totalExcise | 0..1 | Money | Suma akcyzy (dokument); gdy na fakturze są wyroby akcyzowe |
| totalGross | 1..1 | Money | Kwota należności ogółem |
| currency | 1..1 | string (ISO 4217) | Waluta faktury |
| paymentMethod | 0..1 | CodeableConcept | Sposób zapłaty |
| paymentAccount | 0..1 | Reference(BankAccount) | Rachunek bankowy do wpłaty |
| splitPayment | 0..1 | boolean | Mechanizm podzielonej płatności (MPP) |
| ksefAcquisitionDate | 0..1 | dateTime | Data otrzymania w KSeF (rejestracji) |
| lines | 1..* | InvoicePosition | Wiersze faktury w JSON (pole lines, nie position) |
| taxLine | 0..* | InvoiceTaxLine | Podsumowanie wartości faktury w rozbiciu na stawki VAT — patrz sekcja 6 |
| attribute | 0..* | Attribute | Atrybuty rozszerzające |
| relatedDocument | 0..* | Reference(Invoice) lub Reference(Document) | Korekta, faktura korygowana, zamówienie |
| attachment | 0..* | Attachment | Załączniki |
type (z DomainResource): invoice, correction, proforma (system document-type). status: draft, issued, sent, paid, cancelled.
5. Proponowana struktura InvoicePosition (typ zagnieżdżony)
InvoicePosition jest typem zagnieżdżonym w Invoice (jak DocumentPosition w Document) i nie jest osobnym zasobem DomainResource.
| Pole | Kard. | Typ | Opis |
|---|---|---|---|
| positionNo | 1..1 | integer | Numer wiersza (od 1); do referencji np. LedgerEntry.sourcePositionNo |
| description | 0..1 | string | Opis towaru/usługi |
| quantity | 0..1 | Quantity | Ilość + jednostka |
| unitPriceNet | 0..1 | Money | Cena jedn. netto |
| netAmount | 1..1 | Money | Wartość netto pozycji |
| vatRate | 0..1 | CodeableConcept | Stawka VAT (system vat-rate) |
| vatAmount | 0..1 | Money | Kwota VAT pozycji |
| exciseAmount | 0..1 | Money | Kwota akcyzy pozycji (gdy wyroby akcyzowe) |
| exciseType | 0..1 | CodeableConcept | Rodzaj / stawka akcyzy (system np. excise-type); opcjonalnie |
| productReference | 0..1 | Reference(ProductDefinition lub Product) | Referencja do towaru/usługi |
| discount | 0..1 | Money | Rabat/opust (kwota) |
| discountCodeableConcept | 0..1 | CodeableConcept | Rabat/opust (kodowanie) |
| costLink | 0..* | InvoiceCostLink | Powiązania kosztowe pozycji z dokumentami PZ (jeden element per powiązanie pozycja–PZ–magazyn) — patrz sekcja 7 |
Nie definiuje się wariantu, w którym InvoicePosition jest osobnym zasobem DomainResource. InvoicePosition pozostaje elementem struktury Invoice.lines[].
Podsumowanie VAT per stawka wyraża się przez InvoiceTaxLine osadzone w
Invoice.taxLine[]— patrz sekcja 6.
6. Typ osadzony: InvoiceTaxLine (Invoice.taxLine[])
InvoiceTaxLine to typ wartości (complex-type) osadzany jako tablica taxLine[] bezpośrednio w Invoice. Nie jest samodzielnym zasobem, nie rozszerza DomainResource i nie posiada własnej identyfikacji. Gromadzi sumy netto, VAT i brutto per stawka VAT — wymagane przez art. 106e ust. 1 pkt 8–10 ustawy o VAT.
Relacja: jedna faktura → wiele InvoiceTaxLine (po jednym elemencie na każdą unikalną stawkę VAT).
6.1. Struktura
| Pole | Kard. | Typ | Opis |
|---|---|---|---|
| vatRate | 1..1 | CodeableConcept | Stawka VAT — system vat-rate. Kody liczbowe: 23, 8, 5, 0. Kody specjalne: ZW (zwolniony), NP (nie podlega). Patrz ValueSet vat-rate |
| netAmount | 1..1 | Money | Wartość netto dla stawki VAT |
| vatAmount | 1..1 | Money | Kwota VAT dla stawki |
| grossAmount | 1..1 | Money | Wartość brutto dla stawki (netAmount + vatAmount) |
Waluta dziedziczona z Invoice.currency. Suma netAmount wszystkich elementów = Invoice.totalNet; suma vatAmount = Invoice.totalVat; suma grossAmount = Invoice.totalGross.
6.2. Mapowanie: ERP → InvoiceTaxLine
| Pole źródłowe (ERP) | Pole InvoiceTaxLine |
Uwaga |
|---|---|---|
vat_rate |
vatRate (CodeableConcept) |
System vat-rate; wartości ZW i NP jako kody specjalne |
nett_value |
netAmount (Money) |
Waluta domyślnie PLN |
tax_value |
vatAmount (Money) |
|
gross_value |
grossAmount (Money) |
6.3. Mapowanie: KSeF FA → InvoiceTaxLine
| Przepis / KSeF FA(2)/FA(3) | InvoiceTaxLine |
|---|---|
| Art. 106e ust. 1 pkt 8 (suma wartości netto per stawka) | netAmount |
| Art. 106e ust. 1 pkt 9 (kwota podatku per stawka) | vatAmount |
| Art. 106e ust. 1 pkt 10 (kwota należności ogółem per stawka) | grossAmount |
Identyfikator stawki (KSeF: P_12, np. 23, ZW, NP) |
vatRate.coding[].code (system vat-rate) |
6.4. Przykład JSON
{
"id": "INV-2026-0042",
"totalNet": { "value": 2500.00, "currency": "PLN" },
"totalVat": { "value": 290.00, "currency": "PLN" },
"totalGross": { "value": 2790.00, "currency": "PLN" },
"taxLine": [
{
"vatRate": { "coding": [{ "system": "https://api-erp.kamsoft.pl/ns/vat-rate", "code": "23" }] },
"netAmount": { "value": 1500.00, "currency": "PLN" },
"vatAmount": { "value": 345.00, "currency": "PLN" },
"grossAmount": { "value": 1845.00, "currency": "PLN" }
},
{
"vatRate": { "coding": [{ "system": "https://api-erp.kamsoft.pl/ns/vat-rate", "code": "8" }] },
"netAmount": { "value": 800.00, "currency": "PLN" },
"vatAmount": { "value": 64.00, "currency": "PLN" },
"grossAmount": { "value": 864.00, "currency": "PLN" }
},
{
"vatRate": { "coding": [{ "system": "https://api-erp.kamsoft.pl/ns/vat-rate", "code": "ZW", "display": "Zwolniony" }] },
"netAmount": { "value": 200.00, "currency": "PLN" },
"vatAmount": { "value": 0.00, "currency": "PLN" },
"grossAmount": { "value": 200.00, "currency": "PLN" }
}
]
}
6.5. Zgodność z systemami wzorcowymi
| System | Odpowiednik | Pole → InvoiceTaxLine |
|---|---|---|
| SAP FI (BSET) | Tax Line Items per document | MWSKZ → vatRate; HWBAS → netAmount; HWSTE → vatAmount |
| Oracle AP/AR | AP_INVOICE_DISTRIBUTIONS (LINE_TYPE='TAX') | TAX_CODE → vatRate; BASE_AMOUNT → netAmount; AMOUNT → vatAmount |
| D365 F&O (TaxTrans) | Tabela transakcji VAT | TaxCode → vatRate; TaxBaseAmountCur → netAmount; TaxAmountCur → vatAmount |
| UBL 2.3 | Invoice/TaxTotal/TaxSubtotal | TaxCategory/Percent → vatRate; TaxableAmount → netAmount; TaxAmount → vatAmount |
| KSeF FA(2)/FA(3) | P_13_x (netto per stawka), P_14_x (VAT per stawka) | P_12 → vatRate; P_13_1 (23%) → netAmount; P_14_1 → vatAmount |
| Microsoft CDM | SalesTaxTransaction | TaxCode → vatRate; TaxBaseAmount → netAmount; TaxAmount → vatAmount |
7. Typ osadzony: InvoiceCostLink (InvoicePosition.costLink[])
InvoiceCostLink to typ wartości (complex-type) osadzany jako tablica costLink[] w InvoicePosition. Nie jest samodzielnym zasobem, nie rozszerza DomainResource i nie posiada własnej identyfikacji. Reprezentuje powiązanie kosztowe pozycji faktury z dokumentem PZ (Przyjęcie Zewnętrzne) i wartość kosztową dla danego magazynu — służy wyłącznie do odczytu (projekcja/agregat raportowy).
Relacja: jedna pozycja faktury → wiele InvoiceCostLink (jeden element na każde powiązanie pozycja–PZ–magazyn).
InvoicePosition ──(InvoicePosition.costLink[])──< InvoiceCostLink >──(1)──> InventoryDocument (PZ)
│
└──(1)──> Location lub Party (magazyn / podmiot)
7.1. Struktura
| Pole | Kard. | Typ | Opis |
|---|---|---|---|
| sourceDocument | 1..1 | Reference(InventoryDocument) | Dokument PZ; reference = identyfikator PZ (pz_id), display = nazwa definicji (pz) |
| location | 1..1 | Reference(Location lub Party) | Magazyn przyjęcia (warehouse) lub podmiot prowadzący magazyn |
| costAmount | 1..1 | Money | Suma wartości pozycji PZ powiązanych z fakturą (cost_value). Waluta domyślnie PLN |
| comment | 0..1 | string | Uwagi z nagłówka dokumentu PZ (cost_description) |
| category | 0..1 | CodeableConcept | Rodzaj kosztu (cost_type); aktualnie zawsze null — zarezerwowane |
| relatedDocument | 0..* | Reference | Powiązane dokumenty: umowa (agreement_id), zamówienie (order_id); aktualnie null — zarezerwowane |
Wymagane: sourceDocument, location, costAmount. Referencja do InvoicePosition jest niejawna — wynika z osadzenia w InvoicePosition.costLink[].
7.2. Mapowanie: ERP → InvoiceCostLink
| Pole źródłowe (ERP) | Pole InvoiceCostLink |
Uwaga |
|---|---|---|
pz_id |
sourceDocument.reference |
Wewnętrzny ID dokumentu PZ |
pz |
sourceDocument.display |
Nazwa definicji dokumentu PZ |
warehouse |
location.reference |
ID magazynu (Location) lub podmiotu (Party) |
cost_value |
costAmount.value |
Waluta domyślnie PLN |
cost_description |
comment |
Uwagi z nagłówka PZ |
cost_type |
category |
Aktualnie null; zarezerwowane |
agreement_id, agreement_number |
relatedDocument[] (type: agreement) |
Aktualnie null; zarezerwowane |
order_id, order_number |
relatedDocument[] (type: order) |
Aktualnie null; zarezerwowane |
patient_id, mpk_id, managers_account_id |
(nie mapowane) | Aktualnie null; przewidziane dla przyszłych wersji |
7.3. Parametry zapytania (przykład: GET /v1/cost-documents)
| Parametr ERP | Opis | Odpowiednik w InvoiceCostLink |
|---|---|---|
ADataP, ADataK |
Okres wg daty przyjęcia dokumentu (wymagany) | filtr po dacie sourceDocument.effectiveDate |
AIDDofv |
Identyfikator faktury (opcjonalny) | filtr po Invoice.id |
AIDMagz |
Identyfikator magazynu (opcjonalny) | location.reference |
AIDPoralntg |
Identyfikator jednostki organizacyjnej (opcjonalny) | filtr organizacyjny |
AIDFirm |
Identyfikator podmiotu w grupie (opcjonalny) | kontekst multitenancy |
AWKomis |
Uwzględniać dokumenty komisowe (1/0) | filtr type dokumentu PZ |
7.4. Przykład JSON
{
"positionNo": 1,
"description": "Pozycja faktury",
"costLink": [
{
"sourceDocument": { "reference": "InventoryDocument/391", "display": "PZ Przyjęcie Zewnętrzne" },
"location": { "reference": "Location/12", "display": "Magazyn Centralny" },
"costAmount": { "value": 18450.00, "currency": "PLN" },
"comment": "Dostawa leków – faktura kwiecień 2026"
},
{
"sourceDocument": { "reference": "InventoryDocument/392", "display": "PZ Przyjęcie Zewnętrzne" },
"location": { "reference": "Location/5", "display": "Magazyn Apteki" },
"costAmount": { "value": 3200.00, "currency": "PLN" }
}
]
}
7.5. Zgodność z systemami wzorcowymi
| System | Odpowiednik | Pole → InvoiceCostLink |
|---|---|---|
| SAP MM/FI | RBKP + RSEG powiązane z EKBE (GR↔IR) i MSEG | MSEG.MBLNR → sourceDocument; MSEG.LGORT → location; RSEG.WRBTR → costAmount; RSEG.SGTXT → comment |
| Oracle AP | AP_INVOICE_DISTRIBUTIONS + RCV_TRANSACTIONS | RCV_TRANSACTIONS.TRANSACTION_ID → sourceDocument; ORGANIZATION_ID → location; AMOUNT → costAmount |
| D365 F&O | VendInvoiceInfoTable + VendPackingSlipJour | PackingSlipId → sourceDocument; InventLocationId → location; LineAmount → costAmount |
| UBL 2.3 | Invoice/DespatchDocumentReference | DespatchDocumentReference.ID → sourceDocument; DeliveryLocation.ID → location |
| Microsoft CDM | VendorInvoice + PurchaseOrderReceipt | ReceiptId → sourceDocument; WarehouseId → location |
8. Mapowanie: Document + profil → Invoice / InvoicePosition
| Document + profil | Invoice / InvoicePosition |
|---|---|
| Document.identifier | Invoice.identifier |
| Document.issueDate | Invoice.issueDate |
| Document.participant[0] (seller) | Invoice.seller |
| Document.participant[1] (buyer) | Invoice.buyer |
| Profil: saleDate, dueDate | Invoice.saleDate, dueDate |
| Profil: paymentMethod, paymentAccount, splitPayment | Invoice.paymentMethod, paymentAccount, splitPayment |
| Profil: numer KSeF w Document.identifier (system KSeF, value), ksefAcquisitionDate | Invoice.identifier (element z system KSeF, value), Invoice.ksefAcquisitionDate |
| Document.attribute (total-net, total-vat, total-excise, total-gross) | Invoice.totalNet, totalVat, totalExcise, totalGross (+ opcjonalnie attribute) |
| Document.position[] (invoice-line) | Invoice.lines[] (InvoicePosition) |
| DocumentPosition.positionNo, valueString | InvoicePosition.positionNo, description |
| DocumentPosition.valueItem (quantity, unit-price, net-amount, vat-amount, excise-amount) | InvoicePosition.quantity, unitPriceNet, netAmount, vatAmount, exciseAmount |
| DocumentPosition.valueCodeableConcept (vat-rate, rodzaj akcyzy) | InvoicePosition.vatRate, exciseType |
| DocumentPosition.valueReference (Product) | InvoicePosition.productReference |
| Document.relatedDocument | Invoice.relatedDocument |
9. Mapowanie: KSeF FA(2)/FA(3) → Invoice / InvoicePosition
| KSeF (Naglowek, Podmiot, Fa) | Invoice |
|---|---|
| P_1 (numer), P_2_1 (data wystawienia) | identifier, issueDate |
| Podmiot1 (wystawca) | seller (Reference PartyRole) |
| Podmiot2 (nabywca) | buyer (Reference PartyRole) |
| Podmiot3 (płatnik) | payer (0..1) |
| DataSprzedazy, TerminPlatnosci | saleDate, dueDate |
| WarunkiPlatnosci, NrKontaBankowego | paymentMethod, paymentAccount |
| NumerKSeF, data rejestracji | identifier (system KSeF, value = numer KSeF), ksefAcquisitionDate |
| Fa (sumy) | totalNet, totalVat, totalExcise, totalGross, currency |
| FaWiersz (pozycja) | InvoicePosition (patrz poniżej) |
| KSeF FaWiersz | InvoicePosition |
|---|---|
| P_7 (nazwa towaru/usługi) | description |
| P_8A (ilość), P_8B (jednostka) | quantity (Quantity) |
| P_9 (cena jedn. netto) | unitPriceNet |
| P_11 (wartość netto) | netAmount |
| P_12 (stawka VAT) | vatRate |
| P_13_1 (kwota VAT) | vatAmount |
| Kwota akcyzy (wiersz) | exciseAmount, exciseType |
| Odniesienie do towaru | productReference |
| P_14_1 (GTU) itd. | Invoice.attribute lub pozycja jako DocumentPosition (np. valueCodeableConcept / valueItem — bez pola attribute na InvoicePosition w modelu referencyjnym) |
10. Zgodność z systemami ERP (podsumowanie)
| System | Nagłówek → Invoice | Wiersz → InvoicePosition |
|---|---|---|
| SAP SD (VBRK/VBRP) | VBELN→identifier, FKDAT→issueDate, KUNAG→buyer, WAERK→currency, NETWR→totalNet | POSNR→positionNo, MATNR→productReference, FKIMG→quantity, NETWR→netAmount, MWSKZ→vatRate |
| Oracle AR | trx_number→identifier, trx_date→issueDate, bill_to_customer_id→buyer, currency_code→currency | line_number→positionNo, description, quantity, unit_selling_price, extended_amount→netAmount |
| D365 CustInvoiceTable/Trans | InvoiceId, InvoiceDate, CustomerAccount→buyer, DueDate, CurrencyCode | LineNum→positionNo, Qty, SalesPrice, LineAmount, TaxGroup→vatRate |
| UBL 2.3 Invoice | ID, IssueDate, AccountingSupplierParty→seller, AccountingCustomerParty→buyer, LegalMonetaryTotal→totalNet/totalVat/totalGross | InvoiceLine: InvoicedQuantity→quantity, LineExtensionAmount→netAmount, Price/PriceAmount→unitPriceNet |
| CDM | InvoiceNumber, InvoiceDate, DueDate, CustomerId→buyer, TotalAmount→totalGross | LineNumber→positionNo, Quantity, Amount→netAmount |
11. Relacja do Document i profilu
- Document + Invoice-Profile – może służyć unifikacji dokumentów jako Document (np. archiwum / obieg); dekretacja faktury w kanonie API.ERP wyłącznie Invoice + PostingInstruction — Document nie uczestniczy w tym procesie. GR/GI są wyłącznie w InventoryDocument. Profil FK opisuje konwencję mapowania KSeF tam, gdzie Document jest użyty jako widok.
- Invoice + InvoicePosition – dedykowany model kanoniczny dla faktur: jawna struktura (seller, buyer, totalNet, totalVat, totalGross, lines[].netAmount, vatRate itd.), wygodna walidacja i integracja z KSeF/ERP. W implementacji można:
- wystawiać tylko Invoice (API faktur) i opcjonalnie transformować do Document dla EOD/archiwum, albo
- utrzymywać Document jako źródło prawdy i generować Invoice jako widok/zestawienie dla klientów API faktur.
12. PostingInstruction (dekretacja faktury EOD → FKW)
Księgowanie faktury w kanonie API.ERP odbywa się wyłącznie przez parę Invoice + PostingInstruction. Document nie uczestniczy w tym procesie.
PostingInstruction zawiera m.in.:
- symbol, status, daty i parametry procesu FK na nagłówku;
- position[] — pozycje bufora (
accounting-item,vat-summary) z kwotami, alokacjami KR/KO i referencjami; - opcjonalnie register, accountingVariant, paymentAccount.
FKW materializuje LedgerEntry i ewidencje VAT z danych PostingInstruction. Alokacje na CostCarrier — osobno CostAssignment.
13. Odniesienia
- Document, DocumentPosition, Profil Faktura (KSeF)
- PostingInstruction, Register, AccountingVariant
- PartyRole, Party, BankAccount, Attribute
- InventoryDocument, Location — powiązane z
InvoicePosition.costLink[] - KSeF: struktura FA(3); art. 106e ustawy o VAT
- UBL 2.3 Invoice, OAGIS, SAP SD Billing, Oracle AR, D365 F&O, Microsoft CDM
- Schematy JSON:
schemas/canonical-eod/Invoice.schema.json,InvoicePosition.schema.json,InvoiceTaxLine.schema.json,InvoiceCostLink.schema.json - ValueSet
vat-rate— kody stawek VAT