2024-08-28 02:48:08 +02:00
< ? php
/**
* Invoice Ninja ( https :// invoiceninja . com ) .
*
* @ link https :// github . com / invoiceninja / invoiceninja source repository
*
* @ copyright Copyright ( c ) 2024. Invoice Ninja LLC ( https :// invoiceninja . com )
*
* @ license https :// www . elastic . co / licensing / elastic - license
*/
namespace App\Services\EDocument\Gateway\Storecove ;
class StorecoveRouter
2024-10-30 06:49:22 +01:00
{
/**
* Provides a country matrix for the correct scheme to send via
*
* @ var mixed $routing_rules
**/
2024-08-28 02:48:08 +02:00
private array $routing_rules = [
" US " => [
[ " B " , " DUNS, GLN, LEI " , " US:EIN " , " DUNS, GLN, LEI " ],
// ["B","DUNS, GLN, LEI","US:SSN","DUNS, GLN, LEI"],
],
" CA " => [ " B " , " CA:CBN " , false , " CA:CBN " ],
" MX " => [ " B " , " MX:RFC " , false , " MX:RFC " ],
" AU " => [ " B+G " , " AU:ABN " , false , " 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 " , false , " 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 " , false , " 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 " , false , " 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 " , " " , " IT:IVA " , " IT:CUUO " ], // (Peppol)
[ " B " , " " , " IT:IVA " , " IT:CUUO " ], // (SDI)
// ["B","","IT:CF","IT:CUUO"], // (SDI)
[ " C " , " " , " IT:CF " , " Email " ], // (SDI)
[ " G " , " " , " IT:IVA " , " IT:CUUO " ], // (SDI)
],
" 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 " , false , " 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 " , false , " 0195:SGUENT08GA0028A " ],
[ " B " , " SG:UEN " , " SG:GST " , " SG:UEN " ],
],
" GB " => [ " B " , " " , " GB:VAT " , " GB:VAT " ],
" SA " => [ " B " , " " , " SA:TIN " , " Email " ],
" Other " => [ " B " , " DUNS, GLN, LEI " , false , " DUNS, GLN, LEI " ],
];
public function __construct ()
{
}
/**
* Return the routing code based on country and entity classification
*
* @ param string $country
2024-08-28 09:07:17 +02:00
* @ param ? string $classification
2024-08-28 02:48:08 +02:00
* @ return string
*/
2024-08-28 09:07:17 +02:00
public function resolveRouting ( string $country , ? string $classification = 'business' ) : string
2024-08-28 02:48:08 +02:00
{
$rules = $this -> routing_rules [ $country ];
if ( is_array ( $rules ) && ! is_array ( $rules [ 0 ])) {
return $rules [ 3 ];
}
2024-08-29 01:55:27 +02:00
$code = 'B' ;
2024-08-28 02:48:08 +02:00
match ( $classification ) {
" business " => $code = " B " ,
" government " => $code = " G " ,
" individual " => $code = " C " ,
default => $code = " B " ,
};
foreach ( $rules as $rule ) {
if ( stripos ( $rule [ 0 ], $code ) !== false ) {
return $rule [ 3 ];
}
}
return $rules [ 0 ][ 3 ];
}
/**
* resolveTaxScheme
*
* @ param string $country
2024-08-28 04:48:08 +02:00
* @ param ? string $classification
2024-08-28 02:48:08 +02:00
* @ return string
*/
2024-08-28 09:07:17 +02:00
public function resolveTaxScheme ( string $country , ? string $classification = " business " ) : string
2024-08-28 02:48:08 +02:00
{
$rules = isset ( $this -> routing_rules [ $country ]) ? $this -> routing_rules [ $country ] : [ false , false , false , false ];
$code = " B " ;
match ( $classification ) {
" business " => $code = " B " ,
" government " => $code = " G " ,
" individual " => $code = " C " ,
default => $code = " B " ,
};
//single array
if ( is_array ( $rules ) && ! is_array ( $rules [ 0 ])) {
return $rules [ 2 ];
}
foreach ( $rules as $rule ) {
if ( stripos ( $rule [ 0 ], $code ) !== false ) {
return $rule [ 2 ];
}
}
return $rules [ 0 ][ 2 ];
}
2024-10-30 00:09:59 +01:00
/**
* used as a proxy for
* the schemeID of partyidentification
* property - for Storecove only :
*
* Used in the format key : value
*
* ie . IT : IVA / DE : VAT
*
* Note there are multiple options for the following countries :
*
* US ( EIN / SSN ) employer identification number / social security number
* IT ( CF / IVA ) Codice Fiscale ( person / company identifier ) / company vat number
*
* @ var array
2024-10-30 06:49:22 +01:00
* @ deprecated
2024-10-30 00:09:59 +01:00
*/
private array $schemeIdIdentifiers = [
'US' => 'EIN' ,
'US' => 'SSN' ,
'NZ' => 'GST' ,
'CH' => 'VAT' , // VAT number = CHE - 999999999 - MWST|IVA|VAT
'IS' => 'VAT' ,
'LI' => 'VAT' ,
'NO' => 'VAT' ,
'AD' => 'VAT' ,
'AL' => 'VAT' ,
'AT' => 'VAT' , //Tested - Routing GOV + Business
'BA' => 'VAT' ,
'BE' => 'VAT' ,
'BG' => 'VAT' ,
'AU' => 'ABN' , //Australia
'CA' => 'CBN' , //Canada
'MX' => 'RFC' , //Mexico
'NZ' => 'GST' , //Nuuu zulund
'GB' => 'VAT' , //Great Britain
'SA' => 'TIN' , //South Africa
'CY' => 'VAT' ,
'CZ' => 'VAT' ,
'DE' => 'VAT' , //tested - Requires Payment Means to be defined.
'DK' => 'ERST' ,
'EE' => 'VAT' ,
'ES' => 'VAT' , //tested - B2G pending
'FI' => 'VAT' ,
'FR' => 'VAT' , //tested - Need to ensure Siren/Siret routing
'GR' => 'VAT' ,
'HR' => 'VAT' ,
'HU' => 'VAT' ,
'IE' => 'VAT' ,
'IT' => 'IVA' , //tested - Requires a Customer Party Identification (VAT number) - 'IT senders must first be provisioned in the partner system.' Cannot test currently
'IT' => 'CF' , //tested - Requires a Customer Party Identification (VAT number) - 'IT senders must first be provisioned in the partner system.' Cannot test currently
'LT' => 'VAT' ,
'LU' => 'VAT' ,
'LV' => 'VAT' ,
'MC' => 'VAT' ,
'ME' => 'VAT' ,
'MK' => 'VAT' ,
'MT' => 'VAT' ,
'NL' => 'VAT' ,
'PL' => 'VAT' ,
'PT' => 'VAT' ,
'RO' => 'VAT' ,
'RS' => 'VAT' ,
'SE' => 'VAT' ,
'SI' => 'VAT' ,
'SK' => 'VAT' ,
'SM' => 'VAT' ,
'TR' => 'VAT' ,
'VA' => 'VAT' ,
'IN' => 'GSTIN' ,
'JP' => 'IIN' ,
'MY' => 'TIN' ,
'SG' => 'GST' ,
'GB' => 'VAT' ,
'SA' => 'TIN' ,
];
2024-08-28 02:48:08 +02:00
}