E-INVOICE: check data before generating
E-INVOICE: add missing for Belgium : BuyerReference and Due_Date
This commit is contained in:
parent
d776c7bf98
commit
9ebb89b38a
8 changed files with 520 additions and 117 deletions
136
include/XMLDocument/Error_Message.php
Normal file
136
include/XMLDocument/Error_Message.php
Normal file
|
|
@ -0,0 +1,136 @@
|
|||
<?php
|
||||
|
||||
namespace Noalyss\XMLDocument;
|
||||
|
||||
/*
|
||||
* This file is part of NOALYSS.
|
||||
*
|
||||
* NOALYSS is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* NOALYSS is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with NOALYSS; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
// Copyright Author Dany De Bontridder danydb@aevalys.eu 22/10/23
|
||||
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief Give the error message thanks the code for FacturX and UBL21
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @class
|
||||
* @brief Give the error message thanks the code for FacturX and UBL21
|
||||
*
|
||||
property $a_error (double array)
|
||||
keys :
|
||||
- general ,
|
||||
- customer,
|
||||
- ATTR_DEF_NAME=>'CUST_NAME'
|
||||
- ATTR_DEF_ADRESS=>'CUST_ADDR'
|
||||
- ATTR_DEF_POSTCODE=>'CUST_POSTCD'
|
||||
- ATTR_DEF_CITY=>'CUST_CITY'
|
||||
- ATTR_DEF_COUNTRY_CODE=>'CUST_CDCOUNTRY'
|
||||
- ATTR_DEF_NUMTVA=>'CUST_VAT'
|
||||
- ATTR_DEF_PEPPOLID=>'CUST_PEPPOLID'
|
||||
- company,
|
||||
- "INVOICE_EMAIL_COMPANY" company's email
|
||||
- 'INVOICE_CONTACT_NAME' contact name
|
||||
- 'COMPANY_LEGAL_ENTITY' legal form of company
|
||||
- 'COMPANY_LEGAL_REGISTRATION' full name
|
||||
- 'COMPANY_BANK_IBAN' IBAN bank account
|
||||
- 'COMPANY_BANK_BIC' BIC bank account
|
||||
- 'COMPANY_UBL_ID' PEPPOL id
|
||||
- 'MY_COUNTRY_CODE' country code (normally BE)
|
||||
- 'MY_NAME' short company name
|
||||
- 'MY_STREET' address
|
||||
- 'MY_CITY' address
|
||||
- 'MY_TVA' VAT number
|
||||
*
|
||||
*/
|
||||
class Error_Message
|
||||
{
|
||||
|
||||
private $a_error;
|
||||
private $a_message_company;
|
||||
private $a_message_customer;
|
||||
|
||||
/**
|
||||
* @brief constructo
|
||||
* @param $a_error (double array)
|
||||
*/
|
||||
public function __construct($a_error)
|
||||
{
|
||||
$this->a_error = $a_error;
|
||||
$this->a_message_company = array(
|
||||
"INVOICE_EMAIL_COMPANY" => _("L'email de la société ")
|
||||
, 'INVOICE_CONTACT_NAME' => _("Nom du contact")
|
||||
, 'COMPANY_LEGAL_ENTITY' => _("Type de société (SRL,ASBL,...)")
|
||||
, 'COMPANY_LEGAL_REGISTRATION' => _("Nom complet de la société")
|
||||
, 'COMPANY_BANK_IBAN' => _("Compte en banque (IBAN) de la société")
|
||||
, 'COMPANY_BANK_BIC' => _("Code BIC de compte en banque")
|
||||
, 'COMPANY_UBL_ID' => _("Identifiant PEPPOL")
|
||||
, 'MY_COUNTRY_CODE' => _('Code Pays')
|
||||
, 'MY_NAME' => _("Nom de la société")
|
||||
, 'MY_STREET' => _("Adresse de la société")
|
||||
, 'MY_CITY' => _("Ville")
|
||||
, 'MY_TVA' => _("Numéro de TVA")
|
||||
|
||||
);
|
||||
$this->a_message_customer = array(
|
||||
'name' => _("Nom")
|
||||
, 'street' => _("Adresse")
|
||||
, 'postalzone' => _("Code postal")
|
||||
, 'city' => _("Ville")
|
||||
, 'country'=>_("Code pays")
|
||||
, 'customer_id' => _("Numéro de TVA")
|
||||
, 'endpoint_id' => _('Identifiant PEPPOL')
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
public function get_a_error()
|
||||
{
|
||||
return $this->a_error;
|
||||
}
|
||||
|
||||
public function set_a_error($a_error)
|
||||
{
|
||||
$this->a_error = $a_error;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief returns the text of an error
|
||||
* @param $code (string or number)
|
||||
* @param $type (string) customer , general or company
|
||||
*/
|
||||
function get_message_error($code, $type)
|
||||
{
|
||||
if ($type == "customer")
|
||||
{
|
||||
$a_error = $this->a_error['customer'];
|
||||
$a_message = $this->a_message_customer;
|
||||
} else if ($type == "company")
|
||||
{
|
||||
$a_error = $this->a_error['company'];
|
||||
$a_message = $this->a_message_company;
|
||||
} else
|
||||
{
|
||||
throw new \Exception("EM116: unknow type");
|
||||
}
|
||||
|
||||
return $a_message[$code];
|
||||
}
|
||||
}
|
||||
|
|
@ -54,18 +54,22 @@ class InvoiceUBL21 extends XMLInvoice {
|
|||
, 'MY_STREET'
|
||||
, 'MY_CITY'
|
||||
, 'MY_TVA'
|
||||
, 'INVOICE_EMAIL_COMPANY'
|
||||
];
|
||||
protected $pdf_filename; //!< PDF file to insert into XML, it is the file on the filesystem
|
||||
protected $pdf_filename; //!< PDF file to insert into XML,
|
||||
// it is the file on the filesystem
|
||||
public function get_pdf_filename() {
|
||||
return $this->pdf_filename;
|
||||
}
|
||||
/**
|
||||
* @brief returns the text of an error
|
||||
* @brief display_error display a warning with all error
|
||||
*/
|
||||
function get_message_error($a_code)
|
||||
function display_error()
|
||||
{
|
||||
|
||||
$a_error=$this->verify();
|
||||
include NOALYSS_TEMPLATE."/invoiceUBL21-display_error.php";
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief check that all the data are correct
|
||||
* @returns null : no errors, string separated with comma of error code
|
||||
|
|
@ -74,15 +78,17 @@ class InvoiceUBL21 extends XMLInvoice {
|
|||
*/
|
||||
function verify()
|
||||
{
|
||||
///@var $a_error : array of error_code see check_company_error
|
||||
$a_error=[];
|
||||
// verify all VAT
|
||||
$x=parent::verify();
|
||||
// verify that all needed data in PARAMETER are valid
|
||||
$this->check_company_data($a_error);
|
||||
$this->check_customer_data($this->data['customer']['customer_id'], $a_error);
|
||||
return $a_error;
|
||||
|
||||
// verify all VAT
|
||||
///@var $a_error : array of error_code see check_company_error
|
||||
$a_error = array();
|
||||
$a_error['general'] = parent::verify();
|
||||
$a_error['operation']=[];
|
||||
|
||||
// verify that all needed data in PARAMETER are valid
|
||||
$a_error['company'] = $this->check_company_data();
|
||||
$a_error['customer'] = $this->check_customer_data($this->data['customer']['card_id']);
|
||||
return $a_error;
|
||||
}
|
||||
/**
|
||||
* @brief set the PDF
|
||||
|
|
@ -102,17 +108,16 @@ class InvoiceUBL21 extends XMLInvoice {
|
|||
* @brief check that mandatory info are saved in the DB for company (seller)
|
||||
* @param $a_error (array) array of errors, empty if nothing found
|
||||
*/
|
||||
function check_company_data(&$a_error) {
|
||||
function check_company_data() {
|
||||
// var $a_error (array) contains the errors for the company
|
||||
$a_error=array();
|
||||
$company = $this->load_noalyss_parameter();
|
||||
foreach (InvoiceUBL21::EXTRA_PARAMETER as $item) {
|
||||
if (!isset($company[$item]) || $company[$item] == '') {
|
||||
if (!isset($company[$item]) || trim($company[$item]) == '') {
|
||||
$a_error[]=$item;
|
||||
}
|
||||
}
|
||||
if (count($a_error) == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return $a_error;
|
||||
}
|
||||
/**
|
||||
* @brief check that mandatory info are saved in the DB for customer
|
||||
|
|
@ -120,26 +125,49 @@ class InvoiceUBL21 extends XMLInvoice {
|
|||
* @param $a_error (array) array of errors, empty if nothing found
|
||||
* @todo : country code au lieu de country !!
|
||||
*/
|
||||
function check_customer_data($customer_id,&$a_error){
|
||||
$card=new \Fiche($this->cn,$customer_id);
|
||||
$a_needed=[ATTR_DEF_NAME=>'CUST_NAME'
|
||||
,ATTR_DEF_ADRESS=>'CUST_ADDR'
|
||||
,ATTR_DEF_POSTCODE=>'CUST_POSTCD'
|
||||
,ATTR_DEF_CITY=>'CUST_CITY'
|
||||
,ATTR_DEF_COUNTRY_CODE=>'CUST_CDCOUNTRY'
|
||||
,ATTR_DEF_NUMTVA=>'CUST_VAT'
|
||||
,ATTR_DEF_PEPPOLID=>'CUST_PEPPOLID'
|
||||
function check_customer_data($customer_id){
|
||||
$a_error=array();
|
||||
$a_needed=[ATTR_DEF_NAME=>'name'
|
||||
,ATTR_DEF_ADRESS=>'street'
|
||||
,ATTR_DEF_POSTCODE=>'postalzone'
|
||||
,ATTR_DEF_CITY=>'city'
|
||||
,ATTR_DEF_COUNTRY_CODE=>'country'
|
||||
,ATTR_DEF_NUMTVA=>'customer_id'
|
||||
,ATTR_DEF_PEPPOLID=>'endpoint_id'
|
||||
];
|
||||
|
||||
foreach ($a_needed as $item=>$value) {
|
||||
if (\noalyss_trim($card->get_attribute($item))=="") {
|
||||
$a_error[]=$value;
|
||||
if ( $this->data['customer'][$value]=="") {
|
||||
$a_error[]=$value;
|
||||
}
|
||||
}
|
||||
|
||||
return $a_error;
|
||||
}
|
||||
/**
|
||||
* @brief check that the VAT is using a PEPPOL Code
|
||||
*/
|
||||
function check_VAT()
|
||||
{
|
||||
$a_error=array();
|
||||
$nb_operation=count($this->data['operation']);
|
||||
for ($i=0;$i <$nb_operation;$i++)
|
||||
{
|
||||
if ( $this->data['operation'][$i]['vat_code'] == "" ) {
|
||||
$card=new \Fiche(
|
||||
$this->cn
|
||||
,$this->data['operation'][$i]['card_id']
|
||||
);
|
||||
$tva= \Acc_Tva::build($this->cn, $this->data['operation'][$i]['vat_id']);
|
||||
$a_error[]=sprintf(_("%s : %s code TVA pour PEPPOL non configuré code TVA [ %s %s ]")
|
||||
, $i
|
||||
, $card->get_quick_code()
|
||||
,$tva->tva_id
|
||||
,$tva->tva_code
|
||||
);
|
||||
}
|
||||
}
|
||||
if (count($a_error) == 0) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
return $a_error;
|
||||
}
|
||||
/**
|
||||
* @brief transform an operation ($jr_id) into an array, which contains
|
||||
|
|
@ -174,7 +202,7 @@ class InvoiceUBL21 extends XMLInvoice {
|
|||
$VAT_SubTotal=array();
|
||||
for ($i=0;$i < $nb_operation;$i++) {
|
||||
$acc_tva=\Acc_TVA::build($this->cn,$result['operation'][$i]['vat_id'] );
|
||||
$percent = bcmul($acc_tva->tva_rate,100);
|
||||
$percent = bcmul($acc_tva->tva_rate,100,2);
|
||||
// subtotal for VAT
|
||||
$n = find_idx($VAT_SubTotal,'percent',$percent);
|
||||
if ($n == -1 ) {
|
||||
|
|
@ -213,7 +241,8 @@ class InvoiceUBL21 extends XMLInvoice {
|
|||
$customer=$this->createElement('cac:AccountingCustomerParty');
|
||||
$customer_party=$customer->appendChild($this->createElement('cac:Party'));
|
||||
///@todo EndPointID doit être dans les paramètres (voir upgrade.sql)
|
||||
$customer_party->appendChild($this->createElement('cbc:EndpointID',"ERROR"))->setAttribute('schemeID', 9956);
|
||||
$customer_party->appendChild($this->createElement('cbc:EndpointID',$this->data['customer']['endpoint_id']))
|
||||
->setAttribute('schemeID', 9925);
|
||||
$party_name=$this->createElement('cac:PartyName');
|
||||
$party_name->appendChild($this->createElement("cbc:Name", $this->data['customer']['name']));
|
||||
$customer_party->appendChild($party_name);
|
||||
|
|
@ -222,9 +251,10 @@ class InvoiceUBL21 extends XMLInvoice {
|
|||
$postal_address->appendChild($this->createElement("cbc:CityName", $this->data['customer']['city']));
|
||||
$postal_address->appendChild($this->createElement("cbc:PostalZone", $this->data['customer']['postalzone']));
|
||||
///@todo customer = countryCode doit être dans les paramètres (voir upgrade.sql)
|
||||
$country_code ="ERROR";
|
||||
$country_code =$this->data['customer']['country'];
|
||||
$country=$postal_address->appendChild($this->createElement("cac:Country"));
|
||||
$country->appendChild($this->createElement('cbc:IdentificationCode',$country_code??"ERROR:COUNTRY_CODE"));
|
||||
|
||||
$country->appendChild($this->createElement('cbc:IdentificationCode',$country_code));
|
||||
$postal_address->appendChild($country);
|
||||
|
||||
// Tax Schem
|
||||
|
|
@ -290,7 +320,7 @@ class InvoiceUBL21 extends XMLInvoice {
|
|||
|
||||
$supplier=$this->createElement('cac:AccountingSupplierParty');
|
||||
$supplier_party=$supplier->appendChild($this->createElement('cac:Party'));
|
||||
$supplier_party->appendChild($this->createElement('cbc:EndpointID',$company['COMPANY_UBL_ID']??"ERROR"))->setAttribute('schemeID', 9956);
|
||||
$supplier_party->appendChild($this->createElement('cbc:EndpointID',$company['COMPANY_UBL_ID']))->setAttribute('schemeID', 9925);
|
||||
$party_name=$this->createElement('cac:PartyName');
|
||||
$party_name->appendChild($this->createElement('cbc:Name', $this->data['supplier']['name']));
|
||||
$supplier_party->appendChild($party_name);
|
||||
|
|
@ -360,20 +390,20 @@ class InvoiceUBL21 extends XMLInvoice {
|
|||
function build_taxTotal()
|
||||
{
|
||||
$taxTotal=$this->createElement("cac:TaxTotal");
|
||||
$taxTotal->appendChild($this->createElement('cbc:TaxAmount',$this->data['TaxAmount']))
|
||||
$taxTotal->appendChild($this->createElement('cbc:TaxAmount',sprintf("%.2f",$this->data['TaxAmount'])))
|
||||
->setAttribute("currencyID",$this->data['currency']);
|
||||
// for subTotal
|
||||
$subTotal=$this->data['subTotalVAT'];
|
||||
$nb_sub=count($subTotal);
|
||||
for ($i=0;$i<$nb_sub;$i++) {
|
||||
$subTotalXML=$this->createElement("cac:TaxSubtotal");
|
||||
$subTotalXML->appendChild($this->createElement('cbc:TaxableAmount',$subTotal[$i]['amount']))
|
||||
$subTotalXML->appendChild($this->createElement('cbc:TaxableAmount',sprintf("%.2f",$subTotal[$i]['amount'])))
|
||||
->setAttribute("currencyID", $this->data['currency']);
|
||||
$subTotalXML->appendChild($this->createElement('cbc:TaxAmount',$subTotal[$i]['vat']))
|
||||
$subTotalXML->appendChild($this->createElement('cbc:TaxAmount',sprintf("%.2f",$subTotal[$i]['vat'])))
|
||||
->setAttribute("currencyID",$this->data['currency']);
|
||||
$taxCategory=$this->createElement("cac:TaxCategory");
|
||||
$taxCategory->appendChild($this->createElement("cbc:ID","S"));
|
||||
$taxCategory->appendChild($this->createElement("cbc:Percent",$subTotal[$i]['percent']));
|
||||
$taxCategory->appendChild($this->createElement("cbc:Percent",sprintf("%.2f",$subTotal[$i]['percent'])));
|
||||
$taxScheme=$this->createElement("cac:TaxScheme");
|
||||
$taxScheme->appendChild($this->createElement("cbc:ID", "VAT"));
|
||||
$taxCategory->appendChild($taxScheme);
|
||||
|
|
@ -398,13 +428,13 @@ class InvoiceUBL21 extends XMLInvoice {
|
|||
function build_legalMonetaryTotal()
|
||||
{
|
||||
$result=$this->createElement('cac:LegalMonetaryTotal' );
|
||||
$result->appendChild($this->createElement("cbc:LineExtensionAmount",$this->data['LineExtensionAmount']))
|
||||
$result->appendChild($this->createElement("cbc:LineExtensionAmount",sprintf("%.2f",$this->data['LineExtensionAmount'])))
|
||||
->setAttribute("currencyID",$this->data['currency']);
|
||||
$result->appendChild($this->createElement("cbc:TaxExclusiveAmount",$this->data['TaxExclusiveAmount']))
|
||||
$result->appendChild($this->createElement("cbc:TaxExclusiveAmount",sprintf("%.2f",$this->data['TaxExclusiveAmount'])))
|
||||
->setAttribute("currencyID",$this->data['currency']);
|
||||
$result->appendChild($this->createElement("cbc:TaxInclusiveAmount",$this->data['TaxInclusiveAmount']))
|
||||
$result->appendChild($this->createElement("cbc:TaxInclusiveAmount",sprintf("%.2f",$this->data['TaxInclusiveAmount'])))
|
||||
->setAttribute("currencyID", $this->data['currency'] );
|
||||
$result->appendChild($this->createElement("cbc:PayableAmount",$this->data['PayableAmount']))
|
||||
$result->appendChild($this->createElement("cbc:PayableAmount",sprintf("%.2f",$this->data['PayableAmount'])))
|
||||
->setAttribute("currencyID", $this->data['currency'] );
|
||||
return $result;
|
||||
|
||||
|
|
@ -439,29 +469,42 @@ class InvoiceUBL21 extends XMLInvoice {
|
|||
|
||||
$result=$this->createElement('cac:InvoiceLine');
|
||||
$row=$this->data["operation"][$i];
|
||||
$amount=sprintf("%.2f",abs($row['price']));
|
||||
|
||||
$result->appendChild($this->createElement("cbc:ID", $i));
|
||||
///@todo , les unités de quantités devraient être ajoutés à NOALYSS
|
||||
/// il faut adapter les fiches
|
||||
$amount=sprintf("%.2f",abs($row['price']));
|
||||
$result->appendChild(
|
||||
$this->createElement("cbc:InvoicedQuantity", $row['quantity']))
|
||||
$this->createElement("cbc:InvoicedQuantity", sprintf("%.2f",$row['quantity'])))
|
||||
->setAttribute("unitCode", $row["code_quantity"]);
|
||||
$result->appendChild($this->createElement("cbc:LineExtensionAmount", $row['price']))
|
||||
$result->appendChild($this->createElement("cbc:LineExtensionAmount", $amount))
|
||||
->setAttribute("currencyID",$this->data['currency']);
|
||||
// @IMPORTANT@ Impossible de connaitre la remise par article, non prévu dans NOALYSS ALLOWANCE
|
||||
if ( $row['price'] < 0 ) {
|
||||
$allowanceCharge=$this->createElement("cac:AllowanceCharge");
|
||||
$allowanceCharge->appendChild($this->createElement("cbc:ChargeIndicator","false"));
|
||||
$allowanceCharge->appendChild($this->createElement("cbc:Amount",sprintf("%.2f",$amount)));
|
||||
$result->appendChild($allowanceCharge);
|
||||
}
|
||||
|
||||
// ITEM
|
||||
$item=$this->createElement("cac:Item");
|
||||
$card=new \Fiche($this->cn,$row['card_id']);
|
||||
$item->appendChild($this->createElement("cbc:Name", $card->get_attribute(ATTR_DEF_NAME)));
|
||||
$item->appendChild($this->createElement("cbc:Description", $card->get_attribute(ATTR_DEF_NAME)));
|
||||
$item->appendChild($this->createElement("cbc:Name", $card->get_attribute(ATTR_DEF_QUICKCODE)));
|
||||
$classifiedTaxCat=$this->createElement("cac:ClassifiedTaxCategory");
|
||||
///@todo cbc:ID S = standard rate et que se passe-t'il pour l'autoliquidation ???
|
||||
/// Il faut ajouter dans TVA_RATE , un code pour la TVA, voir TVA_RATE.TVA_PEPPOL_CODE
|
||||
$classifiedTaxCat->appendChild($this->createElement("cbc:ID", "S"));
|
||||
$classifiedTaxCat->appendChild($this->createElement("cbc:Percent", $row['vat_percent']));
|
||||
|
||||
//cbc:ID S = standard rate
|
||||
/// see TVA_RATE.TVA_PEPPOL_CODE & C0TVA
|
||||
$classifiedTaxCat->appendChild($this->createElement("cbc:ID", $row['vat_code']));
|
||||
$classifiedTaxCat->appendChild($this->createElement("cbc:Percent", sprintf("%.2f",$row['vat_percent'])));
|
||||
|
||||
$tax_scheme=$this->createElement('cac:TaxScheme');
|
||||
$tax_scheme->appendChild($this->createElement("cbc:ID", "VAT"));
|
||||
$classifiedTaxCat->appendChild($tax_scheme);
|
||||
$item->appendChild($classifiedTaxCat);
|
||||
$result->appendChild($item);
|
||||
$price=$result->appendChild($this->createElement("cac:Price"));
|
||||
$price->appendChild($this->createElement("cbc:PriceAmount", $row['price']))
|
||||
$price->appendChild($this->createElement("cbc:PriceAmount",sprintf("%.2f",$amount)))
|
||||
->setAttribute("currencyID",$this->data['currency']);
|
||||
$result->appendChild($price);
|
||||
|
||||
|
|
@ -470,6 +513,7 @@ class InvoiceUBL21 extends XMLInvoice {
|
|||
}
|
||||
/**
|
||||
* @brief Insert a PDF in the XML
|
||||
* the document type is not due for BELGIUM
|
||||
@code
|
||||
<cac:AdditionalDocumentReference>
|
||||
<cbc:ID>P01</cbc:ID>
|
||||
|
|
@ -511,7 +555,6 @@ class InvoiceUBL21 extends XMLInvoice {
|
|||
|
||||
$result=$this->createElement("cac:AdditionalDocumentReference");
|
||||
$id=$this->createElement("cbc:ID",$i);
|
||||
$documentType=$this->createElement("cbc:DocumentType",'application/pdf');
|
||||
$document_description=$this->createElement("cbc:DocumentDescription",'INVOICE PDF');
|
||||
|
||||
// PDF in base64
|
||||
|
|
@ -523,7 +566,9 @@ class InvoiceUBL21 extends XMLInvoice {
|
|||
$attachment->appendChild($embeddedDocument);
|
||||
|
||||
$result->appendChild($id);
|
||||
$result->appendChild($documentType);
|
||||
// ERROR FOR BELGIUM !
|
||||
// $documentType=$this->createElement("cbc:DocumentType",'application/pdf');
|
||||
// $result->appendChild($documentType);
|
||||
$result->appendChild($document_description);
|
||||
$result->appendChild($attachment);
|
||||
|
||||
|
|
@ -554,7 +599,7 @@ class InvoiceUBL21 extends XMLInvoice {
|
|||
}
|
||||
$root->appendChild($this->createElement('cbc:InvoiceTypeCode',380));
|
||||
$root->appendChild($this->createElement('cbc:DocumentCurrencyCode',$this->data['currency']));
|
||||
|
||||
$root->appendChild($this->createElement('cbc:BuyerReference',"NOALYSS"));
|
||||
/**
|
||||
* insert PDF in the XML
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
<?php
|
||||
namespace Noalyss\XMLDocument;
|
||||
|
||||
use Noalyss\Utility;
|
||||
//use Noalyss\Utility;
|
||||
/*
|
||||
* This file is part of NOALYSS.
|
||||
*
|
||||
|
|
@ -68,6 +68,7 @@ use Noalyss\Utility;
|
|||
[vat_id] => 1
|
||||
[vat_reversed] => 0.0000
|
||||
[code_quantity]=> EA
|
||||
[vat_code]=> Code VAT for PEPPOL (S,K,...)
|
||||
)
|
||||
|
||||
[1] => Array
|
||||
|
|
@ -79,6 +80,7 @@ use Noalyss\Utility;
|
|||
[vat_id] => 1
|
||||
[vat_reversed] => 0.0000
|
||||
[code_quantity]=> EA
|
||||
[vat_code]=> Code VAT for PEPPOL (S,K,...)
|
||||
)
|
||||
|
||||
[2] => Array
|
||||
|
|
@ -90,6 +92,7 @@ use Noalyss\Utility;
|
|||
[vat_id] => 5
|
||||
[vat_reversed] => 15.1200
|
||||
[code_quantity]=> EA
|
||||
[vat_code]=> Code VAT for PEPPOL (S,K,...)
|
||||
)
|
||||
|
||||
)
|
||||
|
|
@ -165,43 +168,13 @@ abstract class XMLInvoice extends \DOMDocument
|
|||
$result=array();
|
||||
$result["id"]= $operation->det->jr_pj_number;
|
||||
$result["issue_date"]=$operation->det->jr_date;
|
||||
$result["due_date"]=$operation->det->jr_ech;
|
||||
$result["due_date"]=($operation->det->jr_ech=="")?$operation->det->jr_date:$operation->det->jr_ech;
|
||||
// supplier
|
||||
$result['supplier']=array();
|
||||
$result['supplier']['name']=$g_parameter->MY_NAME;
|
||||
$result['supplier']['street']=$g_parameter->MY_STREET;
|
||||
$result['supplier']['postalzone']=$g_parameter->MY_POSTCODE;
|
||||
$result['supplier']['city']=$g_parameter->MY_CITY;
|
||||
$result['supplier']['country']=$g_parameter->MY_COUNTRY;
|
||||
$result['supplier']['supplier_id']=$g_parameter->MY_TVA;
|
||||
// official name of the company
|
||||
$result['supplier']['registration_name']=$g_parameter->MY_NAME;
|
||||
// official ID , like VAT
|
||||
$result['supplier']['supplier_id']=str_replace([" ",".","-","/"],"" ,$g_parameter->MY_TVA);
|
||||
//@todo
|
||||
//Autre parametre comme email dans Parameter_Extra_SQL
|
||||
//
|
||||
//
|
||||
// == $result['supplier']['supplier_email']=$g_parameter->;
|
||||
//@todo TESTER S'IL Y A QQ'CHOSE DE VENDU !
|
||||
$result['supplier']=$this->fill_supplier();
|
||||
|
||||
|
||||
//customer
|
||||
$customer=new \Fiche($this->cn,$operation->det->array[0]['qs_client']);
|
||||
$result['customer']=array();
|
||||
$result['customer']['card_id']=$operation->det->array[0]['qs_client'];
|
||||
$result['customer']['name']=$customer->get_attribute(ATTR_DEF_NAME);
|
||||
$result['customer']['street']=$customer->get_attribute(ATTR_DEF_ADRESS);
|
||||
$result['customer']['postalzone']=$customer->get_attribute(ATTR_DEF_POSTCODE);
|
||||
$result['customer']['city']=$customer->get_attribute(ATTR_DEF_CITY);
|
||||
|
||||
// find country_code of this card
|
||||
|
||||
$result['customer']['country']=$customer->get_attribute(ATTR_DEF_COUNTRY);
|
||||
|
||||
$result['customer']['customer_id']=str_replace([" ",".","-","/"],"" ,$customer->get_attribute(ATTR_DEF_NUMTVA));
|
||||
// official name of the company
|
||||
$result['customer']['registration_name']=$customer->get_attribute(ATTR_DEF_NAME);
|
||||
// official ID , like VAT
|
||||
$result['customer']['customer_id']=$customer->get_attribute(ATTR_DEF_NUMTVA);
|
||||
$result['customer']=$this->fill_customer($operation->det->array[0]['qs_client']);
|
||||
|
||||
// currency
|
||||
$result['currency']=$this->cn->get_value("select cr_code_iso from currency where id=$1"
|
||||
|
|
@ -228,6 +201,11 @@ abstract class XMLInvoice extends \DOMDocument
|
|||
|
||||
}
|
||||
$result['operation'][$i]['vat_id']=$operation->det->array[$i]['qs_vat_code'];
|
||||
// // tva code for PEPPOL
|
||||
// $x=$this->cn->get_value("select tva_peppol_code from tva_rate where tva_id=$1"
|
||||
// ,[ $result['operation'][$i]['vat_id']]);
|
||||
$result['operation'][$i]['vat_code']=($x=="")?"S":$x;
|
||||
|
||||
$result['operation'][$i]['vat_reversed']=$operation->det->array[$i]['qs_vat_sided'];
|
||||
}
|
||||
// retrieve currency
|
||||
|
|
@ -237,7 +215,7 @@ abstract class XMLInvoice extends \DOMDocument
|
|||
/**
|
||||
* @brief make an array of parameter_extra where pe_code as key and pe_value
|
||||
* as value
|
||||
* @return array
|
||||
* @return array keys : pe_code,pe_value
|
||||
*/
|
||||
function load_noalyss_parameter()
|
||||
{
|
||||
|
|
@ -257,15 +235,13 @@ abstract class XMLInvoice extends \DOMDocument
|
|||
abstract function make_xml($jr_id);
|
||||
/**
|
||||
* @brief check that mandatory info are saved in the DB for company (seller)
|
||||
* @param $a_error (array) array of errors, empty if nothing found
|
||||
*/
|
||||
abstract function check_company_data(&$a_error) ;
|
||||
abstract function check_company_data() ;
|
||||
/**
|
||||
* @brief check that mandatory info are saved in the DB for customer
|
||||
* @param $customer_id (int) card of the customer FICHE.F_ID
|
||||
* @param $a_error (array) array of errors, empty if nothing found
|
||||
*/
|
||||
abstract function check_customer_data($customer_id,&$a_error) ;
|
||||
abstract function check_customer_data($customer_id) ;
|
||||
/**
|
||||
* @brief create the invoice in the right format, with PDF if any
|
||||
* @param $operation_id (int) JRN.JR_ID
|
||||
|
|
@ -297,6 +273,118 @@ abstract class XMLInvoice extends \DOMDocument
|
|||
*/
|
||||
function verify()
|
||||
{
|
||||
return array();
|
||||
}
|
||||
/**
|
||||
* @brief retrieve data from customer and return it into an array
|
||||
* @param $card_id (int) FICHE.F_ID
|
||||
* @return array keys :
|
||||
* - name
|
||||
* - ,street
|
||||
* - ,postalzone
|
||||
* - ,city
|
||||
* - ,country
|
||||
* - ,customer_id => VAT Number
|
||||
* - , registration_name,
|
||||
* - card_id
|
||||
*/
|
||||
function fill_customer($card_id):array
|
||||
{
|
||||
$customer =new \Fiche($this->cn,$card_id);
|
||||
$result=array();
|
||||
$result['card_id']=$card_id;
|
||||
$result['name']=$customer->get_attribute(ATTR_DEF_NAME,0);
|
||||
$result['street']=$customer->get_attribute(ATTR_DEF_ADRESS,0);
|
||||
$result['postalzone']=$customer->get_attribute(ATTR_DEF_POSTCODE,0);
|
||||
$result['city']=$customer->get_attribute(ATTR_DEF_CITY,0);
|
||||
|
||||
// find country_code of this card
|
||||
$result['country']=$customer->get_attribute(ATTR_DEF_COUNTRY_CODE,0);
|
||||
|
||||
// official ID , like VAT
|
||||
$result['customer_id']=str_replace([" ",".","-","/"],"" ,$customer->get_attribute(ATTR_DEF_NUMTVA,0));
|
||||
// official name of the company
|
||||
$result['registration_name']=$customer->get_attribute(ATTR_DEF_NAME,0);
|
||||
$result['endpoint_id']=$customer->get_attribute(ATTR_DEF_PEPPOLID,0);
|
||||
return $result;
|
||||
}
|
||||
/**
|
||||
* @brief complete $this->data from $g_parameter (global variable) for
|
||||
* Noalyss_Folder_Parameter
|
||||
* @return array keys :
|
||||
* - name
|
||||
* - ,street
|
||||
* - ,postalzone
|
||||
* - ,city
|
||||
* - ,country
|
||||
* - supplier_id => VAT Number
|
||||
* - registration_name,
|
||||
*
|
||||
*/
|
||||
function fill_supplier():array
|
||||
{
|
||||
$a_parameter=$this->load_noalyss_parameter();
|
||||
$result=array();
|
||||
$result['name']=$a_parameter['MY_NAME'];
|
||||
$result['street']=$a_parameter['MY_STREET'];
|
||||
$result['postalzone']=$a_parameter['MY_POSTCODE'];
|
||||
$result['city']=$a_parameter['MY_CITY'];
|
||||
$result['country']=$a_parameter['MY_COUNTRY'];
|
||||
// official name of the company
|
||||
$result['registration_name']=$a_parameter['MY_NAME'];
|
||||
// official ID , like VAT
|
||||
$result['supplier_id']=str_replace([" ",".","-","/"],"" ,$a_parameter['MY_TVA']);
|
||||
$result['COUNTRY_CODE']=$a_parameter['COUNTRY_CODE']??"";
|
||||
$result['COMPANY_LEGAL_REGISTRATION']=$a_parameter['COMPANY_LEGAL_REGISTRATION']??"";
|
||||
$result['COMPANY_LEGAL_ENTITY']=$a_parameter['COMPANY_LEGAL_ENTITY']??"";
|
||||
$result['INVOICE_CONTACT_NAME']=$a_parameter['INVOICE_CONTACT_NAME']??"";
|
||||
$result['INVOICE_EMAIL_COMPANY']=$a_parameter['INVOICE_EMAIL_COMPANY']??"";
|
||||
$result['COMPANY_UBL_ID']=$a_parameter['COMPANY_UBL_ID']??"";
|
||||
return $result;
|
||||
}
|
||||
/**
|
||||
* @brief build operation from array
|
||||
* key :
|
||||
* - [e_march0] => Quick code of the item
|
||||
- [e_march0_label] => Label of item
|
||||
- [e_march0_price] => Unit Price
|
||||
- [e_quant0] => Quantity
|
||||
- [htva_march0] => Price w/0 VAT
|
||||
- [e_march0_tva_id] => Code VAT
|
||||
- [e_march0_tva_amount] => Amount VAT
|
||||
- [tva_march0] => Amount VAT (duplicate -> to remove)
|
||||
- [tvac_march0] => Total Amount Tax included
|
||||
* @param type $a_array
|
||||
* @return type
|
||||
*/
|
||||
function fill_operation_from_array($a_array)
|
||||
{
|
||||
$result=array();
|
||||
$http=new \HttpInput();
|
||||
$http->set_array($a_array);
|
||||
|
||||
$nb_item=$http->get_value("nb_item");
|
||||
for ($i=0;$i<$nb_item;$i++)
|
||||
{
|
||||
if ( $http->get_value("e_march{$i}_tva_id") == "")
|
||||
{
|
||||
continue;
|
||||
}
|
||||
$operation=array();
|
||||
$card=\Fiche::from_qcode($this->cn,trim($http->get_value("e_march{$i}")));
|
||||
$operation['card_id']=$card->id;
|
||||
$operation['quantity']=$http->get_value("e_quant{$i}");
|
||||
$operation['price']=$http->get_value("e_march{$i}_price");
|
||||
$operation['vat']=$http->get_value("tvac_march{$i}");
|
||||
$tva= \Acc_Tva::build($this->cn, $http->get_value("e_march{$i}_tva_id"));
|
||||
$operation['vat_id']=$tva->tva_id;
|
||||
$operation['vat_reversed']=($tva->tva_both_side==1)?$operation['vat']:0;
|
||||
$operation['vat_code']=$tva->tva_peppol_code;
|
||||
|
||||
$operation['code_quantity']=$card->get_attribute(ATTR_DEF_QUANTITY_TYPE,0);
|
||||
$operation['code_quantity']=($operation['code_quantity']=="")?"EA":$operation['code_quantity'];
|
||||
$result[$i]=$operation;
|
||||
}
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,7 +30,9 @@
|
|||
"label"=>"tva_label",
|
||||
"rate"=>"tva_rate",
|
||||
"comment"=>"tva_comment",
|
||||
"account"=>"tva_poste");
|
||||
"account"=>"tva_poste"
|
||||
tva_peppol_code
|
||||
* );
|
||||
|
||||
*/
|
||||
class Acc_Tva
|
||||
|
|
@ -42,7 +44,9 @@ class Acc_Tva
|
|||
"account"=>"tva_poste",
|
||||
"both_side"=>'tva_both_side',
|
||||
'tva_reverse_account'=>'tva_reverse_account',
|
||||
'tva_code'=>'tva_code');
|
||||
'tva_code'=>'tva_code',
|
||||
"tva_peppol_code"=>"tva_peppol_code"
|
||||
);
|
||||
public $tva_id,
|
||||
$tva_label,
|
||||
$tva_rate,
|
||||
|
|
@ -50,16 +54,18 @@ class Acc_Tva
|
|||
$tva_poste,
|
||||
$tva_both_side,
|
||||
$tva_code,
|
||||
$tva_reverse_account;
|
||||
$tva_reverse_account,
|
||||
$tva_peppol_code
|
||||
;
|
||||
|
||||
private $cn; //!< Database connection
|
||||
|
||||
private Tva_Rate_SQL $tva_rate_sql;
|
||||
|
||||
function __construct ($p_init,$p_tva_id=-1)
|
||||
function __construct (Database $cn,$p_tva_id=-1)
|
||||
{
|
||||
$this->cn=$p_init;
|
||||
$this->tva_rate_sql=new Tva_Rate_SQL($p_init,$p_tva_id);
|
||||
$this->cn=$cn;
|
||||
$this->tva_rate_sql=new Tva_Rate_SQL($cn,$p_tva_id);
|
||||
$this->tva_id=$p_tva_id;
|
||||
$this->tva_label=&$this->tva_rate_sql->tva_label;
|
||||
$this->tva_rate=&$this->tva_rate_sql->tva_rate;
|
||||
|
|
@ -68,6 +74,7 @@ class Acc_Tva
|
|||
$this->tva_both_side=&$this->tva_rate_sql->tva_both_side;
|
||||
$this->tva_code=&$this->tva_rate_sql->tva_code;
|
||||
$this->tva_reverse_account=&$this->tva_rate_sql->tva_reverse_account;
|
||||
$this->tva_peppol_code=&$this->tva_rate_sql->tva_peppol_code;
|
||||
|
||||
}
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -329,7 +329,7 @@ class Fiche
|
|||
* @param int $p_ad_id AD_ID from attr_def.ad_id
|
||||
* @param int $p_return 1 return NOTFOUND otherwise an empty string
|
||||
* @see constant.php
|
||||
* @return string
|
||||
* @return string
|
||||
* @note reread data from database and so it reset previous unsaved change
|
||||
*/
|
||||
function get_attribute($p_ad_id,$p_return=1)
|
||||
|
|
@ -1966,12 +1966,12 @@ class Fiche
|
|||
}
|
||||
/**
|
||||
* @brief create a card from a qcode and returns a card
|
||||
* @param string $p_qcode qcode of the card
|
||||
* @param $cn Database cnx
|
||||
* @param $p_qcode (string) qcode of the card
|
||||
*/
|
||||
static function from_qcode($p_qcode)
|
||||
static function from_qcode(Database $cn,string $p_qcode)
|
||||
{
|
||||
$cn=Dossier::connect();
|
||||
$card=new Card($cn);
|
||||
$card=new Fiche($cn);
|
||||
$card->get_by_qcode($p_qcode);
|
||||
return $card;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,6 +79,32 @@ if ( isset ($_POST['view_invoice'] ) )
|
|||
echo '<form class="print" enctype="multipart/form-data" method="post">';
|
||||
echo dossier::hidden();
|
||||
echo $Ledger->confirm($_POST );
|
||||
//----------------------------------------------------------------------------
|
||||
// Check that INVOICE can be generated
|
||||
// for e-invoice only
|
||||
//----------------------------------------------------------------------------
|
||||
if ($g_parameter->MY_INVOICE_FORMAT != 'BASIC')
|
||||
{
|
||||
$xmldocument= \Noalyss\XMLDocument\XMLInvoice::build_xmlinvoice($cn);
|
||||
$array=[];
|
||||
$array['supplier']=$xmldocument->fill_supplier();
|
||||
echo "customer ",$http->post("e_client");
|
||||
$customer=Fiche::from_qcode($cn,trim($http->post("e_client")));
|
||||
|
||||
$array['customer']=$xmldocument->fill_customer($customer->id);
|
||||
$array['operation']=$xmldocument->fill_operation_from_array($_POST);
|
||||
$array['due_date']=$http->post("e_ech");
|
||||
if ( $array['due_date'] == '')
|
||||
{
|
||||
$array['due_date']=$http->post("e_date");
|
||||
}
|
||||
/////////////////////////////////////////////////
|
||||
///@todo ajouter date échéance
|
||||
/////////////////////////////////////////////////
|
||||
$xmldocument->set_data($array);
|
||||
$xmldocument->display_error();
|
||||
}
|
||||
|
||||
echo HtmlInput::hidden('ac',$strac);
|
||||
$Ledger->input_extra_info();
|
||||
echo HtmlInput::submit("record", _("Enregistrement"), 'onClick="return verify_ca(\'\');"');
|
||||
|
|
@ -133,8 +159,8 @@ if ( isset($_POST['record']) )
|
|||
/* Save the attachment or generate doc */
|
||||
if (isset($_FILES['pj'])) {
|
||||
if (noalyss_strlentrim($_FILES['pj']['name']) != 0)
|
||||
$cn->save_receipt($seq);
|
||||
|
||||
{ $cn->save_receipt($seq);
|
||||
}
|
||||
else
|
||||
/* Generate an invoice and save it into the database */
|
||||
if (isset($_POST['gen_invoice']))
|
||||
|
|
@ -154,8 +180,10 @@ if ( isset($_POST['record']) )
|
|||
$xmldocument->build_data($Ledger->jr_id);
|
||||
$code_error = $xmldocument->verify() ;
|
||||
if ( ! empty( $code_error ) ) {
|
||||
echo "Impossible de générer facture : code error $code_error ";
|
||||
echo $xmldocument->get_message_error($code_error);
|
||||
echo "Impossible de générer facture : code error ";
|
||||
\Noalyss\Dbg::echo_var(1, '$code_error is ');
|
||||
\Noalyss\Dbg::echo_var(1, $code_error);
|
||||
// echo $xmldocument->get_message_error($code_error);
|
||||
}
|
||||
$pdf_filename=$acc_document->transform2pdf();
|
||||
|
||||
|
|
@ -188,7 +216,6 @@ if ( isset($_POST['record']) )
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
catch (\Exception $e) {
|
||||
if ( $e->getCode()==EXC_BALANCE)
|
||||
|
|
|
|||
|
|
@ -430,7 +430,8 @@ function noalyss_class_autoloader($class)
|
|||
"noalyss\otp"=>"lib/otp.class.php",
|
||||
'noalyss\xmldocument\xmlinvoice'=>'XMLDocument/XMLInvoice.php',
|
||||
'noalyss\xmldocument\facturx'=>'XMLDocument/FacturX.php',
|
||||
'noalyss\xmldocument\invoiceubl21'=>'XMLDocument/InvoiceUBL21.php'
|
||||
'noalyss\xmldocument\invoiceubl21'=>'XMLDocument/InvoiceUBL21.php',
|
||||
'noalyss\xmldocument\error_message'=>'XMLDocument/Error_Message.php'
|
||||
);
|
||||
if (isset ($aClass[$class])) {
|
||||
require_once NOALYSS_INCLUDE . "/" . $aClass[$class];
|
||||
|
|
|
|||
99
include/template/invoiceUBL21-display_error.php
Normal file
99
include/template/invoiceUBL21-display_error.php
Normal file
|
|
@ -0,0 +1,99 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of NOALYSS.
|
||||
*
|
||||
* NOALYSS is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* NOALYSS is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with NOALYSS; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
// Copyright Author Dany De Bontridder danydb@aevalys.eu 22/10/23
|
||||
|
||||
|
||||
/**
|
||||
* @file
|
||||
* @brief display errors for generating e-invoices, called from
|
||||
* invoiceUBL21-display-error.php
|
||||
*/
|
||||
//var @a_error (array) contains error
|
||||
|
||||
if ( count($a_error) == 0) return;
|
||||
|
||||
$error_message=new \Noalyss\XMLDocument\Error_Message($a_error);
|
||||
var_dump($a_error);
|
||||
?>
|
||||
<div class="notice" >
|
||||
<h3><?=_("Société")?></h3>
|
||||
<p class="text-muted">
|
||||
<?=_("A corriger dans COMPANY")?>
|
||||
</p>
|
||||
<?php
|
||||
//----------------------------------------------------------------------------
|
||||
// company
|
||||
//----------------------------------------------------------------------------
|
||||
$nb_error=count($a_error['company']);
|
||||
for ($i=0;$i<$nb_error;$i++):
|
||||
?>
|
||||
<div class="notice-item">
|
||||
<?=$error_message->get_message_error(code:$a_error['company'][$i],type:'company')?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
endfor;
|
||||
?>
|
||||
<h3><?=_("Client")?></h3>
|
||||
<p class="text-muted">
|
||||
<?=_("A corriger dans la fiche")?>
|
||||
</p>
|
||||
<?php
|
||||
//----------------------------------------------------------------------------
|
||||
// Customer
|
||||
//----------------------------------------------------------------------------
|
||||
$nb_error=count($a_error['customer']);
|
||||
for ($i=0;$i<$nb_error;$i++):
|
||||
?>
|
||||
<div class="notice-item">
|
||||
<?=$error_message->get_message_error(code:$a_error['customer'][$i],type:'customer')?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
endfor;
|
||||
?>
|
||||
<h3><?=_("Opération")?></h3>
|
||||
<p class="text-muted">
|
||||
<?=_("A corriger dans l'opération")?>
|
||||
</p>
|
||||
<?php
|
||||
if ( ! isset($this->data['due_date']) || $this->data['due_date']==""):
|
||||
?>
|
||||
<div class="notice-item">
|
||||
<?=_("Date échéance nécessaire")?>
|
||||
</div>
|
||||
<?php
|
||||
|
||||
endif;
|
||||
//----------------------------------------------------------------------------
|
||||
// Item VAT
|
||||
//----------------------------------------------------------------------------
|
||||
$a_vat_error=$this->check_VAT();
|
||||
$nb_error=count($a_vat_error);
|
||||
for ($i=0;$i<$nb_error;$i++):
|
||||
?>
|
||||
<div class="notice-item">
|
||||
<?=$a_vat_error[$i]?>
|
||||
</div>
|
||||
|
||||
<?php
|
||||
endfor;
|
||||
?>
|
||||
</div>
|
||||
Loading…
Add table
Add a link
Reference in a new issue