diff --git a/app/Http/Controllers/EInvoiceController.php b/app/Http/Controllers/EInvoiceController.php index c2f4962d80..eaba553252 100644 --- a/app/Http/Controllers/EInvoiceController.php +++ b/app/Http/Controllers/EInvoiceController.php @@ -15,6 +15,7 @@ use App\Http\Requests\EInvoice\ValidateEInvoiceRequest; use App\Http\Requests\EInvoice\UpdateEInvoiceConfiguration; use App\Services\EDocument\Standards\Validation\Peppol\EntityLevel; use InvoiceNinja\EInvoice\Models\Peppol\BranchType\FinancialInstitutionBranch; +use InvoiceNinja\EInvoice\Models\Peppol\FinancialInstitutionType\FinancialInstitution; use InvoiceNinja\EInvoice\Models\Peppol\FinancialAccountType\PayeeFinancialAccount; use InvoiceNinja\EInvoice\Models\Peppol\PaymentMeans; use InvoiceNinja\EInvoice\Models\Peppol\CardAccountType\CardAccount; @@ -41,8 +42,6 @@ class EInvoiceController extends BaseController default => $data['passes'] = false, }; - nlog($data); - return response()->json($data, $data['passes'] ? 200 : 400); } @@ -51,45 +50,56 @@ class EInvoiceController extends BaseController { $einvoice = new \InvoiceNinja\EInvoice\Models\Peppol\Invoice(); - $pm = new PaymentMeans(); - $pmc = new PaymentMeansCode(); - $pmc->value = $request->input('payment_means.code', null); - - if($this->input('payment_means.code') == '48') + foreach($request->input('payment_means', []) as $payment_means) { - $ctc = new CardTypeCode(); - $ctc->value = $request->input('payment_means.card_type', null); - $card_account = new CardAccount(); - $card_account->HolderName = $request->input('payment_means.cardholder_name', ''); - $card_account->CardTypeCode = $ctc; - $pm->CardAccount = $card_account; - } + $pm = new PaymentMeans(); - if($this->input('payment_means.iban')) - { - $fib = new FinancialInstitutionBranch(); - $bic_id = new ID(); - $bic_id->value = $request->input('payment_means.bic', null); - $fib->ID = $bic_id; - $pfa = new PayeeFinancialAccount(); - $iban_id = new ID(); - $iban_id->value = $request->input('payment_means.iban', null); - $pfa->ID = $iban_id; - $pfa->Name = $request->input('payment_means.account_name', null); - $pfa->FinancialInstitutionBranch = $fib; - - $pm->PayeeFinancialAccount = $pfa; + $pmc = new PaymentMeansCode(); + $pmc->value = $payment_means['code']; $pm->PaymentMeansCode = $pmc; + + if($payment_means['code'] == '48') + { + $ctc = new CardTypeCode(); + $ctc->value = $payment_means['card_type']; + $card_account = new CardAccount(); + $card_account->HolderName = $payment_means['card_holder']; + $card_account->CardTypeCode = $ctc; + $pm->CardAccount = $card_account; + } + + if(isset($payment_means['iban'])) + { + $fib = new FinancialInstitutionBranch(); + $fi = new FinancialInstitution(); + $bic_id = new ID(); + $bic_id->value = $payment_means['bic_swift']; + $fi->ID = $bic_id; + $fib->FinancialInstitution = $fi; + $pfa = new PayeeFinancialAccount(); + $iban_id = new ID(); + $iban_id->value = $payment_means['iban']; + $pfa->ID = $iban_id; + $pfa->Name = $payment_means['account_holder']; + $pfa->FinancialInstitutionBranch = $fib; + + $pm->PayeeFinancialAccount = $pfa; + + } + + if(isset($payment_means['information'])) + $pm->InstructionNote = $payment_means['information']; + + $einvoice->PaymentMeans[] = $pm; } - - $pm->InstructionNote = $request->input('payment_means.information', ''); - - $einvoice->PaymentMeans[] = $pm; - + $stub = new \stdClass(); $stub->Invoice = $einvoice; + $company = auth()->user()->company(); + $company->e_invoice = $stub; + $company->save(); } } diff --git a/app/Http/Requests/EInvoice/UpdateEInvoiceConfiguration.php b/app/Http/Requests/EInvoice/UpdateEInvoiceConfiguration.php index 44b3df69fd..b99ede0daf 100644 --- a/app/Http/Requests/EInvoice/UpdateEInvoiceConfiguration.php +++ b/app/Http/Requests/EInvoice/UpdateEInvoiceConfiguration.php @@ -41,37 +41,37 @@ class UpdateEInvoiceConfiguration extends Request return [ 'entity' => 'required|bail|in:invoice,client,company', 'payment_means' => 'sometimes|bail|array', - 'payment_means.code' => ['required_with:payment_means', 'bail', Rule::in(PaymentMeans::getPaymentMeansCodelist())], - 'payment_means.bic_swift' => ['bail', + 'payment_means.*.code' => ['required_with:payment_means', 'bail', Rule::in(PaymentMeans::getPaymentMeansCodelist())], + 'payment_means.*.bic_swift' => ['bail', Rule::requiredIf(function () { $code = $this->input('payment_means.code'); $requirements = PaymentMeans::$payment_means_requirements_codes[$code] ?? []; return in_array('bic_swift', $requirements); }), ], - 'payment_means.iban' => ['bail', 'string', 'min:8', 'max:11', + 'payment_means.*.iban' => ['bail', 'sometimes', 'string', 'min:15', 'max:34', Rule::requiredIf(function () { $code = $this->input('payment_means.code'); $requirements = PaymentMeans::$payment_means_requirements_codes[$code] ?? []; return in_array('iban', $requirements); }), ], - 'payment_means.account_holder' => ['bail', 'string', 'min:15', 'max:34', + 'payment_means.*.account_holder' => ['bail', 'sometimes', 'string', 'max:255', Rule::requiredIf(function () { $code = $this->input('payment_means.code'); $requirements = PaymentMeans::$payment_means_requirements_codes[$code] ?? []; return in_array('account_holder', $requirements); }), ], - 'payment_means.information' => ['bail', 'sometimes', 'string'], - 'payment_means.card_type' => ['bail', 'string', 'min:4', + 'payment_means.*.information' => ['bail', 'sometimes', 'nullable', 'string'], + 'payment_means.*.card_type' => ['bail', 'sometimes', 'nullable', 'string', 'min:4', Rule::requiredIf(function () { $code = $this->input('payment_means.code'); $requirements = PaymentMeans::$payment_means_requirements_codes[$code] ?? []; return in_array('card_type', $requirements); }), ], - 'payment_means.card_holder' => ['bail','string', 'min:4', + 'payment_means.*.card_holder' => ['bail', 'sometimes', 'nullable', 'string', 'min:4', Rule::requiredIf(function () { $code = $this->input('payment_means.code'); $requirements = PaymentMeans::$payment_means_requirements_codes[$code] ?? []; diff --git a/app/Services/EDocument/Gateway/Storecove/Models/Invoice.php b/app/Services/EDocument/Gateway/Storecove/Models/Invoice.php index c508fe312d..f4172ca5a7 100644 --- a/app/Services/EDocument/Gateway/Storecove/Models/Invoice.php +++ b/app/Services/EDocument/Gateway/Storecove/Models/Invoice.php @@ -40,7 +40,7 @@ class Invoice #[SerializedPath('[cac:AllowanceCharge]')] /** @var AllowanceCharges[] */ - public array $allowance_charges; + public ?array $allowance_charges = []; //this is an experimental prop // #[SerializedPath('[cac:LegalMonetaryTotal][cbc:TaxInclusiveAmount][#]')] @@ -67,7 +67,7 @@ class Invoice // /** @var ?\DateTime */ #[SerializedPath('[cbc:DueDate]')] // #[Context([DateTimeNormalizer::FORMAT_KEY => 'Y-m-d'])] - public $due_date; + public ?string $due_date; //may need something custom for this public ?string $invoice_period; @@ -166,7 +166,7 @@ class Invoice public function __construct( ?string $invoice_number, - $issue_date, + ?string $issue_date, ?AccountingCustomerParty $accounting_customer_party, ?array $invoice_lines, ?string $accounting_cost, @@ -176,14 +176,14 @@ class Invoice ?string $accounting_currency_tax_amount_currency, ?AccountingSupplierParty $accounting_supplier_party, ?array $allowance_charges, - ?string $amount_including_tax, - ?string $amount_including_vat, + ?float $amount_including_tax, + ?float $amount_including_vat, ?array $attachments, ?bool $consumer_tax_mode, ?Delivery $delivery, ?DeliveryTerms $delivery_terms, ?string $document_currency_code, - $due_date, + ?string $due_date, ?string $invoice_period, ?array $issue_reasons, ?string $issue_time, @@ -335,12 +335,12 @@ class Invoice return $this->allowance_charges; } - public function getAmountIncludingTax(): ?string + public function getAmountIncludingTax(): ?float { return $this->amount_including_tax; } - public function getAmountIncludingVat(): ?string + public function getAmountIncludingVat(): ?float { return $this->amount_including_vat; } @@ -638,13 +638,13 @@ class Invoice return $this; } - public function setAmountIncludingTax(?string $amount_including_tax): self + public function setAmountIncludingTax(?float $amount_including_tax): self { $this->amount_including_tax = $amount_including_tax; return $this; } - public function setAmountIncludingVat(?string $amount_including_vat): self + public function setAmountIncludingVat(?float $amount_including_vat): self { $this->amount_including_vat = $amount_including_vat; return $this; @@ -683,7 +683,7 @@ class Invoice return $this; } - public function setDueDate($due_date): self + public function setDueDate(?string $due_date): self { $this->due_date = $due_date; return $this; diff --git a/app/Services/EDocument/Gateway/Storecove/Models/InvoiceLines.php b/app/Services/EDocument/Gateway/Storecove/Models/InvoiceLines.php index e4b9cce637..2616107547 100644 --- a/app/Services/EDocument/Gateway/Storecove/Models/InvoiceLines.php +++ b/app/Services/EDocument/Gateway/Storecove/Models/InvoiceLines.php @@ -41,13 +41,13 @@ class InvoiceLines public ?array $charges; #[SerializedPath('[cbc:LineExtensionAmount][#]')] - public ?string $amount_excluding_vat; + public ?float $amount_excluding_vat; #[SerializedPath('[cbc:TaxExclusiveAmount][#]')] - public ?string $amount_excluding_tax; + public ?float $amount_excluding_tax; #[SerializedPath('[cbc:TaxInclusiveAmount][#]')] - public ?string $amount_including_tax; + public ?float $amount_including_tax; #[SerializedPath('[cac:Item][cac:ClassifiedTaxCategory]')] /** @var TaxesDutiesFees[] */ @@ -99,9 +99,9 @@ class InvoiceLines ?float $base_quantity, ?string $quantity_unit_code, ?array $charges, - ?string $amount_excluding_vat, - ?string $amount_excluding_tax, - ?string $amount_including_tax, + ?float $amount_excluding_vat, + ?float $amount_excluding_tax, + ?float $amount_including_tax, ?array $taxes_duties_fees, ?string $accounting_cost, ?array $references, @@ -191,17 +191,17 @@ class InvoiceLines return $this->charges; } - public function getAmountExcludingVat(): ?string + public function getAmountExcludingVat(): ?float { return $this->amount_excluding_vat; } - public function getAmountExcludingTax(): ?string + public function getAmountExcludingTax(): ?float { return $this->amount_excluding_tax; } - public function getAmountIncludingTax(): ?string + public function getAmountIncludingTax(): ?float { return $this->amount_including_tax; } @@ -328,19 +328,19 @@ class InvoiceLines return $this; } - public function setAmountExcludingVat(?string $amount_excluding_vat): self + public function setAmountExcludingVat(?float $amount_excluding_vat): self { $this->amount_excluding_vat = $amount_excluding_vat; return $this; } - public function setAmountExcludingTax(?string $amount_excluding_tax): self + public function setAmountExcludingTax(?float $amount_excluding_tax): self { $this->amount_excluding_tax = $amount_excluding_tax; return $this; } - public function setAmountIncludingTax(?string $amount_including_tax): self + public function setAmountIncludingTax(?float $amount_including_tax): self { $this->amount_including_tax = $amount_including_tax; return $this; diff --git a/app/Services/EDocument/Gateway/Storecove/Models/Tax.php b/app/Services/EDocument/Gateway/Storecove/Models/Tax.php index 53808edb82..181231c487 100644 --- a/app/Services/EDocument/Gateway/Storecove/Models/Tax.php +++ b/app/Services/EDocument/Gateway/Storecove/Models/Tax.php @@ -5,15 +5,15 @@ namespace App\Services\EDocument\Gateway\Storecove\Models; class Tax { public ?string $country; - public ?string $amount; - public ?string $percentage; + public ?float $amount; + public ?float $percentage; public ?string $category; public ?string $type; public function __construct( ?string $country, - ?string $amount, - ?string $percentage, + ?float $amount, + ?float $percentage, ?string $category, ?string $type ) { @@ -29,12 +29,12 @@ class Tax return $this->country; } - public function getAmount(): ?string + public function getAmount(): ?float { return $this->amount; } - public function getPercentage(): ?string + public function getPercentage(): ?float { return $this->percentage; } @@ -55,13 +55,13 @@ class Tax return $this; } - public function setAmount(?string $amount): self + public function setAmount(?float $amount): self { $this->amount = $amount; return $this; } - public function setPercentage(?string $percentage): self + public function setPercentage(?float $percentage): self { $this->percentage = $percentage; return $this; diff --git a/app/Services/EDocument/Gateway/Storecove/Models/TaxSubtotals.php b/app/Services/EDocument/Gateway/Storecove/Models/TaxSubtotals.php index 357b932af0..e1f25dd921 100644 --- a/app/Services/EDocument/Gateway/Storecove/Models/TaxSubtotals.php +++ b/app/Services/EDocument/Gateway/Storecove/Models/TaxSubtotals.php @@ -9,24 +9,24 @@ class TaxSubtotals { #[SerializedPath('[cbc:TaxAmount][#]')] - public ?string $tax_amount; + public ?float $tax_amount; public ?string $country; #[SerializedPath('[cbc:TaxableAmount][#]')] - public ?string $taxable_amount; + public ?float $taxable_amount; #[SerializedPath('[cac:TaxCategory][cbc:Percent]')] - public ?string $percentage; + public ?float $percentage; #[SerializedPath('[cac:TaxCategory][cbc:ID][#]')] public ?string $category; public function __construct( - ?string $tax_amount, + ?float $tax_amount, ?string $country, - ?string $taxable_amount, - ?string $percentage, + ?float $taxable_amount, + ?float $percentage, ?string $category ) { $this->tax_amount = $tax_amount; @@ -36,7 +36,7 @@ class TaxSubtotals $this->category = $category; } - public function getTaxAmount(): ?string + public function getTaxAmount(): ?float { return $this->tax_amount; } @@ -46,12 +46,12 @@ class TaxSubtotals return $this->country; } - public function getTaxableAmount(): ?string + public function getTaxableAmount(): ?float { return $this->taxable_amount; } - public function getPercentage(): ?string + public function getPercentage(): ?float { return $this->percentage; } @@ -61,7 +61,7 @@ class TaxSubtotals return $this->category; } - public function setTaxAmount(?string $tax_amount): self + public function setTaxAmount(?float $tax_amount): self { $this->tax_amount = $tax_amount; return $this; @@ -73,13 +73,13 @@ class TaxSubtotals return $this; } - public function setTaxableAmount(?string $taxable_amount): self + public function setTaxableAmount(?float $taxable_amount): self { $this->taxable_amount = $taxable_amount; return $this; } - public function setPercentage(?string $percentage): self + public function setPercentage(?float $percentage): self { $this->percentage = $percentage; return $this; diff --git a/app/Services/EDocument/Gateway/Storecove/Models/TaxesDutiesFees.php b/app/Services/EDocument/Gateway/Storecove/Models/TaxesDutiesFees.php index 92530c8726..d81f4ff918 100644 --- a/app/Services/EDocument/Gateway/Storecove/Models/TaxesDutiesFees.php +++ b/app/Services/EDocument/Gateway/Storecove/Models/TaxesDutiesFees.php @@ -8,10 +8,10 @@ use Symfony\Component\Serializer\Attribute\SerializedPath; class TaxesDutiesFees { public ?string $country; //need to run postprocessing on this - public ?string $amount; + public ?float $amount; #[SerializedName('cbc:Percent')] - public ?string $percentage; + public ?float $percentage; #[SerializedPath('[cbc:ID][#]')] public ?string $category; @@ -21,8 +21,8 @@ class TaxesDutiesFees public function __construct( ?string $country, - ?string $amount, - ?string $percentage, + ?float $amount, + ?float $percentage, ?string $category, ?string $type ) { @@ -38,12 +38,12 @@ class TaxesDutiesFees return $this->country; } - public function getAmount(): ?string + public function getAmount(): ?float { return $this->amount; } - public function getPercentage(): ?string + public function getPercentage(): ?float { return $this->percentage; } @@ -64,13 +64,13 @@ class TaxesDutiesFees return $this; } - public function setAmount(?string $amount): self + public function setAmount(?float $amount): self { $this->amount = $amount; return $this; } - public function setPercentage(?string $percentage): self + public function setPercentage(?float $percentage): self { $this->percentage = $percentage; return $this; diff --git a/app/Services/EDocument/Gateway/Storecove/Mutator.php b/app/Services/EDocument/Gateway/Storecove/Mutator.php index 9a1f3f6fe2..90d6842796 100644 --- a/app/Services/EDocument/Gateway/Storecove/Mutator.php +++ b/app/Services/EDocument/Gateway/Storecove/Mutator.php @@ -574,6 +574,17 @@ class Mutator implements MutatorInterface /////////////// Storecove Helpers /////////////// + public function setClientRoutingCode(): self + { + $code = $this->getClientRoutingCode(); + + $this->setStorecoveMeta($this->buildRouting([ + ["scheme" => $code, "id" => $this->invoice->client->vat_number] + ])); + + return $this; + } + /** * getClientRoutingCode * diff --git a/app/Services/EDocument/Gateway/Storecove/Storecove.php b/app/Services/EDocument/Gateway/Storecove/Storecove.php index d3ce8d708c..4ddd36cd81 100644 --- a/app/Services/EDocument/Gateway/Storecove/Storecove.php +++ b/app/Services/EDocument/Gateway/Storecove/Storecove.php @@ -78,7 +78,8 @@ class Storecove $this->adapter ->transform($model) ->decorate() - ->validate(); + ->validate() + ->getDocument(); } /** @@ -141,33 +142,23 @@ class Storecove /** * Unused as yet * @todo - * @param mixed $document + * @param mixed $payload * @return string|bool */ - public function sendJsonDocument($document) + public function sendJsonDocument(array $payload) { - - $payload = [ - // "legalEntityId" => 290868, - "idempotencyGuid" => \Illuminate\Support\Str::uuid(), - "routing" => [ - "eIdentifiers" => [], - "emails" => ["david@invoiceninja.com"] - ], - "document" => [ - "documentType" => "invoice", - "invoice" => $document, - ], - ]; - + nlog($payload); $uri = "document_submissions"; $r = $this->httpClient($uri, (HttpVerb::POST)->value, $payload, $this->getHeaders()); if($r->successful()) { + nlog("sent! GUID = {$r->json()['guid']}"); return $r->json()['guid']; } + nlog($r->body()); + return false; } diff --git a/app/Services/EDocument/Gateway/Storecove/StorecoveAdapter.php b/app/Services/EDocument/Gateway/Storecove/StorecoveAdapter.php index 51ab23bb59..28826a6b45 100644 --- a/app/Services/EDocument/Gateway/Storecove/StorecoveAdapter.php +++ b/app/Services/EDocument/Gateway/Storecove/StorecoveAdapter.php @@ -23,6 +23,7 @@ use App\Services\EDocument\Gateway\Transformers\StorecoveTransformer; use Symfony\Component\Serializer\Normalizer\AbstractObjectNormalizer; use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory; use App\Services\EDocument\Gateway\Storecove\PeppolToStorecoveNormalizer; +use App\Services\EDocument\Standards\Peppol; use Symfony\Component\Serializer\NameConverter\MetadataAwareNameConverter; use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter; @@ -51,17 +52,33 @@ class StorecoveAdapter { $this->ninja_invoice = $invoice; - $this->buildNexus(); - - $context = [ - DateTimeNormalizer::FORMAT_KEY => 'Y-m-d', - AbstractObjectNormalizer::SKIP_NULL_VALUES => true, - ]; - $serializer = $this->getSerializer(); + $p = (new Peppol($invoice))->run()->toXml(); + + nlog($p); + +$context = [ + DateTimeNormalizer::FORMAT_KEY => 'Y-m-d', + AbstractObjectNormalizer::SKIP_NULL_VALUES => true, + ]; + + +$e = new \InvoiceNinja\EInvoice\EInvoice(); +$peppolInvoice = $e->decode('Peppol', $p, 'xml'); + +$parent = \App\Services\EDocument\Gateway\Storecove\Models\Invoice::class; +$peppolInvoice = $data = $e->encode($peppolInvoice, 'json', $context); +$this->storecove_invoice = $serializer->deserialize($peppolInvoice, $parent, 'json', $context); +// $s_invoice = $serializer->encode($invoice, 'json', $context); +// $arr = json_decode($s_invoice, true); +// $data = $this->removeEmptyValues($arr); + + + $this->buildNexus(); + // @phpstan-ignore-next-line - $this->storecove_invoice = $serializer->deserialize($invoice->e_invoice, Invoice::class, 'json', $context); + // $this->storecove_invoice = $serializer->deserialize($data, Invoice::class, 'json', $context); return $this; @@ -77,6 +94,9 @@ class StorecoveAdapter foreach($line->taxes_duties_fees as &$tax) { $tax->country = $this->nexus; + + if(property_exists($tax,'category')) + $tax->category = $this->tranformTaxCode($tax->category); } unset($tax); } @@ -88,12 +108,27 @@ class StorecoveAdapter foreach($tax_subtotals as &$tax) { $tax->country = $this->nexus; + + if (property_exists($tax, 'category')) + $tax->category = $this->tranformTaxCode($tax->category); + } unset($tax); $this->storecove_invoice->setTaxSubtotals($tax_subtotals); //configure identifiers + //update payment means codes to storecove equivalents + $payment_means = $this->storecove_invoice->getPaymentMeansArray(); + + foreach($payment_means as &$pm) + { + $pm->code = $this->transformPaymentMeansCode($pm->code); + } + + $this->storecove_invoice->setPaymentMeansArray($payment_means); + + $this->storecove_invoice->setTaxSystem('tax_line_percentages'); //set additional identifier if required (ie de => FR with FR vat) return $this; } @@ -151,6 +186,30 @@ class StorecoveAdapter return $serializer; } + public function getDocument(): mixed + { + $serializer = $this->getSerializer(); + + $context = [ + DateTimeNormalizer::FORMAT_KEY => 'Y-m-d', + AbstractObjectNormalizer::SKIP_NULL_VALUES => true, + ]; + + $s_invoice = $serializer->encode($this->storecove_invoice, 'json', $context); + + $s_invoice = json_decode($s_invoice, true); + + $s_invoice = $this->removeEmptyValues($s_invoice); + + $data = [ + 'errors' => $this->getErrors(), + 'document' => $s_invoice, + ]; + + return $data; + + } + private function removeEmptyValues(array $array): array { foreach ($array as $key => $value) { @@ -200,4 +259,61 @@ class StorecoveAdapter return $this; } + + private function tranformTaxCode(string $code): ?string + { + return match($code){ + 'S' => 'standard', + 'Z' => 'zero_rated', + 'E' => 'exempt', + 'AE' => 'reverse_charge', + 'K' => 'intra_community', + 'G' => 'export', + 'O' => 'outside_scope', + 'L' => 'cgst', + 'I' => 'igst', + 'SS' => 'sgst', + 'B' => 'deemed_supply', + 'SR' => 'srca_s', + 'SC' => 'srca_c', + 'NR' => 'not_registered', + default => null + }; + } + + private function transformPaymentMeansCode(?string $code): string + { + return match($code){ + '30' => 'credit_transfer', + '58' => 'sepa_credit_transfer', + '31' => 'debit_transfer', + '49' => 'direct_debit', + '59' => 'sepa_direct_debit', + '48' => 'card', // Generic card payment + '54' => 'bank_card', + '55' => 'credit_card', + '57' => 'standing_agreement', + '10' => 'cash', + '20' => 'bank_cheque', + '21' => 'cashiers_cheque', + '97' => 'aunz_npp', + '98' => 'aunz_npp_payid', + '99' => 'aunz_npp_payto', + '71' => 'aunz_bpay', + '72' => 'aunz_postbillpay', + '73' => 'aunz_uri', + '50' => 'se_bankgiro', + '51' => 'se_plusgiro', + '74' => 'sg_giro', + '75' => 'sg_card', + '76' => 'sg_paynow', + '77' => 'it_mav', + '78' => 'it_pagopa', + '42' => 'nl_ga_beneficiary', + '43' => 'nl_ga_gaccount', + '1' => 'undefined', // Instrument not defined + default => 'undefined', + }; + + } } \ No newline at end of file diff --git a/app/Services/EDocument/Gateway/Transformers/StorecoveTransformer.php b/app/Services/EDocument/Gateway/Transformers/StorecoveTransformer.php index 41c56d5763..6fa1577c02 100644 --- a/app/Services/EDocument/Gateway/Transformers/StorecoveTransformer.php +++ b/app/Services/EDocument/Gateway/Transformers/StorecoveTransformer.php @@ -49,7 +49,7 @@ class StorecoveTransformer implements TransformerInterface public function transform(mixed $invoice) { - $this->s_invoice->setTaxPointDate($invoice->IssueDate->format('Y-m-d')); + // $this->s_invoice->setTaxPointDate($invoice->IssueDate->format('Y-m-d')); // Only use this if we are billing for services between a period. if (isset($invoice->InvoicePeriod[0]) && diff --git a/app/Services/EDocument/Jobs/SendEDocument.php b/app/Services/EDocument/Jobs/SendEDocument.php index d8cb20f672..a38c2fe7c2 100644 --- a/app/Services/EDocument/Jobs/SendEDocument.php +++ b/app/Services/EDocument/Jobs/SendEDocument.php @@ -51,29 +51,48 @@ class SendEDocument implements ShouldQueue $model = $this->entity::find($this->id); + $p = new Peppol($model); + $p->run(); + $identifiers = $p->gateway->mutator->setClientRoutingCode()->getStorecoveMeta(); + + $result = $storecove->build($model); + + if (count($result['errors']) > 0) { + return $result['errors']; + } + + $payload = [ + 'legal_entity_id' => $model->company->legal_entity_id, + "idempotencyGuid" => \Illuminate\Support\Str::uuid(), + 'document' => [ + 'document_type' => 'invoice', + 'invoice' => $result['document'], + ], + 'tenant_id' => $model->company->company_key, + 'routing' => $identifiers['routing'], + // 'e_invoicing_token' => $model->company->e_invoicing_token, + // include whitelabel key. + ]; + + //temp + + $sc = new \App\Services\EDocument\Gateway\Storecove\Storecove(); + $r = $sc->sendJsonDocument($payload); + + + if (is_string($r)) { + return $this->writeActivity($model, $r); + } + else { + // nlog($r->body()); + } + + return; + + if(Ninja::isSelfHost() && ($model instanceof Invoice) && $model->company->legal_entity_id) { - - $p = new Peppol($model); - $p->run(); - $identifiers = $p->gateway->mutator->getStorecoveMeta(); - - $result = $storecove->build($model); - - /**************************** Legacy */ - $xml = $p->toXml(); - $payload = [ - 'legal_entity_id' => $model->company->legal_entity_id, - // 'document' => base64_encode($xml), - 'tenant_id' => $model->company->company_key, - 'identifiers' => $identifiers, - // 'e_invoicing_token' => $model->company->e_invoicing_token, - // include whitelabel key. - ]; - - /**************************** Legacy */ - $r = Http::withHeaders($this->getHeaders()) ->post(config('ninja.hosted_ninja_url')."/api/einvoice/submission", $payload); @@ -95,15 +114,9 @@ class SendEDocument implements ShouldQueue if(Ninja::isHosted() && ($model instanceof Invoice) && $model->company->legal_entity_id) { - //hosted sender - $p = new Peppol($model); - - $p->run(); - $xml = $p->toXml(); - $identifiers = $p->getStorecoveMeta(); $sc = new \App\Services\EDocument\Gateway\Storecove\Storecove(); - $r = $sc->sendDocument($xml, $model->company->legal_entity_id, $identifiers); + $r = $sc->sendJsonDocument($payload); if(is_string($r)) return $this->writeActivity($model, $r); diff --git a/app/Services/EDocument/Standards/Peppol.php b/app/Services/EDocument/Standards/Peppol.php index 551a1e869c..038d7c4b8c 100644 --- a/app/Services/EDocument/Standards/Peppol.php +++ b/app/Services/EDocument/Standards/Peppol.php @@ -191,7 +191,7 @@ class Peppol extends AbstractService $ip = new InvoicePeriod(); $ip->StartDate = new \DateTime($this->invoice->date); $ip->EndDate = new \DateTime($this->invoice->due_date); - $this->p_invoice->InvoicePeriod[] = $ip; + $this->p_invoice->InvoicePeriod = [$ip]; } if ($this->invoice->project_id) { @@ -199,7 +199,7 @@ class Peppol extends AbstractService $id = new \InvoiceNinja\EInvoice\Models\Peppol\IdentifierType\ID(); $id->value = $this->invoice->project->number; $pr->ID = $id; - $this->p_invoice->ProjectReference[] = $pr; + $this->p_invoice->ProjectReference = [$pr]; } /** Auto switch between Invoice / Credit based on the amount value */ @@ -221,7 +221,7 @@ class Peppol extends AbstractService ->getPeppol(); //** @todo double check this logic, this will only ever write the doc once */ - if(strlen($this->invoice->backup ?? '') == 0) + if(is_null($this->invoice->backup)) { $this->invoice->e_invoice = $this->toObject(); $this->invoice->save(); diff --git a/tests/Integration/Einvoice/Storecove/StorecoveTest.php b/tests/Integration/Einvoice/Storecove/StorecoveTest.php index fb581611f3..19beaaa6bb 100644 --- a/tests/Integration/Einvoice/Storecove/StorecoveTest.php +++ b/tests/Integration/Einvoice/Storecove/StorecoveTest.php @@ -105,7 +105,6 @@ class StorecoveTest extends TestCase $this->assertInstanceOf(\InvoiceNinja\EInvoice\Models\Peppol\Invoice::class, $peppolInvoice); $parent = \App\Services\EDocument\Gateway\Storecove\Models\Invoice::class; - // $peppolInvoice = $e->encode($peppolInvoice, 'json'); $peppolInvoice = $data = $e->encode($peppolInvoice, 'json', $context); @@ -159,15 +158,14 @@ class StorecoveTest extends TestCase $p->run(); $peppolInvoice = $p->getInvoice(); + // $s_transformer = new StorecoveTransformer(); + // $s_transformer->transform($peppolInvoice); - $s_transformer = new StorecoveTransformer(); - $s_transformer->transform($peppolInvoice); + // $json = $s_transformer->toJson(); - $json = $s_transformer->toJson(); - - $this->assertJson($json); + // $this->assertJson($json); - nlog($json); + // nlog($json); } // public function testStorecoveTransformer()