invoiceninja / invoiceninja

A source-available invoice, quote, project and time-tracking app built with Laravel
https://invoiceninja.com
Other
8.11k stars 2.26k forks source link

[Bug] Tax free not working on E-Invoice #9773

Closed arnebr closed 2 days ago

arnebr commented 2 months ago

Setup

Interface

Checklist

Describe the bug

When you have a org that is tax exempt so has 0% Tax. The $invoicing_data->getItemTotalTaxes() is empty

Steps To Reproduce

Enable E-Invoice, set Tax in Company to 0 and try to Download file. It throws 500 Server Error

Expected Behavior

XML should be downloadable

Additional context

Screenshots

Logs

Undefined array key 0 {"userId":1,"exception":"[object] (ErrorException(code: 0): Undefined array key 0 at /var/www/vhosts/invoiceninja/vendor/horstoeko/zugferd/src/ZugferdDocumentBuilder.php:274)
[stacktrace]
#0 /var/www/vhosts/invoiceninja/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(256): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError()
#1 /var/www/vhosts/invoiceninja/vendor/horstoeko/zugferd/src/ZugferdDocumentBuilder.php(274): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->Illuminate\\Foundation\\Bootstrap\\{closure}()
#2 /var/www/vhosts/invoiceninja/app/Services/EDocument/Standards/ZugferdEDokument.php(232): horstoeko\\zugferd\\ZugferdDocumentBuilder->setDocumentSummation()
turbo124 commented 1 month ago

@arnebr is this still present in v5.10.11?

arnebr commented 1 month ago

Checked with v5.10.16-C161 and it worked :)

niklas-stegmann commented 2 weeks ago

@turbo124 I still get this error (tested in v5.10.16 and v5.10.26) when this setting is enabled in the invoice: image

If the option is deactivated, the generation works without any problems.

[2024-08-25 12:32:08] production.ERROR: Undefined array key 0 {"userId":1,"exception":"[object] (ErrorException(code: 0): Undefined array key 0 at /var/www/app/vendor/horstoeko/zugferd/src/ZugferdDocumentBuilder.php:274)
[stacktrace]
#0 /var/www/app/vendor/laravel/framework/src/Illuminate/Foundation/Bootstrap/HandleExceptions.php(256): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->handleError(2, 'Undefined array...', '/var/www/app/ve...', 274)
#1 /var/www/app/vendor/horstoeko/zugferd/src/ZugferdDocumentBuilder.php(274): Illuminate\\Foundation\\Bootstrap\\HandleExceptions->Illuminate\\Foundation\\Bootstrap\\{closure}(2, 'Undefined array...', '/var/www/app/ve...', 274)
#2 /var/www/app/app/Services/EDocument/Standards/ZugferdEDokument.php(232): horstoeko\\zugferd\\ZugferdDocumentBuilder->setDocumentSummation(50.0, 50.0, 50.0, 0.0, 0.0, 50.0, Array, 0.0, 0.0)
#3 /var/www/app/app/Jobs/EDocument/CreateEDocument.php(85): App\\Services\\EDocument\\Standards\\ZugferdEDokument->run()
#4 /var/www/app/app/Services/Invoice/InvoiceService.php(209): App\\Jobs\\EDocument\\CreateEDocument->handle()
#5 /var/www/app/app/Http/Controllers/InvoiceController.php(886): App\\Services\\Invoice\\InvoiceService->getEInvoice(Object(App\\Models\\ClientContact))
#6 /var/www/app/vendor/laravel/framework/src/Illuminate/Routing/Controller.php(54): App\\Http\\Controllers\\InvoiceController->downloadEInvoice('LzHhG4cpkZ1vnMz...')
#7 /var/www/app/vendor/laravel/framework/src/Illuminate/Routing/ControllerDispatcher.php(43): Illuminate\\Routing\\Controller->callAction('downloadEInvoic...', Array)
#8 /var/www/app/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Tracing/Routing/TracingControllerDispatcherTracing.php(21): Illuminate\\Routing\\ControllerDispatcher->dispatch(Object(Illuminate\\Routing\\Route), Object(App\\Http\\Controllers\\InvoiceController), 'downloadEInvoic...')
#9 /var/www/app/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Tracing/Routing/TracingRoutingDispatcher.php(18): Sentry\\Laravel\\Tracing\\Routing\\TracingControllerDispatcherTracing->Sentry\\Laravel\\Tracing\\Routing\\{closure}()
#10 /var/www/app/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Tracing/Routing/TracingControllerDispatcherTracing.php(20): Sentry\\Laravel\\Tracing\\Routing\\TracingRoutingDispatcher->wrapRouteDispatch(Object(Closure), Object(Illuminate\\Routing\\Route))
#11 /var/www/app/vendor/laravel/framework/src/Illuminate/Routing/Route.php(260): Sentry\\Laravel\\Tracing\\Routing\\TracingControllerDispatcherTracing->dispatch(Object(Illuminate\\Routing\\Route), Object(App\\Http\\Controllers\\InvoiceController), 'downloadEInvoic...')
#12 /var/www/app/vendor/laravel/framework/src/Illuminate/Routing/Route.php(206): Illuminate\\Routing\\Route->runController()
#13 /var/www/app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(808): Illuminate\\Routing\\Route->run()
#14 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(144): Illuminate\\Routing\\Router->Illuminate\\Routing\\{closure}(Object(Illuminate\\Http\\Request))
#15 /var/www/app/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(124): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#16 /var/www/app/vendor/laravel/framework/src/Illuminate/Routing/Middleware/ThrottleRequests.php(89): Illuminate\\Routing\\Middleware\\ThrottleRequests->handleRequestUsingNamedLimiter(Object(Illuminate\\Http\\Request), Object(Closure), 'api', Object(Closure))
#17 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Routing\\Middleware\\ThrottleRequests->handle(Object(Illuminate\\Http\\Request), Object(Closure), 'api')
#18 /var/www/app/app/Http/Middleware/QueryLogging.php(39): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#19 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): App\\Http\\Middleware\\QueryLogging->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#20 /var/www/app/vendor/laravel/framework/src/Illuminate/Routing/Middleware/SubstituteBindings.php(50): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#21 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Routing\\Middleware\\SubstituteBindings->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#22 /var/www/app/app/Http/Middleware/Locale.php(95): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#23 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): App\\Http\\Middleware\\Locale->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#24 /var/www/app/app/Http/Middleware/TokenAuth.php(102): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#25 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): App\\Http\\Middleware\\TokenAuth->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#26 /var/www/app/app/Http/Middleware/SetDb.php(40): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#27 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): App\\Http\\Middleware\\SetDb->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#28 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#29 /var/www/app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(807): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#30 /var/www/app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(786): Illuminate\\Routing\\Router->runRouteWithinStack(Object(Illuminate\\Routing\\Route), Object(Illuminate\\Http\\Request))
#31 /var/www/app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(750): Illuminate\\Routing\\Router->runRoute(Object(Illuminate\\Http\\Request), Object(Illuminate\\Routing\\Route))
#32 /var/www/app/vendor/laravel/framework/src/Illuminate/Routing/Router.php(739): Illuminate\\Routing\\Router->dispatchToRoute(Object(Illuminate\\Http\\Request))
#33 /var/www/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(201): Illuminate\\Routing\\Router->dispatch(Object(Illuminate\\Http\\Request))
#34 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(144): Illuminate\\Foundation\\Http\\Kernel->Illuminate\\Foundation\\Http\\{closure}(Object(Illuminate\\Http\\Request))
#35 /var/www/app/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Http/FlushEventsMiddleware.php(13): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#36 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Sentry\\Laravel\\Http\\FlushEventsMiddleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#37 /var/www/app/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Http/SetRequestIpMiddleware.php(45): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#38 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Sentry\\Laravel\\Http\\SetRequestIpMiddleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#39 /var/www/app/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Http/SetRequestMiddleware.php(31): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#40 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Sentry\\Laravel\\Http\\SetRequestMiddleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#41 /var/www/app/vendor/livewire/livewire/src/Features/SupportDisablingBackButtonCache/DisableBackButtonCacheMiddleware.php(19): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#42 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Livewire\\Features\\SupportDisablingBackButtonCache\\DisableBackButtonCacheMiddleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#43 /var/www/app/app/Http/Middleware/Cors.php(24): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#44 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): App\\Http\\Middleware\\Cors->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#45 /var/www/app/vendor/laravel/framework/src/Illuminate/Http/Middleware/TrustProxies.php(57): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#46 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Http\\Middleware\\TrustProxies->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#47 /var/www/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#48 /var/www/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/ConvertEmptyStringsToNull.php(31): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#49 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Foundation\\Http\\Middleware\\ConvertEmptyStringsToNull->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#50 /var/www/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TransformsRequest.php(21): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#51 /var/www/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/TrimStrings.php(51): Illuminate\\Foundation\\Http\\Middleware\\TransformsRequest->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#52 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Foundation\\Http\\Middleware\\TrimStrings->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#53 /var/www/app/vendor/laravel/framework/src/Illuminate/Http/Middleware/ValidatePostSize.php(27): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#54 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Http\\Middleware\\ValidatePostSize->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#55 /var/www/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Middleware/PreventRequestsDuringMaintenance.php(110): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#56 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Illuminate\\Foundation\\Http\\Middleware\\PreventRequestsDuringMaintenance->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#57 /var/www/app/vendor/sentry/sentry-laravel/src/Sentry/Laravel/Tracing/Middleware.php(86): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#58 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(183): Sentry\\Laravel\\Tracing\\Middleware->handle(Object(Illuminate\\Http\\Request), Object(Closure))
#59 /var/www/app/vendor/laravel/framework/src/Illuminate/Pipeline/Pipeline.php(119): Illuminate\\Pipeline\\Pipeline->Illuminate\\Pipeline\\{closure}(Object(Illuminate\\Http\\Request))
#60 /var/www/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(176): Illuminate\\Pipeline\\Pipeline->then(Object(Closure))
#61 /var/www/app/vendor/laravel/framework/src/Illuminate/Foundation/Http/Kernel.php(145): Illuminate\\Foundation\\Http\\Kernel->sendRequestThroughRouter(Object(Illuminate\\Http\\Request))
#62 /var/www/app/public/index.php(56): Illuminate\\Foundation\\Http\\Kernel->handle(Object(Illuminate\\Http\\Request))
#63 {main}
"} 
turbo124 commented 2 weeks ago

Just to confirm. Do you have any taxes on the invoice? Or is this with a 0% tax?

niklas-stegmann commented 2 weeks ago

No, I don't have any taxes on my invoice.

turbo124 commented 2 weeks ago

@LarsK1 I believe we are expecting some form of tax to be here?

LarsK1 commented 2 weeks ago

@turbo124 that might really be the issue. XRechnung itself doesn't need taxes to be fully valid

@niklas-stegmann could you please try to generate an invoice with VAT, and report back if that works.

niklas-stegmann commented 2 weeks ago

@LarsK1 yes, it works with VAT.

LarsK1 commented 2 weeks ago

Ah I see, may I ask, what's the reason for no VAT? Are you selling exempted items or is your business exempted (like Kleinunternehmerreglung)?

turbo124 commented 2 weeks ago

under $10k no VAT is required to be charged. However. I believe the document must still include this data in in particular

<cac:TaxCategory>
    <cbc:ID>S</cbc:ID>
    <cbc:Percent>0</cbc:Percent>
    <cbc:TaxExemptionReasonCode>VATNOTREG</cbc:TaxExemptionReasonCode>
    <cbc:TaxExemptionReason>Seller not VAT registered</cbc:TaxExemptionReason>
    <cac:TaxScheme>
        <cbc:ID>VAT</cbc:ID>
    </cac:TaxScheme>
</cac:TaxCategory>
niklas-stegmann commented 2 weeks ago

@LarsK1 My company is under 10K € per year, therefore it falls under the “Kleinunternehmerregelung”

LarsK1 commented 2 weeks ago

@turbo124 we definitely need to find a section for this one. This is a role, that is present in all European countries. If a certain amount is not exceeded, companies can opt in, to not charge any VAT. We should therefore add an toggle for exempted companies and then adjust the einvoice accordingly

turbo124 commented 2 weeks ago

@LarsK1 I think the best option here would be to place the VATNOTREG block in the document if total_taxes == 0

LarsK1 commented 2 weeks ago

@turbo124 that's not an solution for all cases, since there are companies (like mine), which is vat registered and sells vat-free items. Therefore this would be wrong. We really do need an option the user needs to select specifically.

turbo124 commented 2 weeks ago

@LarsK1

There should be a differentiation between NO taxes on the invoice, and Zero taxes on the invoice.

I think that if NO taxes are present, then it would be safe to assume the seller is not vat registered and under threshold.

Zero rated taxes are a different beast all together.

LarsK1 commented 2 weeks ago

@turbo124 I'll add an PR for this on the weekend.

LarsK1 commented 3 days ago

See https://github.com/invoiceninja/invoiceninja/pull/9986

arnebr commented 2 days ago

Close this issue, #9986