From cd3372fb12498c0ec179427c74cb34bf74564ff9 Mon Sep 17 00:00:00 2001 From: David Bomba Date: Mon, 11 Nov 2024 14:46:49 +1100 Subject: [PATCH] Scenario tests --- app/Http/Controllers/EInvoiceController.php | 2 +- .../Requests/Company/UpdateCompanyRequest.php | 9 +- .../EInvoice/Peppol/StoreEntityRequest.php | 1 + .../EInvoice/UpdateEInvoiceConfiguration.php | 12 +++ app/Livewire/BillingPortalPurchase.php | 1 + .../EDocument/Gateway/Storecove/Storecove.php | 1 + .../Gateway/Storecove/StorecoveRouter.php | 5 +- lang/en/texts.php | 2 + .../Einvoice/Storecove/StorecoveTest.php | 98 ++++++++++++++++++- 9 files changed, 123 insertions(+), 8 deletions(-) diff --git a/app/Http/Controllers/EInvoiceController.php b/app/Http/Controllers/EInvoiceController.php index cdfba4f444..634a8475dc 100644 --- a/app/Http/Controllers/EInvoiceController.php +++ b/app/Http/Controllers/EInvoiceController.php @@ -94,7 +94,7 @@ class EInvoiceController extends BaseController $iban_id = new ID(); $iban_id->value = $payment_means['iban']; $pfa->ID = $iban_id; - $pfa->Name = $payment_means['payer_bank_account']; + $pfa->Name = $payment_means['account_holder']; $pfa->FinancialInstitutionBranch = $fib; $pm->PayeeFinancialAccount = $pfa; diff --git a/app/Http/Requests/Company/UpdateCompanyRequest.php b/app/Http/Requests/Company/UpdateCompanyRequest.php index 94c5dc1d91..44537fe2c6 100644 --- a/app/Http/Requests/Company/UpdateCompanyRequest.php +++ b/app/Http/Requests/Company/UpdateCompanyRequest.php @@ -61,6 +61,7 @@ class UpdateCompanyRequest extends Request 'SK' => '/^SK\d{10}$/', 'SI' => '/^SI\d{8}$/', 'SE' => '/^SE\d{12}$/', + 'DE:STNR' => '/^[0-9]{11}$/', //de steurnummer, ]; /** @@ -77,6 +78,10 @@ class UpdateCompanyRequest extends Request public function rules() { + + /** @var \App\Models\User $user */ + $user = auth()->user(); + $input = $this->all(); $rules = []; @@ -121,8 +126,8 @@ class UpdateCompanyRequest extends Request 'string', 'bail', 'sometimes', - Rule::requiredIf(function () { - return $this->input('settings.e_invoice_type') === 'PEPPOL'; + Rule::requiredIf(function () use ($user) { + return $this->input('settings.e_invoice_type') === 'PEPPOL' && $user->company()->settings->classification != 'individual'; }), function ($attribute, $value, $fail) { $country_code = $this->getCountryCode(); diff --git a/app/Http/Requests/EInvoice/Peppol/StoreEntityRequest.php b/app/Http/Requests/EInvoice/Peppol/StoreEntityRequest.php index 4cdd854c92..2879c7f80d 100644 --- a/app/Http/Requests/EInvoice/Peppol/StoreEntityRequest.php +++ b/app/Http/Requests/EInvoice/Peppol/StoreEntityRequest.php @@ -48,6 +48,7 @@ class StoreEntityRequest extends FormRequest 'SK' => '/^SK\d{10}$/', 'SI' => '/^SI\d{8}$/', 'SE' => '/^SE\d{12}$/', + 'DE:STNR' => '/^[0-9]{11}$/', //de steurnummer, ]; public function authorize(): bool diff --git a/app/Http/Requests/EInvoice/UpdateEInvoiceConfiguration.php b/app/Http/Requests/EInvoice/UpdateEInvoiceConfiguration.php index dd43fcd9c2..acff26b85e 100644 --- a/app/Http/Requests/EInvoice/UpdateEInvoiceConfiguration.php +++ b/app/Http/Requests/EInvoice/UpdateEInvoiceConfiguration.php @@ -77,6 +77,18 @@ class UpdateEInvoiceConfiguration extends Request return [...$rules, 'nullable']; }), + 'payment_means.*.account_holder' => Rule::forEach(function (string|null $value, string $attribute) { + $index = explode('.', $attribute)[1]; + $code = $this->input("payment_means.{$index}.code"); + $requirements = PaymentMeans::$payment_means_requirements_codes[$code] ?? []; + $rules = ['bail', 'sometimes', 'string', 'max:255']; + + if (in_array('account_holder', $requirements)) { + return [...$rules, 'required']; + } + + return [...$rules, 'nullable']; + }), 'payment_means.*.information' => ['bail', 'sometimes', 'nullable', 'string'], 'payment_means.*.card_type' => Rule::forEach(function (string|null $value, string $attribute) { $index = explode('.', $attribute)[1]; diff --git a/app/Livewire/BillingPortalPurchase.php b/app/Livewire/BillingPortalPurchase.php index f50fc723f9..5fdbb627c7 100644 --- a/app/Livewire/BillingPortalPurchase.php +++ b/app/Livewire/BillingPortalPurchase.php @@ -484,6 +484,7 @@ class BillingPortalPurchase extends Component 'invoice_id' => $this->invoice->hashed_id, 'context' => $context, 'campaign' => $this->campaign, + 'request_data' => $this->request_data, ], now()->addMinutes(60)); $this->dispatch('beforePaymentEventsCompleted'); diff --git a/app/Services/EDocument/Gateway/Storecove/Storecove.php b/app/Services/EDocument/Gateway/Storecove/Storecove.php index 820ada28f1..e1eed20327 100644 --- a/app/Services/EDocument/Gateway/Storecove/Storecove.php +++ b/app/Services/EDocument/Gateway/Storecove/Storecove.php @@ -381,6 +381,7 @@ class Storecove return $data; } + nlog($r->body()); return $r; } diff --git a/app/Services/EDocument/Gateway/Storecove/StorecoveRouter.php b/app/Services/EDocument/Gateway/Storecove/StorecoveRouter.php index be853fc1a3..6d740bcd38 100644 --- a/app/Services/EDocument/Gateway/Storecove/StorecoveRouter.php +++ b/app/Services/EDocument/Gateway/Storecove/StorecoveRouter.php @@ -137,9 +137,8 @@ class StorecoveRouter } - //DE we can route via Steurnummer - if($this->invoice && $country = "DE" && $classification == 'individual'){ - // if($this->invoice && $country = "DE" && $classification == 'individual' && strlen($this->invoice->client->id_number ?? '') > 4){ + //DE we can route via Steurnummer? double check with storecove @blocked + if($country = "DE" && $classification == 'individual'){ return 'DE:STNR'; } diff --git a/lang/en/texts.php b/lang/en/texts.php index 18aa626eb9..d8aaa5b66d 100644 --- a/lang/en/texts.php +++ b/lang/en/texts.php @@ -5458,6 +5458,8 @@ $lang = array( 'peppol_routing_problem' => 'Routing problem. No recipient/destination found.', 'peppol_sending_failed' => 'Technical delivery problem. Retry not possible', 'peppol_cleared_for_sending' => 'Cleared by tax authority, sending to receiver', + 'account_holder' => 'Account Name', + 'account_holder_help' => 'The name of the account', ); return $lang; diff --git a/tests/Integration/Einvoice/Storecove/StorecoveTest.php b/tests/Integration/Einvoice/Storecove/StorecoveTest.php index 3cd6bbd84f..95d0eec35e 100644 --- a/tests/Integration/Einvoice/Storecove/StorecoveTest.php +++ b/tests/Integration/Einvoice/Storecove/StorecoveTest.php @@ -74,6 +74,8 @@ class StorecoveTest extends TestCase $settings = CompanySettings::defaults(); $settings->vat_number = $params['company_vat'] ?? 'DE123456789'; + $settings->id_number = $params['company_id_number'] ?? ''; + $settings->classification = $params['company_classification'] ?? 'business'; $settings->country_id = Country::where('iso_3166_2', 'DE')->first()->id; $settings->email = $this->faker->safeEmail(); $settings->currency_id = '3'; @@ -170,8 +172,101 @@ class StorecoveTest extends TestCase return compact('company', 'client', 'invoice'); } + public function testDEtoFRB2BReverseCharge() + { + + $this->routing_id = 290868; + + $scenario = [ + 'company_vat' => 'DE923356489', + 'company_id_number' => '01234567890', + 'company_country' => 'DE', + 'company_classification' => 'business', + 'client_country' => 'FR', + 'client_vat' => 'FRAA123456789', + 'client_id_number' => '', + 'classification' => 'business', + 'has_valid_vat' => false, + 'over_threshold' => false, + 'legal_entity_id' => 290868, + 'is_tax_exempt' => true, + ]; + + $data = $this->setupTestData($scenario); + + $invoice = $data['invoice']; + + $line_items = $invoice->line_items; + + foreach($line_items as &$item) + { + $item->tax_id = (string)\App\Models\Product::PRODUCT_TYPE_REVERSE_TAX; + } + unset($item); + + $invoice->line_items = array_values($line_items); + + $invoice = $invoice->calc()->getInvoice(); + + $this->assertEquals(floatval(0), floatval($invoice->total_taxes)); + } + + public function testDEIToDEGNoTaxes() + { + + $this->routing_id = 290868; + + $scenario = [ + 'company_vat' => '', + 'company_id_number' => '01234567890', + 'company_country' => 'DE', + 'company_classification' => 'individual', + 'client_country' => 'DE', + 'client_vat' => '', + 'client_id_number' => '', + 'classification' => 'government', + 'has_valid_vat' => false, + 'over_threshold' => false, + 'legal_entity_id' => 290868, + 'is_tax_exempt' => true, + ]; + + $data = $this->setupTestData($scenario); + + $invoice = $data['invoice']; + $invoice = $invoice->calc()->getInvoice(); + + $this->assertEquals(floatval(0), floatval($invoice->total_taxes)); + } + + public function testDeNoVatNumberToDeVatNumber() + { + + $this->routing_id = 290868; + + $scenario = [ + 'company_vat' => '', + 'company_id_number' => '01234567890', + 'company_country' => 'DE', + 'company_classification' => 'individual', + 'client_country' => 'DE', + 'client_vat' => 'DE923356489', + 'client_id_number' => '', + 'classification' => 'business', + 'has_valid_vat' => true, + 'over_threshold' => false, + 'legal_entity_id' => 290868, + 'is_tax_exempt' => false, + ]; + + $data = $this->setupTestData($scenario); + + $invoice = $data['invoice']; + $invoice = $invoice->calc()->getInvoice(); + + $this->assertGreaterThan(0, $invoice->total_taxes); + } - public function testDeToFrClientTaxExemptSending() { $this->routing_id = 290868; @@ -209,7 +304,6 @@ class StorecoveTest extends TestCase $this->assertEquals(floatval(0), floatval($invoice->total_taxes)); $this->sendDocument($invoice); } - /** * PtestDeToDeClientTaxExemptSending