You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: README.md
+74-35Lines changed: 74 additions & 35 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -13,19 +13,61 @@ Bidirectional conversion between GOBL and the Polish FA_VAT XML format (KSeF).
13
13
14
14
Copyright [Invopop Ltd.](https://invopop.com) 2023. Released publicly under the [Apache License Version 2.0](LICENSE). For commercial licenses please contact the [dev team at invopop](mailto:dev@invopop.com). In order to accept contributions to this library we will require transferring copyrights to Invopop Ltd.
15
15
16
-
## Project Development Objectives
17
-
18
-
The following list the steps to follow through on in order to accomplish the goal of using GOBL to submit electronic invoices to the Polish authorities:
19
-
20
-
1. Add the PL (`pl`) tax regime to [GOBL](https://github.com/invopop/gobl). Figure out local taxes, tax ID validation rules, and any "extensions" that may be required to be defined in GOBL, and send in a PR. For examples of existing regimes, see the [regimes](https://github.com/invopop/gobl/tree/main/regimes) directory. Key Concerns:
21
-
- Basic B2B invoices support.
22
-
- Tax ID validation as per local rules.
23
-
- Support for "simplified" invoices.
24
-
- Requirements for credit-notes or "rectified" invoices and the correction options definition for the tax regime.
25
-
- Any additional fields that need to be validated, like payment terms.
26
-
2. Convert GOBL into FA_VAT format in library. A couple of good examples: [gobl.cfdi for Mexico](https://github.com/invopop/gobl.cfdi) and [gobl.verifactu for Spain](https://github.com/invopop/gobl.verifactu). Library would just be able to run tests in the first version.
27
-
3. Build a CLI (copy from gobl.cfdi and gobl.verifactu projects) to convert GOBL JSON documents into FA_VAT XML.
28
-
4. Build a second part of this project that allows documents to be sent directly to the KSeF. A partial example of this can be found in the [gobl.ticketbai project](https://github.com/invopop/gobl.ticketbai/tree/refactor/internal/gateways). It'd probably be useful to be able to upload via the CLI too.
16
+
## Supported Features
17
+
18
+
The converter handles the following invoice types and features:
- Tax exemption with legal basis (Polish law, EU directive, or other)
44
+
- Margin scheme (travel agency, used goods, art works, collectibles/antiques)
45
+
46
+
**Other features:**
47
+
- Line item discounts
48
+
- Invoice periods (P_6_Od / P_6_Do)
49
+
- Correction/credit note references with KSeF numbers
50
+
- Payment details: means of payment, bank accounts, due dates, advance payments
51
+
- Additional description lines (DodatkowyOpis)
52
+
- Ordering data with order references and order lines (Zamowienie / WarunkiTransakcji)
53
+
- Rounding adjustments to reconcile KSeF and GOBL totals
54
+
- Gross pricing (P_9B) support in KSeF → GOBL direction
55
+
- Credit notes with before/after correction lines (StanPrzed)
56
+
- Prepayment invoices without line items (bypass mode with totals from tax summaries)
57
+
58
+
## CLI
59
+
60
+
The `gobl.ksef` CLI provides two commands:
61
+
62
+
-**`convert`** - Convert a GOBL JSON envelope into a FA_VAT XML document:
63
+
```bash
64
+
gobl.ksef convert input.json output.xml
65
+
```
66
+
67
+
-**`send`** - Convert and send a GOBL JSON envelope to the KSeF API:
68
+
```bash
69
+
gobl.ksef send input.json [nip] [token] [keyPath]
70
+
```
29
71
30
72
## Testing
31
73
@@ -80,40 +122,37 @@ FA_VAT is the Polish electronic invoice format. The format uses XML.
80
122
81
123
## Parsing (KSeF → GOBL)
82
124
83
-
The parsing functionality converts KSeF FA_VAT XML documents back into GOBL format. The current implementation includes:
125
+
The parsing functionality converts KSeF FA_VAT XML documents back into GOBL format. The implementation includes:
84
126
85
127
-**Party conversion**: Converts seller (Podmiot1), buyer (Podmiot2), and third parties (Podmiot3) to GOBL parties
86
-
-**Invoice data**: Parses invoice metadata including codes, dates, and currency
87
-
-**Line items**: Converts FA_VAT line items to GOBL invoice lines
88
-
-**Payment terms**: Extracts payment information and terms
89
-
-**Rounding adjustments**: Handles rounding differences to ensure totals match
90
-
-**Round-trip validation**: All conversions are validated through round-trip tests (GOBL → KSeF → GOBL)
91
-
92
-
**Note**: The parsing is functional but may not handle all edge cases. Some complex scenarios from the tax agency might require special handling, particularly invoices without line items, which would need synthetic lines created.
128
+
-**Invoice data**: Parses invoice metadata including type, codes, dates, currency, and annotations
129
+
-**Line items**: Converts FA_VAT line items (FaWiersz) to GOBL invoice lines, including discounts and tax combos
130
+
-**Credit notes**: Handles line inversion for correction invoices, including before/after correction lines (StanPrzed)
131
+
-**Gross pricing**: Supports invoices using gross unit prices (P_9B) by setting `PricesInclude = VAT`
132
+
-**Ordering data**: Maps Zamowienie (order) and WarunkiTransakcji (transaction conditions) to GOBL ordering purchases
133
+
-**Payment details**: Extracts payment means, bank accounts, due dates, and advance payments
134
+
-**Prepayment invoices**: Handles advance invoices without line items (ZAL/KOR_ZAL) using bypass mode with totals from tax summary fields
135
+
-**Rounding adjustments**: Handles rounding differences between KSeF and GOBL calculation methods
136
+
-**Round-trip validation**: All GOBL → KSeF conversions are validated through round-trip tests (GOBL → KSeF → GOBL)
93
137
94
138
## KSeF API
95
139
96
-
KSeF is the Polish system for submitting electronic invoices to the Polish authorities.
140
+
KSeF is the Polish system for submitting electronic invoices to the Polish authorities. The system uses API version 2.0, which introduced JWT-based authentication, mandatory invoice encryption, and a unified session model.
97
141
98
142
Useful links:
99
143
100
144
-[National e-Invoice System](https://ksef.mf.gov.pl/) - for details on system in general (English translation available - language picker is in the top right corner)
101
-
-[KSeF Test Zone](https://ksef-test.mf.gov.pl/) - as above, but for testing
102
-
-[API documentation](https://ksef-test.mf.gov.pl/docs/v2/index.html) for the test environment (in Polish)
103
-
104
-
KSeF provide three environments:
105
-
106
-
1.[Test Environment](https://ksef-test.mf.gov.pl/) for application development with fictitious data.
107
-
2.[Pre-production "demo"](https://ksef-demo.mf.gov.pl/) area with production data, but not officially declared.
|**Demo** (Pre-production) | Matches production configuration, for final validation |[api-demo.ksef.mf.gov.pl](https://api-demo.ksef.mf.gov.pl/docs/v2)|
153
+
|**Production**| Full legal validity, production data |[api.ksef.mf.gov.pl](https://api.ksef.mf.gov.pl/docs/v2)|
113
154
114
-
1. Batches ([test openapi 'batch' spec](https://ksef-test.mf.gov.pl/openapi/gtw/svc/api/KSeF-batch.yaml)) - for sending multiple documents at the same time.
115
-
2. Common ([test openapi 'common' spec](https://ksef-test.mf.gov.pl/openapi/gtw/svc/api/KSeF-common.yaml)) - general operations that don't require authentication.
116
-
3. Interactive ([test openapi 'online' spec](https://ksef-test.mf.gov.pl/openapi/gtw/svc/api/KSeF-online.yaml)) - sending a single document in each request.
155
+
The OpenAPI specification is available at each environment's `/docs/v2/openapi.json` endpoint.
|`Podmiot2>JST`|`JST`|`2`| Jednostka Samorządu Terytorialnego = local government unit, special case where the buyer is a local government unit |
15
-
|`Podmiot2>GV`|`GV`|`2`| Grupa VAT = VAT group, special case |
16
-
|`Fa>P_16`|`CashAccounting`|`2`||
17
-
|`Fa>P_18`|`ReverseCharge`|`2`||
18
-
|`Fa>P_18A`|`SplitPaymentMechanism`|`2`||
19
-
|`Fa>Adnotacje>Zwolnienie>P_19N`|`NoTaxExemptGoods`|`1`| For tax exempt goods, set `P_19` to 1, otherwise set `P_19N` to 1 |
13
+
|`SystemInfo`|`SystemInfo`|`Invopop`||
20
14
|`Fa>NoweSrodkiTransportu>P_22N`|`NoNewTransportIntraCommunitySupply`|`1`| For new transport intra-community supply, set `P_22` to 1 (rare special case), otherwise set `P_22N` to 1 |
21
15
|`Fa>P_23`|`SimplifiedProcedureBySecondTaxpayer`|`2`| For simplified procedure by second taxpayer (for three-party transactions inside the European Union), set `P_23` to 1, otherwise set `P_23` to 2 |
22
-
|`Fa>PMarzy>P_PMarzyN`|`NoMarginProcedures`|`1`| For margin procedure (applies to specific types of goods and services), set `P_PMarzy` to 1, otherwise set `P_PMarzyN` to 1 |
23
16
|`Fa>Platnosc>RachunekBankowyFaktora`|`FactorBankAccounts`|`[]`| Bank account of the factor (third party) |
24
17
25
18
## Not mapped
@@ -67,8 +60,7 @@ The following fields are now present in the structs but are not currently being
67
60
### Invoice (Fa)
68
61
| XML field | Struct field | Notes |
69
62
| --------- | ------------ | ----- |
70
-
|`Fa>P1_M`|`Issue Place`||
71
-
|`Fa>P_6`|`Completion date`| The date of delivery or completion of the delivery of goods or services or the date of receipt of payment, referred to in Art. 106b sec. 1(4) of the Act, if such date is specified and differs from the date of issue of the invoice.|
63
+
|`Fa>P_6`|`CompletionDate`| The date of delivery or completion of the delivery of goods or services or the date of receipt of payment, referred to in Art. 106b sec. 1(4) of the Act, if such date is specified and differs from the date of issue of the invoice.|
**Note**: `Fa>WarunkiTransakcji>Zamowienia` (order references) is now mapped bidirectionally via `Ordering.Purchases`. The first order reference date and number are converted. Other WarunkiTransakcji fields remain unmapped.
106
+
115
107
### Transport - COMPLETE STRUCTURE NOT MAPPED
116
108
| XML field | Struct field | Notes |
117
109
| --------- | ------------ | ----- |
@@ -130,13 +122,6 @@ The following fields are now present in the structs but are not currently being
|`Fa>P_1M`|`IssuePlace`| issue place - not required in schema |
179
+
|`Fa>P_14_1W`|`StandardRateTaxConvertedToPln`| for foreign currency invoices |
180
+
|`Fa>P_14_2W`|`ReducedRateTaxConvertedToPln`| for foreign currency invoices |
181
+
|`Fa>P_14_3W`|`SuperReducedRateTaxConvertedToPln`| for foreign currency invoices |
207
182
|`Fa>FP`|`FP`| indicates a case where an invoice is issued in addition to a regular receipt - not required in schema |
208
-
|`Fa>FaWiersz>StanPrzed`|`BeforeCorrectionMarker`| in a correction invoice, indicates that the line describes the state before the correction |
209
-
|`Fa>P_13_11`|`MarginNetSale`|
210
-
| `Fa>FaWiersz>GTU` | `SpecialGoodsCode` | Code identifying certain classes of goods and services (01 = alcoholic beverages, 02 = vehicle fuels...), values GTU_01 to GTU_13
211
-
|`Fa>P_6_Od`| Start of the invoice period |
212
-
|`Fa>P_6_Do`| End of the invoice period |
213
-
|`Fa>P_13_6_1`|`ZeroTaxExceptIntraCommunityNetSale`| Tax-exempt sale amount other than intra-EU supply and export |
214
-
|`Fa>P_13_6_2`|`IntraCommunityNetSale`| Intra-EU supply, tax-exempt sale amount |
215
-
|`Fa>P_13_6_3`|`ExportNetSale`| Export tax-exempt sale amount |
183
+
|`Fa>FaWiersz>StanPrzed`|`BeforeCorrectionMarker`| in a correction invoice, indicates that the line describes the state before the correction. Used during KSeF → GOBL parsing but not set during GOBL → KSeF building. |
184
+
|`Fa>FaWiersz>GTU`|`SpecialGoodsCode`| Code identifying certain classes of goods and services (01 = alcoholic beverages, 02 = vehicle fuels...), values GTU_01 to GTU_13 |
216
185
217
-
## Other cases
186
+
## Other cases
218
187
219
-
-`P_12`in our code always contains a number, but in the examples 22 and 23 the field contains text `0 WDT` and`0 EX` respectively.
188
+
-`P_12`now handles both numeric rates (e.g. `23`, `8`) and text values (`0 WDT`, `0 EX`, `zw`, `np I`, `np II`, `oo`,`0 KR`) for zero-rated, exempt, and special tax categories.
0 commit comments