Storecove sending
This commit is contained in:
parent
a96d16f09e
commit
aca54675dc
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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] ?? [];
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
*
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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',
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
|
@ -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]) &&
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
|
|
|
|||
Loading…
Reference in New Issue