mirror of
https://github.com/invoiceninja/invoiceninja.git
synced 2024-09-20 16:31:33 +02:00
Add identifiers for storecove
This commit is contained in:
parent
a8c7d49528
commit
913a3e3ad9
@ -90,7 +90,7 @@ class Peppol extends AbstractService
|
||||
'NO' => 'VAT',
|
||||
'AD' => 'VAT',
|
||||
'AL' => 'VAT',
|
||||
'AT' => 'VAT', //Pending Tests.
|
||||
'AT' => 'VAT', //Tested - Routing GOV + Business
|
||||
'BA' => 'VAT',
|
||||
'BE' => 'VAT',
|
||||
'BG' => 'VAT',
|
||||
@ -155,6 +155,82 @@ class Peppol extends AbstractService
|
||||
"896" => "Debit note related to self-billed invoice"
|
||||
];
|
||||
|
||||
// 0 1 2 3
|
||||
// ["Country" => ["B2X","Legal","Tax","Routing"],
|
||||
private array $routing_rules = [
|
||||
"US" => ["B","DUNS, GLN, LEI","US:EIN, US:SSN","DUNS, GLN, LEI"],
|
||||
"CA" => ["B","CA:CBN","","CA:CBN"],
|
||||
"MX" => ["B","MX:RFC","","MX:RFC"],
|
||||
"AU" => ["B+G","AU:ABN","","AU:ABN"],
|
||||
"NZ" => ["B+G","GLN","NZ:GST","GLN"],
|
||||
"CH" => ["B+G","CH:UIDB","CH:VAT","CH:UIDB"],
|
||||
"IS" => ["B+G","IS:KTNR","IS:VAT","IS:KTNR"],
|
||||
"LI" => ["B+G","","LI:VAT","LI:VAT"],
|
||||
"NO" => ["B+G","NO:ORG","NO:VAT","NO:ORG"],
|
||||
"AD" => ["B+G","","AD:VAT","AD:VAT"],
|
||||
"AL" => ["B+G","","AL:VAT","AL:VAT"],
|
||||
"AT" => [
|
||||
["G","AT:GOV","","9915:b"],
|
||||
["B","","AT:VAT","AT:VAT"],
|
||||
],
|
||||
"BA" => ["B+G","","BA:VAT","BA:VAT"],
|
||||
"BE" => ["B+G","BE:EN","BE:VAT","BE:EN"],
|
||||
"BG" => ["B+G","","BG:VAT","BG:VAT"],
|
||||
"CY" => ["B+G","","CY:VAT","CY:VAT"],
|
||||
"CZ" => ["B+G","","CZ:VAT","CZ:VAT"],
|
||||
"DE" => [
|
||||
["G","DE:LWID","","DE:LWID"],
|
||||
["B","","DE:VAT","DE:VAT"],
|
||||
],
|
||||
"DK" => ["B+G","DK:DIGST","DK:ERST","DK:DIGST"],
|
||||
"EE" => ["B+G","EE:CC","EE:VAT","EE:CC"],
|
||||
"ES" => ["B","","ES:VAT","ES:VAT"],
|
||||
"FI" => ["B+G","FI:OVT","FI:VAT","FI:OVT"],
|
||||
"FR" => [
|
||||
["G","FR:SIRET + customerAssignedAccountIdValue","","0009:11000201100044"],
|
||||
["B","FR:SIRENE or FR:SIRET","FR:VAT","FR:SIRENE or FR:SIRET"],
|
||||
],
|
||||
"GR" => ["B+G","","GR:VAT","GR:VAT"],
|
||||
"HR" => ["B+G","","HR:VAT","HR:VAT"],
|
||||
"HU" => ["B+G","","HU:VAT","HU:VAT"],
|
||||
"IE" => ["B+G","","IE:VAT","IE:VAT"],
|
||||
"IT" => [
|
||||
["G (Peppol)","","IT:IVA","IT:CUUO"],
|
||||
["B (SDI)","","IT:CF and/or IT:IVA","IT:CUUO"],
|
||||
["C (SDI)","","IT:CF","Email"],
|
||||
["G (SDI)","","IT:IVA","IT:CUUO"],
|
||||
],
|
||||
"LT" => ["B+G","LT:LEC","LT:VAT","LT:LEC"],
|
||||
"LU" => ["B+G","LU:MAT","LU:VAT","LU:VAT"],
|
||||
"LV" => ["B+G","","LV:VAT","LV:VAT"],
|
||||
"MC" => ["B+G","","MC:VAT","MC:VAT"],
|
||||
"ME" => ["B+G","","ME:VAT","ME:VAT"],
|
||||
"MK" => ["B+G","","MK:VAT","MK:VAT"],
|
||||
"MT" => ["B+G","","MT:VAT","MT:VAT"],
|
||||
"NL" => ["G","NL:OINO","","NL:OINO"],
|
||||
"NL" => ["B","NL:KVK","NL:VAT","NL:KVK or NL:VAT"],
|
||||
"PL" => ["G+B","","PL:VAT","PL:VAT"],
|
||||
"PT" => ["G+B","","PT:VAT","PT:VAT"],
|
||||
"RO" => ["G+B","","RO:VAT","RO:VAT"],
|
||||
"RS" => ["G+B","","RS:VAT","RS:VAT"],
|
||||
"SE" => ["G+B","SE:ORGNR","SE:VAT","SE:ORGNR"],
|
||||
"SI" => ["G+B","","SI:VAT","SI:VAT"],
|
||||
"SK" => ["G+B","","SK:VAT","SK:VAT"],
|
||||
"SM" => ["G+B","","SM:VAT","SM:VAT"],
|
||||
"TR" => ["G+B","","TR:VAT","TR:VAT"],
|
||||
"VA" => ["G+B","","VA:VAT","VA:VAT"],
|
||||
"IN" => ["B","","IN:GSTIN","Email"],
|
||||
"JP" => ["B","JP:SST","JP:IIN","JP:SST"],
|
||||
"MY" => ["B","MY:EIF","MY:TIN","MY:EIF"],
|
||||
"SG" => [
|
||||
["G","SG:UEN","","0195:SGUENT08GA0028A"],
|
||||
["B","SG:UEN","SG:GST (optional)","SG:UEN"],
|
||||
],
|
||||
"GB" => ["B","","GB:VAT","GB:VAT"],
|
||||
"SA" => ["B","","SA:TIN","Email"],
|
||||
"Other" => ["B","DUNS, GLN, LEI","","DUNS, GLN, LEI"],
|
||||
];
|
||||
|
||||
private Company $company;
|
||||
|
||||
private InvoiceSum | InvoiceSumInclusive $calc;
|
||||
@ -270,7 +346,8 @@ class Peppol extends AbstractService
|
||||
// $this->p_invoice->TaxTotal = $this->getTotalTaxes(); it only wants the aggregate here!!
|
||||
$this->p_invoice->LegalMonetaryTotal = $this->getLegalMonetaryTotal();
|
||||
|
||||
$this->countryLevelMutators();
|
||||
$this->senderSpecificLevelMutators()
|
||||
->receiverSpecificLevelMutators();
|
||||
|
||||
return $this;
|
||||
|
||||
@ -805,12 +882,15 @@ class Peppol extends AbstractService
|
||||
}
|
||||
|
||||
/**
|
||||
* countryLevelMutators
|
||||
* senderSpecificLevelMutators
|
||||
*
|
||||
* Runs sender level specific requirements for the e-invoice,
|
||||
*
|
||||
* ie, mutations that are required by the senders country.
|
||||
*
|
||||
* Runs country level specific requirements for the e-invoice
|
||||
* @return self
|
||||
*/
|
||||
private function countryLevelMutators():self
|
||||
private function senderSpecificLevelMutators():self
|
||||
{
|
||||
|
||||
if(method_exists($this, $this->invoice->company->country()->iso_3166_2))
|
||||
@ -819,6 +899,24 @@ class Peppol extends AbstractService
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* receiverSpecificLevelMutators
|
||||
*
|
||||
* Runs receiver level specific requirements for the e-invoice
|
||||
*
|
||||
* ie mutations that are required by the receiving country
|
||||
* @return self
|
||||
*/
|
||||
private function receiverSpecificLevelMutators():self
|
||||
{
|
||||
|
||||
if(method_exists($this, "client_{$this->invoice->company->country()->iso_3166_2}"))
|
||||
$this->{"client_{$this->invoice->company->country()->iso_3166_2}"}();
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* setPaymentMeans
|
||||
*
|
||||
@ -1029,7 +1127,7 @@ class Peppol extends AbstractService
|
||||
|
||||
if($this->invoice->client->classification == 'government') {
|
||||
//routing "b" for production "test" for test environment
|
||||
$this->setStorecoveMeta($this->buildRouting('AT:GOV', "test"));
|
||||
$this->setStorecoveMeta($this->buildRouting('AT:GOV', "b"));
|
||||
|
||||
//for government clients this must be set.
|
||||
$this->setCustomerAssignedAccountId(true);
|
||||
@ -1134,7 +1232,8 @@ class Peppol extends AbstractService
|
||||
$this->setStorecoveMeta($this->buildRouting('FR:SIRET', "0009:{$this->invoice->client->id_number}"));
|
||||
}
|
||||
|
||||
// ??????????????????????? //@TODO
|
||||
// Apparently this is not a special field according to support
|
||||
// sounds like it is optional
|
||||
// The service code must be sent in invoice.buyerReference (deprecated) or the invoice.references array (documentType buyer_reference)
|
||||
|
||||
if(strlen($this->invoice->po_number ?? '') >1) {
|
||||
@ -1146,22 +1245,55 @@ class Peppol extends AbstractService
|
||||
|
||||
private function IT(): self
|
||||
{
|
||||
|
||||
// IT Sender, IT Receiver, B2B/B2G
|
||||
// Provide the receiver IT:VAT and the receiver IT:CUUO (codice destinatario)
|
||||
if($this->invoice->client->classification == 'government' && $this->invoice->company->country()->iso_3166_2 == 'IT') {
|
||||
|
||||
$this->setStorecoveMeta($this->buildRouting('IT:VAT', $this->invoice->client->routing_id));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// IT Sender, IT Receiver, B2C
|
||||
// Provide the receiver IT:CF and the receiver IT:CUUO (codice destinatario)
|
||||
if($this->invoice->client->classification == 'individual' && $this->invoice->company->country()->iso_3166_2 == 'IT') {
|
||||
|
||||
$this->setStorecoveMeta($this->buildRouting('IT:CF', $this->invoice->client->routing_id));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
// IT Sender, non-IT Receiver
|
||||
// Provide the receiver tax identifier and any routing identifier applicable to the receiving country (see Receiver Identifiers).
|
||||
if($this->invoice->client->country->iso_3166_2 != 'IT' && $this->invoice->company->country()->iso_3166_2 == 'IT') {
|
||||
|
||||
$code = $this->buildForeignRoutingCode();
|
||||
|
||||
$this->setStorecoveMeta($this->buildRouting($code, $this->invoice->client->vat_number));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
private function client_IT(): self
|
||||
{
|
||||
|
||||
// non-IT Sender, IT Receiver, B2C
|
||||
// Provide the receiver IT:CF and an optional email. The invoice will be eReported and sent via email. Note that this cannot be a PEC email address.
|
||||
if(in_array($this->invoice->client->classification, ['individual']) && $this->invoice->company->country()->iso_3166_2 != 'IT') {
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
|
||||
// non-IT Sender, IT Receiver, B2B/B2G
|
||||
// Provide the receiver IT:VAT and the receiver IT:CUUO (codice destinatario)
|
||||
|
||||
// non-IT Sender, IT Receiver, B2C
|
||||
// Provide the receiver IT:CF and an optional email. The invoice will be eReported and sent via email. Note that this cannot be a PEC email address.
|
||||
|
||||
return $this;
|
||||
|
||||
}
|
||||
|
||||
private function MY(): self
|
||||
|
@ -616,7 +616,7 @@ $x = '<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
}
|
||||
|
||||
private function createATData()
|
||||
private function createATData(bool $is_gov = false)
|
||||
{
|
||||
|
||||
$this->routing_id = 293801;
|
||||
@ -668,7 +668,7 @@ $x = '<?xml version="1.0" encoding="utf-8"?>
|
||||
'balance' => 0,
|
||||
'paid_to_date' => 0,
|
||||
'vat_number' => 'ATU87654321',
|
||||
'id_number' => 'FN 123456x', // Example format for Austrian company registration numbers
|
||||
'id_number' => $is_gov ? 'ATU12312321' : 'FN 123456x', // Example format for Austrian company registration numbers
|
||||
'custom_value1' => '2024-07-22 10:00:00',
|
||||
'custom_value2' => 'blau',
|
||||
'custom_value3' => 'musterwort',
|
||||
@ -688,7 +688,7 @@ $x = '<?xml version="1.0" encoding="utf-8"?>
|
||||
'settings' => ClientSettings::Defaults(),
|
||||
'client_hash' => \Illuminate\Support\Str::random(32),
|
||||
'routing_id' => '',
|
||||
'classification' => 'business',
|
||||
'classification' => $is_gov ? 'government' : 'business',
|
||||
]);
|
||||
|
||||
|
||||
@ -726,7 +726,39 @@ $x = '<?xml version="1.0" encoding="utf-8"?>
|
||||
|
||||
}
|
||||
|
||||
public function testAtRules()
|
||||
public function testAtGovernmentRules()
|
||||
{
|
||||
$this->routing_id = 293801;
|
||||
|
||||
$invoice = $this->createATData(true);
|
||||
|
||||
$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 = $p->getStorecoveMeta();
|
||||
|
||||
$sc = new \App\Services\EDocument\Gateway\Storecove\Storecove();
|
||||
$sc->sendDocument($xml, $this->routing_id, $identifiers);
|
||||
|
||||
}
|
||||
|
||||
public function PestAtRules()
|
||||
{
|
||||
$this->routing_id = 293801;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user