Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Gross invoice example? #47

Open
hschneider opened this issue Nov 8, 2024 · 6 comments
Open

Gross invoice example? #47

hschneider opened this issue Nov 8, 2024 · 6 comments

Comments

@hschneider
Copy link

At first thanks for this great package.

Is it possible that someone translates the net invoice example to a gros invoice?
A simple invoice with 19% VAT, no tax exemption.

Otherwise its very hard to determine where to enter net values.

I am sure, this will prevent tons of validation errors and questions:

note = IncludedNote()
note.content.add("Test Node 1")
doc.header.notes.add(note)

doc.trade.agreement.seller.name = "Lieferant GmbH"
doc.trade.settlement.payee.name = "Kunde GmbH"

doc.trade.agreement.buyer.name = "Kunde GmbH"
doc.trade.settlement.invoicee.name = "Kunde GmbH"

doc.trade.settlement.currency_code = "EUR"
doc.trade.settlement.payment_means.type_code = "ZZZ"

doc.trade.agreement.seller.address.country_id = "DE"
doc.trade.agreement.seller.address.country_subdivision = "Bayern"

doc.trade.agreement.seller_order.issue_date_time = datetime.now(timezone.utc)
doc.trade.agreement.buyer_order.issue_date_time = datetime.now(timezone.utc)
doc.trade.settlement.advance_payment.received_date = datetime.now(timezone.utc)
doc.trade.agreement.customer_order.issue_date_time = datetime.now(timezone.utc)

li = LineItem()
li.document.line_id = "1"
li.product.name = "Rainbow"
li.agreement.gross.amount = Decimal("999.00")
li.agreement.gross.basis_quantity = (Decimal("1.0000"), "C62")  # C62 == pieces
li.agreement.net.amount = Decimal("999.00")
li.agreement.net.basis_quantity = (Decimal("999.00"), "EUR")
li.delivery.billed_quantity = (Decimal("1.0000"), "C62")  # C62 == pieces
li.settlement.trade_tax.type_code = "VAT"
li.settlement.trade_tax.category_code = "E"
li.settlement.trade_tax.rate_applicable_percent = Decimal("0.00")
li.settlement.monetary_summation.total_amount = Decimal("999.00")
doc.trade.items.add(li)

trade_tax = ApplicableTradeTax()
trade_tax.calculated_amount = Decimal("0.00")
trade_tax.basis_amount = Decimal("999.00")
trade_tax.type_code = "VAT"
trade_tax.category_code = "AE"
trade_tax.exemption_reason_code = 'VATEX-EU-AE'
trade_tax.rate_applicable_percent = Decimal("0.00")
doc.trade.settlement.trade_tax.add(trade_tax)

doc.trade.settlement.monetary_summation.line_total = Decimal("999.00")
doc.trade.settlement.monetary_summation.charge_total = Decimal("0.00")
doc.trade.settlement.monetary_summation.allowance_total = Decimal("0.00")
doc.trade.settlement.monetary_summation.tax_basis_total = Decimal("999.00")
doc.trade.settlement.monetary_summation.tax_total = Decimal("0.00")
doc.trade.settlement.monetary_summation.grand_total = Decimal("999.00")
doc.trade.settlement.monetary_summation.due_amount = Decimal("999.00")

THANKS!

@hschneider
Copy link
Author

hschneider commented Nov 8, 2024

To be more specific, I tried to setup this invoice:

1 x test procuct 59 EUR net.
Grand total: 70,21 EUR with 19% VAT inclusive.

This is the code:

 li = LineItem()
        li.document.line_id = "1"
        li.product.name = "TEST"
        li.agreement.gross.amount = Decimal("59.00")
        li.agreement.gross.basis_quantity = (Decimal("1.00"), "H87")  # C62 == pieces
        li.agreement.net.amount = Decimal("59.00")
        li.agreement.net.basis_quantity = (Decimal("59.00"), "EUR")
        li.delivery.billed_quantity = (Decimal("1.00"), "H87")  # C62 == pieces
        li.settlement.trade_tax.type_code = "VAT"
        li.settlement.trade_tax.category_code = "S"
        li.settlement.trade_tax.rate_applicable_percent = Decimal("19.00")
        li.settlement.monetary_summation.total_amount = Decimal("59.00")
        self.docZF.trade.items.add(li)

        trade_tax = ApplicableTradeTax()
        trade_tax.calculated_amount = Decimal("11.21")
        trade_tax.basis_amount = Decimal("59.00")
        trade_tax.type_code = "VAT"
        trade_tax.category_code = "S"
        #trade_tax.exemption_reason_code = 'VATEX-EU-AE'
        trade_tax.rate_applicable_percent = Decimal("19.00")
        self.docZF.trade.settlement.trade_tax.add(trade_tax)

        self.docZF.trade.settlement.monetary_summation.line_total = Decimal("59.00")
        self.docZF.trade.settlement.monetary_summation.charge_total = Decimal("0.00")       # Gebühren
        self.docZF.trade.settlement.monetary_summation.allowance_total = Decimal("0.00")    # Zuschläge
        self.docZF.trade.settlement.monetary_summation.tax_basis_total = Decimal("59.00")
        self.docZF.trade.settlement.monetary_summation.tax_total = Decimal("11.21")
        self.docZF.trade.settlement.monetary_summation.grand_total = Decimal("70.21")
        self.docZF.trade.settlement.monetary_summation.due_amount = Decimal("70.21")

Verifying the PDF, throws this error:

16:45:28.353 [main] INFO  o.m.validator.XMLValidator - FailedAssert 
16:45:28.360 [main] ERROR o.m.validator.ZUGFeRDValidator - Error 4: 
	Invoice total amount with VAT (BT-112) = Invoice total amount without VAT (BT-109) + Invoice total VAT amount (BT-110). from /xslt/ZF_221/FACTUR-X_EXTENDED.xslt)

Valitool says:

[VD-Valitool-59]-Rechenfehler (ggf. wegen Rundungsfehler): MonetarySummation -> GrandTotalAmount = TaxBasisTotalAmount + TaxTotalAmount 59.00 + 0.00 = 59.00 Dies entspricht nicht dem angebenen Wert 70.21

So TaxTotalAmount is read as 0.00.
In the code it is set to .settlement.monetary_summation.tax_total = Decimal("11.21")

Did I miss something or did I hit some bug?

@raphaelm
Copy link
Member

raphaelm commented Nov 8, 2024

So the problem is that you are trying to do the impossible.

ZUGFeRD 2 is modeled after EN16931. The German version of that norm is freely available at DIN…

… and it only allows net invoices. Gross invoices are impossible to be EN16931 compliant.

Yes, this sucks a lot. Someone has not thought this entire thing through and it has already given me sleepless nights.

ZUGFeRD 2.3 EXTENDED introduces some flexibility on the rounding check, which is however in violation of current EN16931.

@hschneider
Copy link
Author

Ouch! OK - thanks for the info.

@0xD0M1M0
Copy link

0xD0M1M0 commented Nov 24, 2024

To fix "Invoice total amount with VAT (BT-112) = Invoice total amount without VAT (BT-109) + Invoice total VAT amount (BT-110)" add a currencyID to taxTotalAmount:

<ram:TaxTotalAmount currencyID="EUR">VALUE</ram:TaxTotalAmount>

Reference: https://xeinkauf.de/app/uploads/2024/07/302-XRechnung-2024-06-20.pdf
Page 66 / BR-53:

Wenn ein Währungscode für die Umsatzsteuerabrechnung "VAT accounting currency code" (BT-6) angegeben wurde, muss der Umsatzsteuergesamtbetrag in der Abrechnungswährung "Invoice total VAT amount in accounting currency" (BT-111) angegeben werden.

@raphaelm
Copy link
Member

That's not the issue at hand

@0xD0M1M0
Copy link

Sorry. I just read the error message and saw a solution.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants