noalyss Version-10
NOALYSS : serveur de comptabilité et ERP (2002)
Loading...
Searching...
No Matches
facturx.class.php
Go to the documentation of this file.
1<?php
2namespace Noalyss\XMLDocument;
3/*
4 * This file is part of NOALYSS.
5 *
6 * NOALYSS is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 2 of the License, or
9 * (at your option) any later version.
10 *
11 * NOALYSS is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with NOALYSS; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19*/
20// Copyright Author Dany De Bontridder danydb@aevalys.eu 22/10/23
21
22use horstoeko\zugferd\codelists\ZugferdCountryCodes;
23use horstoeko\zugferd\codelists\ZugferdCurrencyCodes;
24use horstoeko\zugferd\codelists\ZugferdElectronicAddressScheme;
25use horstoeko\zugferd\codelists\ZugferdInvoiceType;
26use horstoeko\zugferd\codelists\ZugferdReferenceCodeQualifiers;
27use horstoeko\zugferd\codelists\ZugferdUnitCodes;
28use horstoeko\zugferd\codelists\ZugferdVatCategoryCodes;
29use horstoeko\zugferd\codelists\ZugferdVatTypeCodes;
30use horstoeko\zugferd\ZugferdDocumentBuilder;
31use horstoeko\zugferd\ZugferdProfiles;
32
33/**
34 * @file
35 * @brief FacturX French / German Standard for invoicing
36 */
37
38/**
39 * @class FacturX
40 * @brief FacturX French / German Standard for invoicing
41 */
42class FacturX extends XMLInvoice
43{
45 "INVOICE_EMAIL_COMPANY"
46 , 'INVOICE_CONTACT_NAME'
47 , 'COMPANY_LEGAL_ENTITY'
48 , 'COMPANY_LEGAL_REGISTRATION'
49 , 'COMPANY_BANK_IBAN'
50 , 'COMPANY_BANK_BIC'
51 , 'MY_NAME'
52 , 'MY_STREET'
53 , 'MY_CITY'
54 , 'MY_COUNTRY_CODE'
55 , 'MY_TVA'
56 ,'SIREN'
57 // ,'SIRET'
58 ];
59
60 protected $pdf_filename;
61
62 function build_data($jr_id): array {
63 $this->data=parent::build_data($jr_id);
64 return $this->data;
65 }
66 /**
67 * @brief check that mandatory info are saved in the DB
68 * @param $a_error (array) array of errors, empty if nothing found
69 */
71 {
72 $a_error=array();
73 $company = $this->load_noalyss_parameter();
74 foreach (FacturX::EXTRA_PARAMETER as $item) {
75 if (!isset($company[$item]) || trim($company[$item]) == '') {
76 $a_error[]=$item;
77 }
78 }
79 return $a_error;
80 }
81 /**
82 * @brief check that mandatory info are saved in the DB for customer
83 */
85 $a_error=array();
86 $a_needed=[ATTR_DEF_NAME=>'name'
87 ,ATTR_DEF_ADRESS=>'street'
88 ,ATTR_DEF_POSTCODE=>'postalzone'
89 ,ATTR_DEF_CITY=>'city'
90 ,ATTR_DEF_COUNTRY_CODE=>'country'
91 ,ATTR_DEF_NUMTVA=>'customer_vat_id'
92 ];
93
94 foreach ($a_needed as $item=>$value) {
95 if ( $this->data['customer'][$value]=="") {
96 $a_error[]=$value;
97 }
98 }
99
100 return $a_error;
101 }
102
103 /**
104 * @brief create an XML invoice(Factur-X) based on JRN.JR_ID operation
105 * @parameter $jr_id (int) operation JRN.JR_ID operation
106 *@return XML String
107 *@note SIREN or SIRET is mandatory
108 */
109 function make_xml($jr_id)
110 {
111 $this->data = $this->build_data($jr_id);
112 $company = $this->load_noalyss_parameter();
113 // var_dump($this->data);
114 $documentBuilder = ZugferdDocumentBuilder::createNew(ZugferdProfiles::PROFILE_EN16931);
115 $documentBuilder->setDocumentInformation(
116 $this->data['id']
117 ,"380"
118 ,\DateTime::createFromFormat( 'Y-m-d',$this->data["issue_date"])
119 , $this->data['currency']
120 );
121
122 $documentBuilder->addDocumentPaymentTerm(
123 sprintf("IBAN %s",$company['COMPANY_BANK_IBAN'])
124 ,\DateTime::createFromFormat( 'Y-m-d',$this->data["due_date"])
125 , $this->data['info']['communication']
126 );
127 //------------------------------------------------
128 // SELLER
129 //------------------------------------------------
130 $documentBuilder->setDocumentSeller($company['MY_NAME'], );
131 $documentBuilder->addDocumentSellerGlobalId($company['SIREN'], '0009');
132 $documentBuilder->addDocumentSellerTaxNumber($company['MY_TVA']);
133 $documentBuilder->addDocumentSellerVATRegistrationNumber($company['MY_TVA']);
134 $documentBuilder->setDocumentSellerAddress(
135 $company['MY_STREET']
136 , '', ''
137 , $company['MY_POSTCODE']
138 , $company['MY_CITY']
139 ,$company['MY_COUNTRY_CODE']);
140
141 $documentBuilder->setDocumentSellerCommunication(ZugferdElectronicAddressScheme::UNECE3155_EM
142 , $company["INVOICE_EMAIL_COMPANY"]);
143
144 //------------------------------------------------
145 // BUYER
146 //------------------------------------------------
147
148 $documentBuilder->setDocumentBuyer($this->data['customer']['name'], $this->data['customer']['customer_vat_id']);
149 $documentBuilder->setDocumentBuyerAddress(
150 $this->data['customer']['street']
151 , ''
152 , ''
153 , $this->data['customer']['postalzone']
154 , $this->data['customer']['city']
155 , $this->data['customer']['country']
156 );
157// $documentBuilder->setDocumentBuyerContact('H. Meier', 'Einkauf', '+49-333-4444444', '+49-333-5555555', 'hm@kunde.de');
158// $documentBuilder->setDocumentBuyerCommunication(ZugferdElectronicAddressScheme::UNECE3155_EM, 'purchase@kunde.de');
159
160 $documentBuilder->setDocumentBuyerOrderReferencedDocument($this->data['info']['order']);
161
162 //------------------------------------------------
163 // Item & total
164 //------------------------------------------------
165
166 $base=0;$vat=0;
167 $nb=count($this->data['operation']);
168
169 for ($i=0;$i < $nb;$i++) {
170 $documentBuilder->addNewPosition($i+1);
171 $documentBuilder->setDocumentPositionProductDetails($this->data['operation'][$i]['qcode']
172 ,$this->data['operation'][$i]['name']
173 ,$this->data['operation'][$i]['description']
174 );
175 $documentBuilder->setDocumentPositionNetPrice($this->data['operation'][$i]['price']);
176 $documentBuilder->setDocumentPositionQuantity($this->data['operation'][$i]['quantity']
177 ,$this->data['operation'][$i]['code_quantity']
178 );
179 $documentBuilder->addDocumentPositionTax(
180 $this->data['operation'][$i]['vat_code']
181 , ZugferdVatTypeCodes::VALUE_ADDED_TAX
182 , bcmul($this->data['operation'][$i]['vat_rate'],100,2)
183 );
184 $documentBuilder->setDocumentPositionLineSummation($this->data['operation'][$i]['price']);
185
186
187 $base=bcadd($base,$this->data['operation'][$i]['price'],2);
188 $vat=bcadd($vat,$this->data['operation'][$i]['vat'],2);
189 $vat=bcsub($vat,$this->data['operation'][$i]['vat_reversed'],2);
190 }
191 $tt = bcadd($base,$vat,2);
192 //------------------------------------------------
193 // VAT Detail
194 //------------------------------------------------
195 $subTotal=$this->data['subTotalVAT'];
196 $nb_sub=count($subTotal);
197 for ($i=0;$i<$nb_sub;$i++)
198 {
199 $documentBuilder->addDocumentTax(
200 $subTotal[$i]["vat_code"]
201 , ZugferdVatTypeCodes::VALUE_ADDED_TAX
202 ,sprintf("%.2f",$subTotal[$i]['amount'])
203 , sprintf("%.2f",$subTotal[$i]['vat'])
204 , sprintf("%.2f",$subTotal[$i]['percent'])
205 );
206 }
207 //------------------------------------------------
208 // Total summary
209 //------------------------------------------------
210 $documentBuilder->setDocumentSummation(
211 sprintf("%.2f",$this->data['TaxInclusiveAmount'])
212 , sprintf("%.2f",$this->data['PayableAmount'])
213 , sprintf("%.2f",$this->data['TaxExclusiveAmount'])
214 , 0.0
215 , 0.0
216 , sprintf("%.2f",$this->data['LineExtensionAmount'])
217 , sprintf("%.2f",(bcsub($this->data['TaxInclusiveAmount'],
218 $this->data['TaxExclusiveAmount'],
219 2)
220 )
221 )
222 , 0
223 );
224
225
226 return $documentBuilder;
227
228
229 }
230 /**
231 * @brief create the invoice in the right format
232 * @param $operation_id (int) JRN.JR_ID
233 * @return string PDF Invoice including the XML
234 */
236 $documentBuilder= $this->make_xml($operation_id);
237
238 $invoice = \horstoeko\zugferd\ZugferdDocumentPdfBuilder::fromPdfFile($documentBuilder, $this->pdf_filename);
239 $invoice->generateDocument();
240 $invoice->saveDocument($this->pdf_filename."-new.pdf");
241 return $invoice->downloadString();
242 }
243
244 /**
245 * @brief check that all the data are correct
246 * @returns empty arry : no errors, array with error code
247 * @see get_message_error
248 */
249 public function verify()
250 {
251 // verify all VAT
252 ///@var $a_error : array of error_code see check_company_error
253 $a_error = array();
254 $a_error['general'] = [];
255 $a_error['operation']=[];
256
257 // verify that all needed data in PARAMETER are valid
258 $a_error['company'] = $this->check_company_data();
259 $a_error['customer'] = $this->check_customer_data();
260
261 return $a_error;
262 }
263 function check_VAT()
264 {
265 return array();
266 }
267
268}
$base
FacturX French / German Standard for invoicing.
check_company_data()
check that mandatory info are saved in the DB
make_xml($jr_id)
create an XML invoice(Factur-X) based on JRN.JR_ID operation @parameter $jr_id (int) operation JRN....
check_VAT()
check that the VAT is using a PEPPOL Code
check_customer_data()
check that mandatory info are saved in the DB for customer
create_invoice($operation_id)
create the invoice in the right format
build_data($jr_id)
transform an operation ($jr_id) into an array, which contains needed information for making an e-invo...
Mother class for e-invoice.
$jr_id
$data (Array) data retrieve from DB
load_noalyss_parameter()
make an array of parameter_extra where pe_code as key and pe_value as value
const ATTR_DEF_ADRESS
Definition constant.php:230
const ATTR_DEF_NUMTVA
Definition constant.php:229
const ATTR_DEF_NAME
Definition constant.php:223
const ATTR_DEF_COUNTRY_CODE
Definition constant.php:255
const ATTR_DEF_POSTCODE
Definition constant.php:231
const ATTR_DEF_CITY
Definition constant.php:236