dolibarr  9.0.0
commondocgenerator.class.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2003-2005 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3  * Copyright (C) 2004-2010 Laurent Destailleur <eldy@users.sourceforge.net>
4  * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
5  * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
6  * Copyright (C) 2015 Marcos García <marcosgdf@gmail.com>
7  * Copyright (C) 2016 Charlie Benke <charlie@patas-monkey.com>
8  * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
9  *
10  * This program is free software; you can redistribute it and/or modify
11  * it under the terms of the GNU General Public License as published by
12  * the Free Software Foundation; either version 3 of the License, or
13  * (at your option) any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18  * GNU General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program. If not, see <http://www.gnu.org/licenses/>.
22  * or see http://www.gnu.org/
23  */
24 
35 abstract class CommonDocGenerator
36 {
40  public $error='';
41 
45  public $errors = array();
46 
50  protected $db;
51 
52 
58  public function __construct($db)
59  {
60  $this->db = $db;
61  }
62 
63 
64  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
72  function get_substitutionarray_user($user,$outputlangs)
73  {
74  // phpcs:enable
75  global $conf;
76 
77  $logotouse=$conf->user->dir_output.'/'.get_exdir($user->id, 2, 0, 1, $user, 'user').'/'.$user->photo;
78 
79  return array(
80  'myuser_lastname'=>$user->lastname,
81  'myuser_firstname'=>$user->firstname,
82  'myuser_fullname'=>$user->getFullName($outputlangs,1),
83  'myuser_login'=>$user->login,
84  'myuser_phone'=>$user->office_phone,
85  'myuser_address'=>$user->address,
86  'myuser_zip'=>$user->zip,
87  'myuser_town'=>$user->town,
88  'myuser_country'=>$user->country,
89  'myuser_country_code'=>$user->country_code,
90  'myuser_state'=>$user->state,
91  'myuser_state_code'=>$user->state_code,
92  'myuser_fax'=>$user->office_fax,
93  'myuser_mobile'=>$user->user_mobile,
94  'myuser_email'=>$user->email,
95  'myuser_logo'=>$logotouse,
96  'myuser_job'=>$user->job,
97  'myuser_web'=>'' // url not exist in $user object
98  );
99  }
100 
101 
102  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
110  function get_substitutionarray_mysoc($mysoc,$outputlangs)
111  {
112  // phpcs:enable
113  global $conf;
114 
115  if (empty($mysoc->forme_juridique) && ! empty($mysoc->forme_juridique_code))
116  {
117  $mysoc->forme_juridique=getFormeJuridiqueLabel($mysoc->forme_juridique_code);
118  }
119  if (empty($mysoc->country) && ! empty($mysoc->country_code))
120  {
121  $mysoc->country=$outputlangs->transnoentitiesnoconv("Country".$mysoc->country_code);
122  }
123  if (empty($mysoc->state) && ! empty($mysoc->state_code))
124  {
125  $mysoc->state=getState($mysoc->state_code,0);
126  }
127 
128  $logotouse=$conf->mycompany->dir_output.'/logos/thumbs/'.$mysoc->logo_small;
129 
130  return array(
131  'mycompany_logo'=>$logotouse,
132  'mycompany_name'=>$mysoc->name,
133  'mycompany_email'=>$mysoc->email,
134  'mycompany_phone'=>$mysoc->phone,
135  'mycompany_fax'=>$mysoc->fax,
136  'mycompany_address'=>$mysoc->address,
137  'mycompany_zip'=>$mysoc->zip,
138  'mycompany_town'=>$mysoc->town,
139  'mycompany_country'=>$mysoc->country,
140  'mycompany_country_code'=>$mysoc->country_code,
141  'mycompany_state'=>$mysoc->state,
142  'mycompany_state_code'=>$mysoc->state_code,
143  'mycompany_web'=>$mysoc->url,
144  'mycompany_juridicalstatus'=>$mysoc->forme_juridique,
145  'mycompany_managers'=>$mysoc->managers,
146  'mycompany_capital'=>$mysoc->capital,
147  'mycompany_barcode'=>$mysoc->barcode,
148  'mycompany_idprof1'=>$mysoc->idprof1,
149  'mycompany_idprof2'=>$mysoc->idprof2,
150  'mycompany_idprof3'=>$mysoc->idprof3,
151  'mycompany_idprof4'=>$mysoc->idprof4,
152  'mycompany_idprof5'=>$mysoc->idprof5,
153  'mycompany_idprof6'=>$mysoc->idprof6,
154  'mycompany_vatnumber'=>$mysoc->tva_intra,
155  'mycompany_object'=>$mysoc->object,
156  'mycompany_note_private'=>$mysoc->note_private,
157  //'mycompany_note_public'=>$mysoc->note_public, // Only private not exists for "mysoc" but both for thirdparties
158  );
159  }
160 
161 
162  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
170  function get_substitutionarray_thirdparty($object,$outputlangs)
171  {
172  // phpcs:enable
173  global $conf;
174 
175  if (empty($object->country) && ! empty($object->country_code))
176  {
177  $object->country=$outputlangs->transnoentitiesnoconv("Country".$object->country_code);
178  }
179  if (empty($object->state) && ! empty($object->state_code))
180  {
181  $object->state=getState($object->state_code,0);
182  }
183 
184  $array_thirdparty = array(
185  'company_name'=>$object->name,
186  'company_name_alias' => $object->name_alias,
187  'company_email'=>$object->email,
188  'company_phone'=>$object->phone,
189  'company_fax'=>$object->fax,
190  'company_address'=>$object->address,
191  'company_zip'=>$object->zip,
192  'company_town'=>$object->town,
193  'company_country'=>$object->country,
194  'company_country_code'=>$object->country_code,
195  'company_state'=>$object->state,
196  'company_state_code'=>$object->state_code,
197  'company_web'=>$object->url,
198  'company_barcode'=>$object->barcode,
199  'company_vatnumber'=>$object->tva_intra,
200  'company_customercode'=>$object->code_client,
201  'company_suppliercode'=>$object->code_fournisseur,
202  'company_customeraccountancycode'=>$object->code_compta,
203  'company_supplieraccountancycode'=>$object->code_compta_fournisseur,
204  'company_juridicalstatus'=>$object->forme_juridique,
205  'company_outstanding_limit'=>$object->outstanding_limit,
206  'company_capital'=>$object->capital,
207  'company_idprof1'=>$object->idprof1,
208  'company_idprof2'=>$object->idprof2,
209  'company_idprof3'=>$object->idprof3,
210  'company_idprof4'=>$object->idprof4,
211  'company_idprof5'=>$object->idprof5,
212  'company_idprof6'=>$object->idprof6,
213  'company_note_public'=>$object->note_public,
214  'company_note_private'=>$object->note_private,
215  'company_default_bank_iban'=>$object->bank_account->iban,
216  'company_default_bank_bic'=>$object->bank_account->bic
217  );
218 
219  // Retrieve extrafields
220  if(is_array($object->array_options) && count($object->array_options))
221  {
222  require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
223  $extrafields = new ExtraFields($this->db);
224  $extralabels = $extrafields->fetch_name_optionals_label('societe',true);
225  $object->fetch_optionals();
226 
227  foreach($extrafields->attribute_label as $key=>$label)
228  {
229  if($extrafields->attribute_type[$key] == 'price')
230  {
231  $object->array_options['options_'.$key] = price($object->array_options['options_'.$key],0,$outputlangs,0,0,-1,$conf->currency);
232  }
233  else if($extrafields->attribute_type[$key] == 'select' || $extrafields->attribute_type[$key] == 'checkbox')
234  {
235  $object->array_options['options_'.$key] = $extrafields->attribute_param[$key]['options'][$object->array_options['options_'.$key]];
236  }
237  $array_thirdparty = array_merge($array_thirdparty, array ('company_options_'.$key => $object->array_options ['options_' . $key]));
238  }
239  }
240  return $array_thirdparty;
241  }
242 
243  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
252  function get_substitutionarray_contact($object, $outputlangs, $array_key = 'object')
253  {
254  // phpcs:enable
255  global $conf;
256 
257  if(empty($object->country) && ! empty($object->country_code))
258  {
259  $object->country = $outputlangs->transnoentitiesnoconv("Country" . $object->country_code);
260  }
261  if(empty($object->state) && ! empty($object->state_code))
262  {
263  $object->state = getState($object->state_code, 0);
264  }
265 
266  $array_contact = array (
267  $array_key . '_fullname' => $object->getFullName($outputlangs, 1),
268  $array_key . '_lastname' => $object->lastname,
269  $array_key . '_firstname' => $object->firstname,
270  $array_key . '_address' => $object->address,
271  $array_key . '_zip' => $object->zip,
272  $array_key . '_town' => $object->town,
273  $array_key . '_state_id' => $object->state_id,
274  $array_key . '_state_code' => $object->state_code,
275  $array_key . '_state' => $object->state,
276  $array_key . '_country_id' => $object->country_id,
277  $array_key . '_country_code' => $object->country_code,
278  $array_key . '_country' => $object->country,
279  $array_key . '_poste' => $object->poste,
280  $array_key . '_socid' => $object->socid,
281  $array_key . '_statut' => $object->statut,
282  $array_key . '_code' => $object->code,
283  $array_key . '_email' => $object->email,
284  $array_key . '_jabberid' => $object->jabberid,
285  $array_key . '_phone_pro' => $object->phone_pro,
286  $array_key . '_phone_perso' => $object->phone_perso,
287  $array_key . '_phone_mobile' => $object->phone_mobile,
288  $array_key . '_fax' => $object->fax,
289  $array_key . '_birthday' => $object->birthday,
290  $array_key . '_default_lang' => $object->default_lang,
291  $array_key . '_note_public' => $object->note_public,
292  $array_key . '_note_private' => $object->note_private
293  );
294 
295  // Retrieve extrafields
296  require_once DOL_DOCUMENT_ROOT . '/core/class/extrafields.class.php';
297  $extrafields = new ExtraFields($this->db);
298  $extralabels = $extrafields->fetch_name_optionals_label('socpeople', true);
299  $object->fetch_optionals();
300 
301  foreach($extrafields->attribute_label as $key => $label)
302  {
303  if ($extrafields->attribute_type[$key] == 'price')
304  {
305  $object->array_options['options_' . $key] = price($object->array_options ['options_' . $key], 0, $outputlangs, 0, 0, - 1, $conf->currency);
306  }
307  elseif($extrafields->attribute_type[$key] == 'select' || $extrafields->attribute_type[$key] == 'checkbox')
308  {
309  $object->array_options['options_' . $key] = $extrafields->attribute_param[$key]['options'][$object->array_options['options_' . $key]];
310  }
311  $array_contact = array_merge($array_contact, array($array_key.'_options_' . $key => $object->array_options['options_'. $key]));
312  }
313  return $array_contact;
314  }
315 
316 
317  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
324  function get_substitutionarray_other($outputlangs)
325  {
326  // phpcs:enable
327  global $conf;
328 
329  $now=dol_now('gmt'); // gmt
330  $array_other = array(
331  // Date in default language
332  'current_date'=>dol_print_date($now,'day','tzuser'),
333  'current_datehour'=>dol_print_date($now,'dayhour','tzuser'),
334  'current_server_date'=>dol_print_date($now,'day','tzserver'),
335  'current_server_datehour'=>dol_print_date($now,'dayhour','tzserver'),
336  // Date in requested output language
337  'current_date_locale'=>dol_print_date($now,'day','tzuser',$outputlangs),
338  'current_datehour_locale'=>dol_print_date($now,'dayhour','tzuser',$outputlangs),
339  'current_server_date_locale'=>dol_print_date($now,'day','tzserver',$outputlangs),
340  'current_server_datehour_locale'=>dol_print_date($now,'dayhour','tzserver',$outputlangs),
341  );
342 
343 
344  foreach($conf->global as $key => $val)
345  {
346  if (preg_match('/(_pass|password|secret|_key|key$)/i', $key)) $newval = '*****forbidden*****';
347  else $newval = $val;
348  $array_other['__['.$key.']__'] = $newval;
349  }
350 
351  return $array_other;
352  }
353 
354 
355  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
364  function get_substitutionarray_object($object,$outputlangs,$array_key='object')
365  {
366  // phpcs:enable
367  global $conf;
368 
369  $sumpayed=$sumdeposit=$sumcreditnote='';
370  if ($object->element == 'facture')
371  {
372  $invoice_source=new Facture($this->db);
373  if ($object->fk_facture_source > 0)
374  {
375  $invoice_source->fetch($object->fk_facture_source);
376  }
377  $sumpayed = $object->getSommePaiement();
378  $sumdeposit = $object->getSumDepositsUsed();
379  $sumcreditnote = $object->getSumCreditNotesUsed();
380  }
381 
382  $date = ($object->element == 'contrat' ? $object->date_contrat : $object->date);
383 
384  $resarray=array(
385  $array_key.'_id'=>$object->id,
386  $array_key.'_ref'=>$object->ref,
387  $array_key.'_ref_ext'=>$object->ref_ext,
388  $array_key.'_ref_customer'=>(! empty($object->ref_client) ? $object->ref_client : (empty($object->ref_customer) ? '' : $object->ref_customer)),
389  $array_key.'_ref_supplier'=>(! empty($object->ref_fournisseur) ? $object->ref_fournisseur : (empty($object->ref_supplier) ? '' : $object->ref_supplier)),
390  $array_key.'_source_invoice_ref'=>$invoice_source->ref,
391  // Dates
392  $array_key.'_hour'=>dol_print_date($date,'hour'),
393  $array_key.'_date'=>dol_print_date($date,'day'),
394  $array_key.'_date_rfc'=>dol_print_date($date,'dayrfc'),
395  $array_key.'_date_limit'=>(! empty($object->date_lim_reglement)?dol_print_date($object->date_lim_reglement,'day'):''),
396  $array_key.'_date_end'=>(! empty($object->fin_validite)?dol_print_date($object->fin_validite,'day'):''),
397  $array_key.'_date_creation'=>dol_print_date($object->date_creation,'day'),
398  $array_key.'_date_modification'=>(! empty($object->date_modification)?dol_print_date($object->date_modification,'day'):''),
399  $array_key.'_date_validation'=>(! empty($object->date_validation)?dol_print_date($object->date_validation,'dayhour'):''),
400  $array_key.'_date_delivery_planed'=>(! empty($object->date_livraison)?dol_print_date($object->date_livraison,'day'):''),
401  $array_key.'_date_close'=>(! empty($object->date_cloture)?dol_print_date($object->date_cloture,'dayhour'):''),
402 
403  $array_key.'_payment_mode_code'=>$object->mode_reglement_code,
404  $array_key.'_payment_mode'=>($outputlangs->transnoentitiesnoconv('PaymentType'.$object->mode_reglement_code)!='PaymentType'.$object->mode_reglement_code?$outputlangs->transnoentitiesnoconv('PaymentType'.$object->mode_reglement_code):$object->mode_reglement),
405  $array_key.'_payment_term_code'=>$object->cond_reglement_code,
406  $array_key.'_payment_term'=>($outputlangs->transnoentitiesnoconv('PaymentCondition'.$object->cond_reglement_code)!='PaymentCondition'.$object->cond_reglement_code?$outputlangs->transnoentitiesnoconv('PaymentCondition'.$object->cond_reglement_code):($object->cond_reglement_doc?$object->cond_reglement_doc:$object->cond_reglement)),
407 
408  $array_key.'_total_ht_locale'=>price($object->total_ht, 0, $outputlangs),
409  $array_key.'_total_vat_locale'=>(! empty($object->total_vat)?price($object->total_vat, 0, $outputlangs):price($object->total_tva, 0, $outputlangs)),
410  $array_key.'_total_localtax1_locale'=>price($object->total_localtax1, 0, $outputlangs),
411  $array_key.'_total_localtax2_locale'=>price($object->total_localtax2, 0, $outputlangs),
412  $array_key.'_total_ttc_locale'=>price($object->total_ttc, 0, $outputlangs),
413 
414  $array_key.'_total_ht'=>price2num($object->total_ht),
415  $array_key.'_total_vat'=>(! empty($object->total_vat)?price2num($object->total_vat):price2num($object->total_tva)),
416  $array_key.'_total_localtax1'=>price2num($object->total_localtax1),
417  $array_key.'_total_localtax2'=>price2num($object->total_localtax2),
418  $array_key.'_total_ttc'=>price2num($object->total_ttc),
419 
420  $array_key.'_multicurrency_code' => price2num($object->multicurrency_code),
421  $array_key.'_multicurrency_tx' => price2num($object->multicurrency_tx),
422  $array_key.'_multicurrency_total_ht' => price2num($object->multicurrency_total_ht),
423  $array_key.'_multicurrency_total_tva' => price2num($object->multicurrency_total_tva),
424  $array_key.'_multicurrency_total_ttc' => price2num($object->multicurrency_total_ttc),
425  $array_key.'_multicurrency_total_ht_locale' => price($object->multicurrency_total_ht, 0, $outputlangs),
426  $array_key.'_multicurrency_total_tva_locale' => price($object->multicurrency_total_tva, 0, $outputlangs),
427  $array_key.'_multicurrency_total_ttc_locale' => price($object->multicurrency_total_ttc, 0, $outputlangs),
428 
429  $array_key.'_note_private'=>$object->note,
430  $array_key.'_note_public'=>$object->note_public,
431  $array_key.'_note'=>$object->note_public, // For backward compatibility
432 
433  // Payments
434  $array_key.'_already_payed_locale'=>price($sumpayed, 0, $outputlangs),
435  $array_key.'_already_payed'=>price2num($sumpayed),
436  $array_key.'_already_deposit_locale'=>price($sumdeposit, 0, $outputlangs),
437  $array_key.'_already_deposit'=>price2num($sumdeposit),
438  $array_key.'_already_creditnote_locale'=>price($sumcreditnote, 0, $outputlangs),
439  $array_key.'_already_creditnote'=>price2num($sumcreditnote),
440 
441  $array_key.'_already_payed_all_locale'=>price(price2num($sumpayed + $sumdeposit + $sumcreditnote, 'MT'), 0, $outputlangs),
442  $array_key.'_already_payed_all'=> price2num(($sumpayed + $sumdeposit + $sumcreditnote), 'MT'),
443 
444  // Remain to pay with all know infrmation (except open direct debit requests)
445  $array_key.'_remain_to_pay_locale'=>price(price2num($object->total_ttc - $sumpayed - $sumdeposit - $sumcreditnote, 'MT'), 0, $outputlangs),
446  $array_key.'_remain_to_pay'=>price2num($object->total_ttc - $sumpayed - $sumdeposit - $sumcreditnote, 'MT')
447  );
448 
449  if (method_exists($object, 'getTotalDiscount')) {
450  $resarray[$array_key.'_total_discount_ht_locale'] = price($object->getTotalDiscount(), 0, $outputlangs);
451  $resarray[$array_key.'_total_discount_ht'] = price2num($object->getTotalDiscount());
452  } else {
453  $resarray[$array_key.'_total_discount_ht_locale'] = '';
454  $resarray[$array_key.'_total_discount_ht'] = '';
455  }
456 
457  // Fetch project information if there is a project assigned to this object
458  if ($object->element != "project" && ! empty($object->fk_project) && $object->fk_project > 0)
459  {
460  if (! is_object($object->project))
461  {
462  $object->fetch_projet();
463  }
464 
465  $resarray[$array_key.'_project_ref'] = $object->project->ref;
466  $resarray[$array_key.'_project_title'] = $object->project->title;
467  $resarray[$array_key.'_project_description'] = $object->project->description;
468  $resarray[$array_key.'_project_date_start'] = dol_print_date($object->project->date_start, 'day');
469  $resarray[$array_key.'_project_date_end'] = dol_print_date($object->project->date_end, 'day');
470  }
471 
472  // Add vat by rates
473  if (is_array($object->lines) && count($object->lines)>0)
474  {
475  foreach ($object->lines as $line)
476  {
477  // $line->tva_tx format depends on database field accuraty, no reliable. This is kept for backward comaptibility
478  if (empty($resarray[$array_key.'_total_vat_'.$line->tva_tx])) $resarray[$array_key.'_total_vat_'.$line->tva_tx]=0;
479  $resarray[$array_key.'_total_vat_'.$line->tva_tx]+=$line->total_tva;
480  $resarray[$array_key.'_total_vat_locale_'.$line->tva_tx]=price($resarray[$array_key.'_total_vat_'.$line->tva_tx]);
481  // $vatformated is vat without not expected chars (so 20, or 8.5 or 5.99 for example)
482  $vatformated=vatrate($line->tva_tx);
483  if (empty($resarray[$array_key.'_total_vat_'.$vatformated])) $resarray[$array_key.'_total_vat_'.$vatformated]=0;
484  $resarray[$array_key.'_total_vat_'.$vatformated]+=$line->total_tva;
485  $resarray[$array_key.'_total_vat_locale_'.$vatformated]=price($resarray[$array_key.'_total_vat_'.$vatformated]);
486  }
487  }
488  // Retrieve extrafields
489  if (is_array($object->array_options) && count($object->array_options))
490  {
491  $extrafieldkey=$object->element;
492 
493  require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
494  $extrafields = new ExtraFields($this->db);
495  $extralabels = $extrafields->fetch_name_optionals_label($extrafieldkey,true);
496  $object->fetch_optionals();
497 
498  $resarray = $this->fill_substitutionarray_with_extrafields($object,$resarray,$extrafields,$array_key,$outputlangs);
499  }
500  return $resarray;
501  }
502 
503  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
511  function get_substitutionarray_lines($line, $outputlangs)
512  {
513  // phpcs:enable
514  global $conf;
515 
516  $resarray= array(
517  'line_fulldesc'=>doc_getlinedesc($line,$outputlangs),
518  'line_product_ref'=>$line->product_ref,
519  'line_product_ref_fourn'=>$line->ref_fourn, // for supplier doc lines
520  'line_product_label'=>$line->product_label,
521  'line_product_type'=>$line->product_type,
522  'line_desc'=>$line->desc,
523  'line_vatrate'=>vatrate($line->tva_tx,true,$line->info_bits),
524  'line_up'=>price2num($line->subprice),
525  'line_up_locale'=>price($line->subprice, 0, $outputlangs),
526  'line_qty'=>$line->qty,
527  'line_discount_percent'=>($line->remise_percent?$line->remise_percent.'%':''),
528  'line_price_ht'=>price2num($line->total_ht),
529  'line_price_ttc'=>price2num($line->total_ttc),
530  'line_price_vat'=>price2num($line->total_tva),
531  'line_price_ht_locale'=>price($line->total_ht, 0, $outputlangs),
532  'line_price_ttc_locale'=>price($line->total_ttc, 0, $outputlangs),
533  'line_price_vat_locale'=>price($line->total_tva, 0, $outputlangs),
534  // Dates
535  'line_date_start'=>dol_print_date($line->date_start, 'day', 'tzuser'),
536  'line_date_start_locale'=>dol_print_date($line->date_start, 'day', 'tzuser', $outputlangs),
537  'line_date_start_rfc'=>dol_print_date($line->date_start, 'dayrfc', 'tzuser'),
538  'line_date_end'=>dol_print_date($line->date_end, 'day', 'tzuser'),
539  'line_date_end_locale'=>dol_print_date($line->date_end, 'day', 'tzuser', $outputlangs),
540  'line_date_end_rfc'=>dol_print_date($line->date_end, 'dayrfc', 'tzuser'),
541 
542  'line_multicurrency_code' => price2num($line->multicurrency_code),
543  'line_multicurrency_subprice' => price2num($line->multicurrency_subprice),
544  'line_multicurrency_total_ht' => price2num($line->multicurrency_total_ht),
545  'line_multicurrency_total_tva' => price2num($line->multicurrency_total_tva),
546  'line_multicurrency_total_ttc' => price2num($line->multicurrency_total_ttc),
547  'line_multicurrency_subprice_locale' => price($line->multicurrency_subprice, 0, $outputlangs),
548  'line_multicurrency_total_ht_locale' => price($line->multicurrency_total_ht, 0, $outputlangs),
549  'line_multicurrency_total_tva_locale' => price($line->multicurrency_total_tva, 0, $outputlangs),
550  'line_multicurrency_total_ttc_locale' => price($line->multicurrency_total_ttc, 0, $outputlangs),
551  );
552 
553  // Units
554  if ($conf->global->PRODUCT_USE_UNITS)
555  {
556  $resarray['line_unit']=$outputlangs->trans($line->getLabelOfUnit('long'));
557  $resarray['line_unit_short']=$outputlangs->trans($line->getLabelOfUnit('short'));
558  }
559 
560  // Retrieve extrafields
561  $extrafieldkey=$line->element;
562  $array_key="line";
563  require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
564  $extrafields = new ExtraFields($this->db);
565  $extralabels = $extrafields->fetch_name_optionals_label($extrafieldkey,true);
566  $line->fetch_optionals();
567 
568  $resarray = $this->fill_substitutionarray_with_extrafields($line,$resarray,$extrafields,$array_key=$array_key,$outputlangs);
569 
570  // Load product data optional fields to the line -> enables to use "line_options_{extrafield}"
571  if (isset($line->fk_product) && $line->fk_product > 0)
572  {
573  $tmpproduct = new Product($this->db);
574  $result = $tmpproduct->fetch($line->fk_product);
575  foreach($tmpproduct->array_options as $key=>$label)
576  $resarray["line_product_".$key] = $label;
577  }
578 
579  return $resarray;
580  }
581 
582  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
591  function get_substitutionarray_shipment($object,$outputlangs,$array_key='object')
592  {
593  // phpcs:enable
594  global $conf;
595  dol_include_once('/core/lib/product.lib.php');
596  $object->list_delivery_methods($object->shipping_method_id);
597  $calculatedVolume=($object->trueWidth * $object->trueHeight * $object->trueDepth);
598 
599  $array_shipment=array(
600  $array_key.'_id'=>$object->id,
601  $array_key.'_ref'=>$object->ref,
602  $array_key.'_ref_ext'=>$object->ref_ext,
603  $array_key.'_ref_customer'=>$object->ref_customer,
604  $array_key.'_date_delivery'=>dol_print_date($object->date_delivery,'day'),
605  $array_key.'_hour_delivery'=>dol_print_date($object->date_delivery,'hour'),
606  $array_key.'_date_creation'=>dol_print_date($object->date_creation,'day'),
607  $array_key.'_total_ht'=>price($object->total_ht),
608  $array_key.'_total_vat'=>price($object->total_tva),
609  $array_key.'_total_ttc'=>price($object->total_ttc),
610  $array_key.'_total_discount_ht' => price($object->getTotalDiscount()),
611  $array_key.'_note_private'=>$object->note_private,
612  $array_key.'_note'=>$object->note_public,
613  $array_key.'_tracking_number'=>$object->tracking_number,
614  $array_key.'_tracking_url'=>$object->tracking_url,
615  $array_key.'_shipping_method'=>$object->listmeths[0]['libelle'],
616  $array_key.'_weight'=>$object->trueWeight.' '.measuring_units_string($object->weight_units, 'weight'),
617  $array_key.'_width'=>$object->trueWidth.' '.measuring_units_string($object->width_units, 'size'),
618  $array_key.'_height'=>$object->trueHeight.' '.measuring_units_string($object->height_units, 'size'),
619  $array_key.'_depth'=>$object->trueDepth.' '.measuring_units_string($object->depth_units, 'size'),
620  $array_key.'_size'=>$calculatedVolume.' '.measuring_units_string(0, 'volume'),
621  );
622 
623  // Add vat by rates
624  foreach ($object->lines as $line)
625  {
626  if (empty($array_shipment[$array_key.'_total_vat_'.$line->tva_tx])) $array_shipment[$array_key.'_total_vat_'.$line->tva_tx]=0;
627  $array_shipment[$array_key.'_total_vat_'.$line->tva_tx]+=$line->total_tva;
628  }
629 
630  // Retrieve extrafields
631  if (is_array($object->array_options) && count($object->array_options))
632  {
633  require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
634  $extrafields = new ExtraFields($this->db);
635  $extralabels = $extrafields->fetch_name_optionals_label('expedition',true);
636  $object->fetch_optionals();
637 
638  $array_shipment = $this->fill_substitutionarray_with_extrafields($object,$array_shipment,$extrafields,$array_key,$outputlangs);
639  }
640 
641  return $array_shipment;
642  }
643 
644 
645  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
653  function get_substitutionarray_shipment_lines($line, $outputlangs)
654  {
655  // phpcs:enable
656  global $conf;
657  dol_include_once('/core/lib/product.lib.php');
658 
659  $resarray = array(
660  'line_fulldesc'=>doc_getlinedesc($line,$outputlangs),
661  'line_product_ref'=>$line->product_ref,
662  'line_product_label'=>$line->product_label,
663  'line_desc'=>$line->desc,
664  'line_vatrate'=>vatrate($line->tva_tx,true,$line->info_bits),
665  'line_up'=>price($line->subprice),
666  'line_qty'=>$line->qty,
667  'line_qty_shipped'=>$line->qty_shipped,
668  'line_qty_asked'=>$line->qty_asked,
669  'line_discount_percent'=>($line->remise_percent?$line->remise_percent.'%':''),
670  'line_price_ht'=>price($line->total_ht),
671  'line_price_ttc'=>price($line->total_ttc),
672  'line_price_vat'=>price($line->total_tva),
673  'line_weight'=>empty($line->weight) ? '' : $line->weight*$line->qty_shipped.' '.measuring_units_string($line->weight_units, 'weight'),
674  'line_length'=>empty($line->length) ? '' : $line->length*$line->qty_shipped.' '.measuring_units_string($line->length_units, 'size'),
675  'line_surface'=>empty($line->surface) ? '' : $line->surface*$line->qty_shipped.' '.measuring_units_string($line->surface_units, 'surface'),
676  'line_volume'=>empty($line->volume) ? '' : $line->volume*$line->qty_shipped.' '.measuring_units_string($line->volume_units, 'volume'),
677  );
678 
679  // Retrieve extrafields
680  $extrafieldkey = $line->element;
681  $array_key = "line";
682  require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
683  $extrafields = new ExtraFields($this->db);
684  $extralabels = $extrafields->fetch_name_optionals_label($extrafieldkey, true);
685  $line->fetch_optionals();
686 
687  $resarray = $this->fill_substitutionarray_with_extrafields($line, $resarray, $extrafields, $array_key, $outputlangs);
688 
689  return $resarray;
690  }
691 
692 
693  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
702  function get_substitutionarray_each_var_object(&$object,$outputlangs,$recursive=true)
703  {
704  // phpcs:enable
705  $array_other = array();
706  if (!empty($object)) {
707  foreach($object as $key => $value) {
708  if (!empty($value)) {
709  if (!is_array($value) && !is_object($value)) {
710  $array_other['object_'.$key] = $value;
711  }
712  if (is_array($value) && $recursive) {
713  $array_other['object_'.$key] = $this->get_substitutionarray_each_var_object($value,$outputlangs,false);
714  }
715  }
716  }
717  }
718  return $array_other;
719  }
720 
721 
722  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.NotCamelCaps
733  function fill_substitutionarray_with_extrafields($object,$array_to_fill,$extrafields,$array_key,$outputlangs)
734  {
735  // phpcs:enable
736  global $conf;
737  foreach($extrafields->attribute_label as $key=>$label)
738  {
739  if($extrafields->attribute_type[$key] == 'price')
740  {
741  $object->array_options['options_'.$key] = price2num($object->array_options['options_'.$key]);
742  $object->array_options['options_'.$key.'_currency'] = price($object->array_options['options_'.$key],0,$outputlangs,0,0,-1,$conf->currency);
743  //Add value to store price with currency
744  $array_to_fill=array_merge($array_to_fill,array($array_key.'_options_'.$key.'_currency' => $object->array_options['options_'.$key.'_currency']));
745  }
746  else if($extrafields->attribute_type[$key] == 'select' || $extrafields->attribute_type[$key] == 'checkbox')
747  {
748  $object->array_options['options_'.$key] = $extrafields->attribute_param[$key]['options'][$object->array_options['options_'.$key]];
749  }
750  else if($extrafields->attribute_type[$key] == 'date')
751  {
752  if (strlen($object->array_options['options_'.$key])>0)
753  {
754  $date = $object->array_options['options_'.$key];
755  $object->array_options['options_'.$key] = dol_print_date($date,'day'); // using company output language
756  $object->array_options['options_'.$key.'_locale'] = dol_print_date($date,'day','tzserver',$outputlangs); // using output language format
757  $object->array_options['options_'.$key.'_rfc'] = dol_print_date($date,'dayrfc'); // international format
758  }
759  else
760  {
761  $object->array_options['options_'.$key] = '';
762  $object->array_options['options_'.$key.'_locale'] = '';
763  $object->array_options['options_'.$key.'_rfc'] = '';
764  }
765  $array_to_fill=array_merge($array_to_fill,array($array_key.'_options_'.$key.'_locale' => $object->array_options['options_'.$key.'_locale']));
766  $array_to_fill=array_merge($array_to_fill,array($array_key.'_options_'.$key.'_rfc' => $object->array_options['options_'.$key.'_rfc']));
767  }
768  else if($extrafields->attribute_type[$key] == 'datetime')
769  {
770  $datetime = $object->array_options['options_'.$key];
771  $object->array_options['options_'.$key] = ($datetime!="0000-00-00 00:00:00"?dol_print_date($object->array_options['options_'.$key],'dayhour'):''); // using company output language
772  $object->array_options['options_'.$key.'_locale'] = ($datetime!="0000-00-00 00:00:00"?dol_print_date($object->array_options['options_'.$key],'dayhour','tzserver',$outputlangs):''); // using output language format
773  $object->array_options['options_'.$key.'_rfc'] = ($datetime!="0000-00-00 00:00:00"?dol_print_date($object->array_options['options_'.$key],'dayhourrfc'):''); // international format
774  $array_to_fill=array_merge($array_to_fill,array($array_key.'_options_'.$key.'_locale' => $object->array_options['options_'.$key.'_locale']));
775  $array_to_fill=array_merge($array_to_fill,array($array_key.'_options_'.$key.'_rfc' => $object->array_options['options_'.$key.'_rfc']));
776  }
777  else if($extrafields->attribute_type[$key] == 'link')
778  {
779  $id = $object->array_options['options_'.$key];
780  if ($id != "")
781  {
782  $param = $extrafields->attribute_param[$key];
783  $param_list=array_keys($param['options']); // $param_list='ObjectName:classPath'
784  $InfoFieldList = explode(":", $param_list[0]);
785  $classname=$InfoFieldList[0];
786  $classpath=$InfoFieldList[1];
787  if (! empty($classpath))
788  {
789  dol_include_once($InfoFieldList[1]);
790  if ($classname && class_exists($classname))
791  {
792  $tmpobject = new $classname($this->db);
793  $tmpobject->fetch($id);
794  // completely replace the id with the linked object name
795  $object->array_options['options_'.$key] = $tmpobject->name;
796  }
797  }
798  }
799  }
800 
801  $array_to_fill=array_merge($array_to_fill,array($array_key.'_options_'.$key => $object->array_options['options_'.$key]));
802  }
803 
804  return $array_to_fill;
805  }
806 
807 
820  function printRect($pdf, $x, $y, $l, $h, $hidetop=0, $hidebottom=0)
821  {
822  if (empty($hidetop) || $hidetop==-1) $pdf->line($x, $y, $x+$l, $y);
823  $pdf->line($x+$l, $y, $x+$l, $y+$h);
824  if (empty($hidebottom)) $pdf->line($x+$l, $y+$h, $x, $y+$h);
825  $pdf->line($x, $y+$h, $x, $y);
826  }
827 
828 
836  function columnSort($a, $b)
837  {
838  if(empty($a['rank'])){ $a['rank'] = 0; }
839  if(empty($b['rank'])){ $b['rank'] = 0; }
840  if ($a['rank'] == $b['rank']) {
841  return 0;
842  }
843  return ($a['rank'] > $b['rank']) ? -1 : 1;
844  }
845 
856  function prepareArrayColumnField($object,$outputlangs,$hidedetails=0,$hidedesc=0,$hideref=0)
857  {
858  global $conf;
859 
860  $this->defineColumnField($object,$outputlangs,$hidedetails,$hidedesc,$hideref);
861 
862 
863  // Sorting
864  uasort ( $this->cols, array( $this, 'columnSort' ) );
865 
866  // Positionning
867  $curX = $this->page_largeur-$this->marge_droite; // start from right
868 
869  // Array witdh
870  $arrayWidth = $this->page_largeur-$this->marge_droite-$this->marge_gauche;
871 
872  // Count flexible column
873  $totalDefinedColWidth = 0;
874  $countFlexCol = 0;
875  foreach ($this->cols as $colKey =>& $colDef)
876  {
877  if(!$this->getColumnStatus($colKey)) continue; // continue if desable
878 
879  if(!empty($colDef['scale'])){
880  // In case of column widht is defined by percentage
881  $colDef['width'] = abs($arrayWidth * $colDef['scale'] / 100 );
882  }
883 
884  if(empty($colDef['width'])){
885  $countFlexCol++;
886  }
887  else{
888  $totalDefinedColWidth += $colDef['width'];
889  }
890  }
891 
892  foreach ($this->cols as $colKey =>& $colDef)
893  {
894  // setting empty conf with default
895  if(!empty($colDef['title'])){
896  $colDef['title'] = array_replace($this->defaultTitlesFieldsStyle, $colDef['title']);
897  }
898  else{
899  $colDef['title'] = $this->defaultTitlesFieldsStyle;
900  }
901 
902  // setting empty conf with default
903  if(!empty($colDef['content'])){
904  $colDef['content'] = array_replace($this->defaultContentsFieldsStyle, $colDef['content']);
905  }
906  else{
907  $colDef['content'] = $this->defaultContentsFieldsStyle;
908  }
909 
910  if($this->getColumnStatus($colKey))
911  {
912  // In case of flexible column
913  if(empty($colDef['width'])){
914  $colDef['width'] = abs(($arrayWidth - $totalDefinedColWidth)) / $countFlexCol;
915  }
916 
917  // Set positions
918  $lastX = $curX;
919  $curX = $lastX - $colDef['width'];
920  $colDef['xStartPos'] = $curX;
921  $colDef['xEndPos'] = $lastX;
922  }
923  }
924  }
925 
932  function getColumnContentWidth($colKey)
933  {
934  $colDef = $this->cols[$colKey];
935  return $colDef['width'] - $colDef['content']['padding'][3] - $colDef['content']['padding'][1];
936  }
937 
938 
945  function getColumnContentXStart($colKey)
946  {
947  $colDef = $this->cols[$colKey];
948  return $colDef['xStartPos'] + $colDef['content']['padding'][3];
949  }
950 
957  function getColumnRank($colKey)
958  {
959  if(!isset($this->cols[$colKey]['rank'])) return -1;
960  return $this->cols[$colKey]['rank'];
961  }
962 
972  function insertNewColumnDef($newColKey, $defArray, $targetCol = false, $insertAfterTarget = false)
973  {
974  // prepare wanted rank
975  $rank = -1;
976 
977  // try to get rank from target column
978  if(!empty($targetCol)){
979  $rank = $this->getColumnRank($targetCol);
980  if($rank>=0 && $insertAfterTarget){ $rank++; }
981  }
982 
983  // get rank from new column definition
984  if($rank<0 && !empty($defArray['rank'])){
985  $rank = $defArray['rank'];
986  }
987 
988  // error: no rank
989  if($rank<0){ return -1; }
990 
991  foreach ($this->cols as $colKey =>& $colDef)
992  {
993  if( $rank <= $colDef['rank'])
994  {
995  $colDef['rank'] = $colDef['rank'] + 1;
996  }
997  }
998 
999  $defArray['rank'] = $rank;
1000  $this->cols[$newColKey] = $defArray; // array_replace is used to preserve keys
1001 
1002  return $rank;
1003  }
1004 
1005 
1015  function printStdColumnContent($pdf, &$curY, $colKey, $columnText = '')
1016  {
1017  global $hookmanager;
1018 
1019  $parameters=array(
1020  'curY' => &$curY,
1021  'columnText' => $columnText,
1022  'colKey' => $colKey
1023  );
1024  $reshook=$hookmanager->executeHooks('printStdColumnContent',$parameters,$this); // Note that $action and $object may have been modified by hook
1025  if ($reshook < 0) setEventMessages($hookmanager->error,$hookmanager->errors,'errors');
1026  if (!$reshook)
1027  {
1028  if(empty($columnText)) return;
1029  $pdf->SetXY($this->getColumnContentXStart($colKey),$curY); // Set curent position
1030  $colDef = $this->cols[$colKey];
1031  $pdf->MultiCell( $this->getColumnContentWidth($colKey),2, $columnText,'',$colDef['content']['align']);
1032  }
1033  }
1034 
1035 
1042  function getColumnStatus($colKey)
1043  {
1044  if( !empty($this->cols[$colKey]['status'])){
1045  return true;
1046  }
1047  else return false;
1048  }
1049 }
setEventMessages($mesg, $mesgs, $style='mesgs')
Set event messages in dol_events session object.
prepareArrayColumnField($object, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0)
Prepare Array Column Field.
get_substitutionarray_shipment($object, $outputlangs, $array_key='object')
Define array with couple substitution key => substitution value.
get_substitutionarray_lines($line, $outputlangs)
Define array with couple substitution key => substitution value.
insertNewColumnDef($newColKey, $defArray, $targetCol=false, $insertAfterTarget=false)
get column position rank from column key
getColumnRank($colKey)
get column position rank from column key
get_exdir($num, $level, $alpha, $withoutslash, $object, $modulepart)
Return a path to have a the directory according to object where files are stored. ...
get_substitutionarray_each_var_object(&$object, $outputlangs, $recursive=true)
Define array with couple subtitution key => subtitution value.
Class to manage products or services.
get_substitutionarray_object($object, $outputlangs, $array_key='object')
Define array with couple substitution key => substitution value.
__construct($db)
Constructor.
get_substitutionarray_user($user, $outputlangs)
Define array with couple subtitution key => subtitution value.
getState($id, $withcode='', $dbtouse=0, $withregion=0, $outputlangs='', $entconv=1)
Return state translated from an id.
doc_getlinedesc($line, $outputlangs, $hideref=0, $hidedesc=0, $issupplierline=0)
Return line description translated in outputlangs and encoded into UTF8.
Definition: doc.lib.php:41
get_substitutionarray_shipment_lines($line, $outputlangs)
Define array with couple substitution key => substitution value.
getColumnStatus($colKey)
get column status from column key
Class to manage standard extra fields.
getFormeJuridiqueLabel($code)
Retourne le nom traduit de la forme juridique.
if(! function_exists('dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
getColumnContentXStart($colKey)
get column content X (abscissa) left position from column key
get_substitutionarray_mysoc($mysoc, $outputlangs)
Define array with couple subtitution key => subtitution value.
dol_now($mode='gmt')
Return date for now.
printRect($pdf, $x, $y, $l, $h, $hidetop=0, $hidebottom=0)
Rect pdf.
columnSort($a, $b)
uasort callback function to Sort colums fields
vatrate($rate, $addpercent=false, $info_bits=0, $usestarfornpr=0)
Return a string with VAT rate label formated for view output Used into pdf and HTML pages...
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages...
dol_print_date($time, $format='', $tzoutput='tzserver', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
get_substitutionarray_contact($object, $outputlangs, $array_key='object')
Define array with couple subtitution key => subtitution value.
get_substitutionarray_thirdparty($object, $outputlangs)
Define array with couple subtitution key => subtitution value.
measuring_units_string($unit, $measuring_style='')
Return translation label of a unit key.
fill_substitutionarray_with_extrafields($object, $array_to_fill, $extrafields, $array_key, $outputlangs)
Fill array with couple extrafield key => extrafield value.
Parent class for documents generators.
get_substitutionarray_other($outputlangs)
Define array with couple subtitution key => subtitution value.
Class to manage invoices.
printStdColumnContent($pdf, &$curY, $colKey, $columnText='')
print standard column content
getColumnContentWidth($colKey)
get column content width from column key
price2num($amount, $rounding='', $alreadysqlnb=0)
Function that return a number with universal decimal format (decimal separator is &#39;...