diff --git a/app/Services/EDocument/Gateway/Storecove/Storecove.php b/app/Services/EDocument/Gateway/Storecove/Storecove.php index 0ce0a8561372..397e8813ff2b 100644 --- a/app/Services/EDocument/Gateway/Storecove/Storecove.php +++ b/app/Services/EDocument/Gateway/Storecove/Storecove.php @@ -137,14 +137,14 @@ class Storecove { } - public function sendDocument($document) + public function sendDocument(string $document, int $routing_id, array $identifiers = []) { $payload = [ - "legalEntityId"=> 290868, + "legalEntityId" => $routing_id, "idempotencyGuid"=> \Illuminate\Support\Str::uuid(), "routing" => [ - "eIdentifiers" => [], + "eIdentifiers" => $identifiers, "emails" => ["david@invoiceninja.com"] ], "document"=> [ diff --git a/app/Services/EDocument/Standards/Peppol.php b/app/Services/EDocument/Standards/Peppol.php index ab86be75fc81..d6c6e8f538ee 100644 --- a/app/Services/EDocument/Standards/Peppol.php +++ b/app/Services/EDocument/Standards/Peppol.php @@ -254,6 +254,10 @@ class Peppol extends AbstractService { $this->p_invoice->ID = $this->invoice->number; $this->p_invoice->IssueDate = new \DateTime($this->invoice->date); + + if($this->invoice->due_date) + $this->p_invoice->DueDate = new \DateTime($this->invoice->due_date); + $this->p_invoice->InvoiceTypeCode = 380; // $this->p_invoice->AccountingSupplierParty = $this->getAccountingSupplierParty(); $this->p_invoice->AccountingCustomerParty = $this->getAccountingCustomerParty(); @@ -862,17 +866,24 @@ class Peppol extends AbstractService /** * ES * - * @Pending - testing. + * @Pending + * + * ES:DIRE - routing identifier + * + * testing. //293098 * * @return self */ private function ES(): self { - // For B2B, provide an ES:DIRE routing identifier and an ES:VAT tax identifier. - // both sender and receiver must be an ES company; - // you must have a "credit_transfer" PaymentMean; - // the "dueDate" property is mandatory. + if(!isset($this->invoice->due_date)) + $this->p_invoice->DueDate = new \DateTime($this->invoice->date); + + if($this->invoice->client->classification == 'business' && $this->invoice->company->getSetting('classification') == 'business') { + //must have a paymentmeans as credit_transfer + $this->setPaymentMeans(true); + } // For B2G, provide three ES:FACE identifiers in the routing object, // as well as the ES:VAT tax identifier in the accountingCustomerParty.publicIdentifiers. diff --git a/tests/Integration/Einvoice/Storecove/StorecoveTest.php b/tests/Integration/Einvoice/Storecove/StorecoveTest.php index 57882e1feb46..d227c6848254 100644 --- a/tests/Integration/Einvoice/Storecove/StorecoveTest.php +++ b/tests/Integration/Einvoice/Storecove/StorecoveTest.php @@ -28,7 +28,7 @@ class StorecoveTest extends TestCase use MockAccountData; use DatabaseTransactions; - private string $routing_id = ''; + private int $routing_id; protected function setUp(): void { @@ -352,7 +352,7 @@ $x = ' $sc = new \App\Services\EDocument\Gateway\Storecove\Storecove(); - $sc->sendDocument($x); + $sc->sendDocument($x, 290868); } */ @@ -398,10 +398,117 @@ $x = ' } + private function createESData() + { + $this->routing_id = 293098; + + $settings = CompanySettings::defaults(); + $settings->company_logo = 'https://pdf.invoicing.co/favicon-v2.png'; + $settings->website = 'www.invoiceninja.de'; + $settings->address1 = 'Calle Gran Vía, 28'; + $settings->address2 = 'Edificio Telefónica'; + $settings->city = 'Madrid'; + $settings->state = 'Madrid'; + $settings->postal_code = '28013'; + $settings->phone = '030 1234567'; + $settings->email = $this->faker->unique()->safeEmail(); + $settings->country_id = '724'; // Germany's ISO country code + $settings->vat_number = 'ESB16645678'; + $settings->id_number = 'HRB 12345'; + $settings->use_credits_payment = 'always'; + $settings->timezone_id = '1'; // CET (Central European Time) + $settings->entity_send_time = 0; + $settings->e_invoice_type = 'PEPPOL'; + $settings->currency_id = '3'; + $settings->classification = 'business'; + + $company = Company::factory()->create([ + 'account_id' => $this->account->id, + 'settings' => $settings, + ]); + + $this->user->companies()->attach($company->id, [ + 'account_id' => $this->account->id, + 'is_owner' => true, + 'is_admin' => 1, + 'is_locked' => 0, + 'permissions' => '', + 'notifications' => CompanySettings::notificationAdminDefaults(), + 'settings' => null, + ]); + + Client::unguard(); + + $c = + Client::create([ + 'company_id' => $company->id, + 'user_id' => $this->user->id, + 'name' => 'Empresa Ejemplo S.A.', + 'website' => 'https://www.empresa-ejemplo.es', + 'private_notes' => 'Estas son notas privadas para el cliente de prueba.', + 'balance' => 0, + 'paid_to_date' => 0, + 'vat_number' => 'ESB12345678', // Spanish VAT number with ES prefix + 'id_number' => 'B12345678', // Typical format for Spanish company registration numbers + 'custom_value1' => '2024-07-22 10:00:00', + 'custom_value2' => 'azul', // Spanish for blue + 'custom_value3' => 'palabraejemplo', // Spanish for sample word + 'custom_value4' => 'test@ejemplo.com', + 'address1' => 'Calle Ejemplo 123', + 'address2' => '2ª Planta, Oficina 45', + 'city' => 'Madrid', + 'state' => 'Madrid', + 'postal_code' => '28013', + 'country_id' => '724', // Spain + 'shipping_address1' => 'Calle Ejemplo 123', + 'shipping_address2' => '2ª Planta, Oficina 45', + 'shipping_city' => 'Madrid', + 'shipping_state' => 'Madrid', + 'shipping_postal_code' => '28013', + 'shipping_country_id' => '724', // Spain + 'settings' => ClientSettings::Defaults(), + 'client_hash' => \Illuminate\Support\Str::random(32), + 'routing_id' => '', + ]); + + $item = new InvoiceItem(); + $item->product_key = "Product Key"; + $item->notes = "Product Description"; + $item->cost = 10; + $item->quantity = 10; + $item->tax_rate1 = 21; + $item->tax_name1 = 'IVA'; + + $invoice = Invoice::factory()->create([ + 'company_id' => $company->id, + 'user_id' => $this->user->id, + 'client_id' => $c->id, + 'discount' => 0, + 'uses_inclusive_taxes' => false, + 'status_id' => 1, + 'tax_rate1' => 0, + 'tax_name1' => '', + 'tax_rate2' => 0, + 'tax_rate3' => 0, + 'tax_name2' => '', + 'tax_name3' => '', + 'line_items' => [$item], + 'number' => 'ES-'.rand(1000, 100000), + 'date' => now()->format('Y-m-d'), + 'due_date' => now()->addDays(14)->format('Y-m-d'), + ]); + + $invoice = $invoice->calc()->getInvoice(); + $invoice->service()->markSent()->save(); + + return $invoice; + + } + private function createDEData() { - $this->routing_id = '290868'; + $this->routing_id = 290868; $settings = CompanySettings::defaults(); $settings->company_logo = 'https://pdf.invoicing.co/favicon-v2.png'; @@ -495,7 +602,8 @@ $x = ' 'tax_name3' => '', 'line_items' => [$item], 'number' => 'DE-'.rand(1000, 100000), - 'date' => now()->format('Y-m-d') + 'date' => now()->format('Y-m-d'), + 'due_date' => now()->addDays(14)->format('Y-m-d'), ]); $invoice = $invoice->calc()->getInvoice(); @@ -506,6 +614,42 @@ $x = ' } + public function testEsRules() + { + + $invoice = $this->createESData(); + + $e_invoice = new \InvoiceNinja\EInvoice\Models\Peppol\Invoice(); + + $stub = json_decode('{"Invoice":{"Note":"Nooo","PaymentMeans":[{"ID":{"value":"afdasfasdfasdfas"},"PayeeFinancialAccount":{"Name":"PFA-NAME","ID":{"value":"DE89370400440532013000"},"AliasName":"PFA-Alias","AccountTypeCode":{"value":"CHECKING"},"AccountFormatCode":{"value":"IBAN"},"CurrencyCode":{"value":"EUR"},"FinancialInstitutionBranch":{"ID":{"value":"DEUTDEMMXXX"},"Name":"Deutsche Bank"}}}]}}'); + foreach($stub as $key => $value) { + $e_invoice->{$key} = $value; + } + + $invoice->e_invoice = $e_invoice; + $invoice->save(); + + $this->assertInstanceOf(Invoice::class, $invoice); + $this->assertInstanceof(\InvoiceNinja\EInvoice\Models\Peppol\Invoice::class, $e_invoice); + + $p = new Peppol($invoice); + + $p->run(); + $xml = $p->toXml(); + nlog($xml); + + $identifiers = [ + [ + 'scheme' => 'ES:VAT', + 'id' => 'ESB53625999' + ], + ]; + + $sc = new \App\Services\EDocument\Gateway\Storecove\Storecove(); + $sc->sendDocument($xml, $this->routing_id, $identifiers); + + } + public function testDeRules() { $invoice = $this->createDEData(); @@ -527,8 +671,16 @@ $x = ' $p->run(); $xml = $p->toXml(); nlog($xml); - $sc = new \App\Services\EDocument\Gateway\Storecove\Storecove(); - $sc->sendDocument($xml); + + $identifiers = [ + [ + 'scheme' => 'DE:VAT', + 'id' => 'DE010101010' + ] + ]; + + $sc = new \App\Services\EDocument\Gateway\Storecove\Storecove(); + $sc->sendDocument($xml, $this->routing_id, $identifiers); }