dolibarr  19.0.0-dev
doc_generic_project_odt.modules.php
Go to the documentation of this file.
1 <?php
2 /* Copyright (C) 2010-2012 Laurent Destailleur <eldy@users.sourceforge.net>
3  * Copyright (C) 2012 Juanjo Menent <jmenent@2byte.es>
4  * Copyright (C) 2013 Florian Henry <florian.henry@ope-concept.pro>
5  * Copyright (C) 2016-2023 Charlene Benke <charlene@patas-monkey.com>
6  * Copyright (C) 2018 Frédéric France <frederic.france@netlogic.fr>
7  * Copyright (C) 2023 Gauthier VERDOL <gauthier.verdol@atm-consulting.fr>
8  *
9  * This program is free software; you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation; either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the GNU General Public License
20  * along with this program. If not, see <https://www.gnu.org/licenses/>.
21  * or see https://www.gnu.org/
22  */
23 
30 require_once DOL_DOCUMENT_ROOT.'/core/modules/project/modules_project.php';
31 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
32 require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
34 require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
35 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
36 require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
37 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
38 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
39 require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
40 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
41 if (isModEnabled("propal")) {
42  require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
43 }
44 if (isModEnabled('facture')) {
45  require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
46 }
47 if (isModEnabled('facture')) {
48  require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php';
49 }
50 if (isModEnabled('commande')) {
51  require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
52 }
53 if (isModEnabled("supplier_invoice")) {
54  require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
55 }
56 if (isModEnabled("supplier_order")) {
57  require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
58 }
59 if (isModEnabled('contrat')) {
60  require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
61 }
62 if (isModEnabled('ficheinter')) {
63  require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
64 }
65 if (isModEnabled('deplacement')) {
66  require_once DOL_DOCUMENT_ROOT.'/compta/deplacement/class/deplacement.class.php';
67 }
68 if (isModEnabled('agenda')) {
69  require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
70 }
71 if (isModEnabled('expedition')) {
72  require_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php';
73 }
74 
79 {
84  public $emetteur;
85 
90  public $version = 'dolibarr';
91 
92 
98  public function __construct($db)
99  {
100  global $conf, $langs, $mysoc;
101 
102  // Load traductions files required by page
103  $langs->loadLangs(array("companies", "main"));
104 
105  $this->db = $db;
106  $this->name = "ODT templates";
107  $this->description = $langs->trans("DocumentModelOdt");
108  $this->scandir = 'PROJECT_ADDON_PDF_ODT_PATH'; // Name of constant that is used to save list of directories to scan
109 
110  // Page size for A4 format
111  $this->type = 'odt';
112  $this->page_largeur = 0;
113  $this->page_hauteur = 0;
114  $this->format = array($this->page_largeur, $this->page_hauteur);
115  $this->marge_gauche = 0;
116  $this->marge_droite = 0;
117  $this->marge_haute = 0;
118  $this->marge_basse = 0;
119 
120  $this->option_logo = 1; // Display logo
121  $this->option_tva = 0; // Manage the vat option COMMANDE_TVAOPTION
122  $this->option_modereg = 0; // Display payment mode
123  $this->option_condreg = 0; // Display payment terms
124  $this->option_multilang = 1; // Available in several languages
125  $this->option_escompte = 0; // Displays if there has been a discount
126  $this->option_credit_note = 0; // Support credit notes
127  $this->option_freetext = 1; // Support add of a personalised text
128  $this->option_draft_watermark = 0; // Support add of a watermark on drafts
129 
130  // Get source company
131  $this->emetteur = $mysoc;
132  if (!$this->emetteur->country_code) {
133  $this->emetteur->country_code = substr($langs->defaultlang, -2); // Par defaut, si n'etait pas defini
134  }
135  }
136 
137 
138  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
147  public function get_substitutionarray_object($object, $outputlangs, $array_key = 'object')
148  {
149  // phpcs:enable
150  global $conf;
151 
152  $resarray = array(
153  $array_key.'_id'=>$object->id,
154  $array_key.'_ref'=>$object->ref,
155  $array_key.'_title'=>$object->title,
156  $array_key.'_description'=>$object->description,
157  $array_key.'_date_creation'=>dol_print_date($object->date_c, 'day'),
158  $array_key.'_date_modification'=>dol_print_date($object->date_m, 'day'),
159  $array_key.'_date_start'=>dol_print_date($object->date_start, 'day'),
160  $array_key.'_date_end'=>dol_print_date($object->date_end, 'day'),
161  $array_key.'_note_private'=>$object->note_private,
162  $array_key.'_note_public'=>$object->note_public,
163  $array_key.'_public'=>$object->public,
164  $array_key.'_statut'=>$object->getLibStatut()
165  );
166 
167  require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
168  $extrafields = new ExtraFields($this->db);
169  $extrafields->fetch_name_optionals_label($object->table_element, true);
170  $object->fetch_optionals();
171 
172  $resarray = $this->fill_substitutionarray_with_extrafields($object, $resarray, $extrafields, $array_key, $outputlangs);
173 
174  return $resarray;
175  }
176 
177  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
185  public function get_substitutionarray_tasks(Task $task, $outputlangs)
186  {
187  // phpcs:enable
188  $resarray = array(
189  'task_ref'=>$task->ref,
190  'task_fk_project'=>$task->fk_project,
191  'task_projectref'=>$task->projectref,
192  'task_projectlabel'=>$task->projectlabel,
193  'task_label'=>$task->label,
194  'task_description'=>$task->description,
195  'task_fk_parent'=>$task->fk_task_parent,
196  'task_duration'=>$task->duration,
197  'task_duration_hour'=>convertSecondToTime($task->duration, 'all'),
198  'task_planned_workload'=>$task->planned_workload,
199  'task_planned_workload_hour'=>convertSecondToTime($task->planned_workload, 'all'),
200  'task_progress'=>$task->progress,
201  'task_public'=>$task->public,
202  'task_date_start'=>dol_print_date($task->date_start, 'day'),
203  'task_date_end'=>dol_print_date($task->date_end, 'day'),
204  'task_note_private'=>$task->note_private,
205  'task_note_public'=>$task->note_public
206  );
207 
208  require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
209  $extrafields = new ExtraFields($this->db);
210  $extrafields->fetch_name_optionals_label($task->table_element, true);
211  $task->fetch_optionals();
212 
213  $resarray = $this->fill_substitutionarray_with_extrafields($task, $resarray, $extrafields, 'task', $outputlangs);
214 
215  return $resarray;
216  }
217 
218  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
226  public function get_substitutionarray_project_contacts($contact, $outputlangs)
227  {
228  // phpcs:enable
229  global $conf;
230  $pc = 'projcontacts_'; // prefix to avoid typos
231 
232  $ret = array(
233  $pc.'id'=>$contact['id'],
234  $pc.'rowid'=>$contact['rowid'],
235  $pc.'role'=>$contact['libelle'],
236  $pc.'lastname'=>$contact['lastname'],
237  $pc.'firstname'=>$contact['firstname'],
238  $pc.'civility'=>$contact['civility'],
239  $pc.'fullcivname'=>$contact['fullname'],
240  $pc.'socname'=>$contact['socname'],
241  $pc.'email'=>$contact['email']
242  );
243 
244  if ($contact['source'] == 'external') {
245  $ret[$pc.'isInternal'] = ''; // not internal
246 
247  $ct = new Contact($this->db);
248  $ct->fetch($contact['id']);
249  $ret[$pc.'phone_pro'] = $ct->phone_pro;
250  $ret[$pc.'phone_perso'] = $ct->phone_perso;
251  $ret[$pc.'phone_mobile'] = $ct->phone_mobile;
252 
253  // fetch external user extrafields
254  require_once DOL_DOCUMENT_ROOT.'/core/class/extrafields.class.php';
255  $extrafields = new ExtraFields($this->db);
256  $extrafields->fetch_name_optionals_label($ct->table_element, true);
257  $extrafields_num = $ct->fetch_optionals();
258  //dol_syslog(get_class($this)."::get_substitutionarray_project_contacts: ===== Number of Extrafields found: ".$extrafields_num, LOG_DEBUG);
259  foreach ($ct->array_options as $efkey => $efval) {
260  dol_syslog(get_class($this)."::get_substitutionarray_project_contacts: +++++ Extrafield ".$efkey." => ".$efval, LOG_DEBUG);
261  $ret[$pc.$efkey] = $efval; // add nothing else because it already comes as 'options_XX'
262  }
263  } elseif ($contact['source'] == 'internal') {
264  $ret[$pc.'isInternal'] = '1'; // this is an internal user
265 
266  $ct = new User($this->db);
267  $ct->fetch($contact['id']);
268  $ret[$pc.'phone_pro'] = $ct->office_phone;
269  $ret[$pc.'phone_perso'] = '';
270  $ret[$pc.'phone_mobile'] = $ct->user_mobile;
271  // do internal users have extrafields ?
272  }
273  return $ret;
274  }
275 
276  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
284  public function get_substitutionarray_project_file($file, $outputlangs)
285  {
286  // phpcs:enable
287  global $conf;
288 
289  return array(
290  'projfile_name'=>$file['name'],
291  'projfile_date'=>dol_print_date($file['date'], 'day'),
292  'projfile_size'=>$file['size']
293  );
294  }
295 
296  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
304  public function get_substitutionarray_project_reference($refdetail, $outputlangs)
305  {
306  // phpcs:enable
307  global $conf;
308 
309  return array(
310  'projref_type'=>$refdetail['type'],
311  'projref_ref'=>$refdetail['ref'],
312  'projref_date'=>dol_print_date($refdetail['date'], 'day'),
313  'projref_socname'=>$refdetail['socname'],
314  'projref_amountht'=>price($refdetail['amountht'], 0, $outputlangs),
315  'projref_amountttc'=>price($refdetail['amountttc'], 0, $outputlangs),
316  'projref_status'=>$refdetail['status']
317  );
318  }
319 
320  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
328  public function get_substitutionarray_tasksressource($taskressource, $outputlangs)
329  {
330  // phpcs:enable
331  global $conf;
332  //dol_syslog(get_class($this).'::get_substitutionarray_tasksressource taskressource='.var_export($taskressource,true),LOG_DEBUG);
333  return array(
334  'taskressource_rowid'=>$taskressource['rowid'],
335  'taskressource_role'=>$taskressource['libelle'],
336  'taskressource_lastname'=>$taskressource['lastname'],
337  'taskressource_firstname'=>$taskressource['firstname'],
338  'taskressource_fullcivname'=>$taskressource['fullname'],
339  'taskressource_socname'=>$taskressource['socname'],
340  'taskressource_email'=>$taskressource['email']
341  );
342  }
343 
344  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
352  public function get_substitutionarray_taskstime($tasktime, $outputlangs)
353  {
354  // phpcs:enable
355  global $conf;
356 
357  return array(
358  'tasktime_rowid'=>$tasktime['rowid'],
359  'tasktime_task_date'=>dol_print_date($tasktime['task_date'], 'day'),
360  'tasktime_task_duration_sec'=>$tasktime['task_duration'],
361  'tasktime_task_duration'=>convertSecondToTime($tasktime['task_duration'], 'all'),
362  'tasktime_note'=>$tasktime['note'],
363  'tasktime_fk_user'=>$tasktime['fk_user'],
364  'tasktime_user_name'=>$tasktime['name'],
365  'tasktime_user_first'=>$tasktime['firstname'],
366  'tasktime_fullcivname'=>$tasktime['fullcivname'],
367  'tasktime_amountht'=>$tasktime['amountht'],
368  'tasktime_amountttc'=>$tasktime['amountttc'],
369  'tasktime_thm'=>$tasktime['thm'],
370  );
371  }
372 
373  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
381  public function get_substitutionarray_task_file($file, $outputlangs)
382  {
383  // phpcs:enable
384  global $conf;
385 
386  return array(
387  'tasksfile_name'=>$file['name'],
388  'tasksfile_date'=>dol_print_date($file['date'], 'day'),
389  'tasksfile_size'=>$file['size']
390  );
391  }
392 
393 
400  public function info($langs)
401  {
402  global $conf, $langs;
403 
404  // Load translation files required by the page
405  $langs->loadLangs(array("companies", "errors"));
406 
407  $form = new Form($this->db);
408 
409  $texte = $this->description.".<br>\n";
410  $texte .= '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
411  $texte .= '<input type="hidden" name="token" value="'.newToken().'">';
412  $texte .= '<input type="hidden" name="page_y" value="">';
413  $texte .= '<input type="hidden" name="action" value="setModuleOptions">';
414  $texte .= '<input type="hidden" name="param1" value="PROJECT_ADDON_PDF_ODT_PATH">';
415  $texte .= '<table class="nobordernopadding" width="100%">';
416 
417  // List of directories area
418  $texte .= '<tr><td>';
419  $texttitle = $langs->trans("ListOfDirectories");
420  $listofdir = explode(',', preg_replace('/[\r\n]+/', ',', trim($conf->global->PROJECT_ADDON_PDF_ODT_PATH)));
421  $listoffiles = array();
422  foreach ($listofdir as $key => $tmpdir) {
423  $tmpdir = trim($tmpdir);
424  $tmpdir = preg_replace('/DOL_DATA_ROOT/', DOL_DATA_ROOT, $tmpdir);
425  if (!$tmpdir) {
426  unset($listofdir[$key]);
427  continue;
428  }
429  if (!is_dir($tmpdir)) {
430  $texttitle .= img_warning($langs->trans("ErrorDirNotFound", $tmpdir), 0);
431  } else {
432  $tmpfiles = dol_dir_list($tmpdir, 'files', 0, '\.(ods|odt)');
433  if (count($tmpfiles)) {
434  $listoffiles = array_merge($listoffiles, $tmpfiles);
435  }
436  }
437  }
438  $texthelp = $langs->trans("ListOfDirectoriesForModelGenODT");
439  // Add list of substitution keys
440  $texthelp .= '<br>'.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'<br>';
441  $texthelp .= $langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it
442 
443  $texte .= $form->textwithpicto($texttitle, $texthelp, 1, 'help', '', 1);
444  $texte .= '<div><div style="display: inline-block; min-width: 100px; vertical-align: middle;">';
445  $texte .= '<textarea class="flat" cols="60" name="value1">';
446  $texte .= $conf->global->PROJECT_ADDON_PDF_ODT_PATH;
447  $texte .= '</textarea>';
448  $texte .= '</div><div style="display: inline-block; vertical-align: middle;">';
449  $texte .= '<input type="submit" class="button small reposition" name="modify" value="'.$langs->trans("Modify").'">';
450  $texte .= '<br></div></div>';
451 
452  // Scan directories
453  $nbofiles = count($listoffiles);
454  if (!empty($conf->global->PROJECT_ADDON_PDF_ODT_PATH)) {
455  $texte .= $langs->trans("NumberOfModelFilesFound").': <b>';
456  //$texte.=$nbofiles?'<a id="a_'.get_class($this).'" href="#">':'';
457  $texte .= $nbofiles;
458  //$texte.=$nbofiles?'</a>':'';
459  $texte .= '</b>';
460  }
461 
462  if ($nbofiles) {
463  $texte .= '<div id="div_'.get_class($this).'" class="hiddenx">';
464  // Show list of found files
465  foreach ($listoffiles as $file) {
466  $texte .= '- '.$file['name'].' <a href="'.DOL_URL_ROOT.'/document.php?modulepart=doctemplates&file=projects/'.urlencode(basename($file['name'])).'">'.img_picto('', 'listlight').'</a>';
467  $texte .= ' &nbsp; <a class="reposition" href="'.$_SERVER["PHP_SELF"].'?modulepart=doctemplates&keyforuploaddir=PROJECT_ADDON_PDF_ODT_PATH&action=deletefile&token='.newToken().'&file='.urlencode(basename($file['name'])).'">'.img_picto('', 'delete').'</a>';
468  $texte .= '<br>';
469  }
470  $texte .= '</div>';
471  }
472 
473  $texte .= '</td>';
474 
475  $texte .= '<td rowspan="2" class="tdtop hideonsmartphone">';
476  $texte .= '<span class="opacitymedium">';
477  $texte .= $langs->trans("ExampleOfDirectoriesForModelGen");
478  $texte .= '</span>';
479  $texte .= '</td>';
480  $texte .= '</tr>';
481 
482  $texte .= '</table>';
483  $texte .= '</form>';
484 
485  return $texte;
486  }
487 
488  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
497  public function write_file($object, $outputlangs, $srctemplatepath)
498  {
499  // phpcs:enable
500  global $user, $langs, $conf, $mysoc, $hookmanager;
501 
502  if (empty($srctemplatepath)) {
503  dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING);
504  return -1;
505  }
506 
507  // Add odtgeneration hook
508  if (!is_object($hookmanager)) {
509  include_once DOL_DOCUMENT_ROOT.'/core/class/hookmanager.class.php';
510  $hookmanager = new HookManager($this->db);
511  }
512  $hookmanager->initHooks(array('odtgeneration'));
513  global $action;
514 
515  if (!is_object($outputlangs)) {
516  $outputlangs = $langs;
517  }
518  $sav_charset_output = $outputlangs->charset_output;
519  $outputlangs->charset_output = 'UTF-8';
520 
521  // Load translation files required by the page
522  $outputlangs->loadLangs(array("main", "dict", "companies", "projects"));
523 
524  if ($conf->project->dir_output) {
525  // If $object is id instead of object
526  if (!is_object($object)) {
527  $id = $object;
528  $object = new Project($this->db);
529  $result = $object->fetch($id);
530  if ($result < 0) {
531  dol_print_error($this->db, $object->error);
532  return -1;
533  }
534  }
535 
536  $object->fetch_thirdparty();
537 
538  $dir = $conf->project->dir_output;
539  $objectref = dol_sanitizeFileName($object->ref);
540  if (!preg_match('/specimen/i', $objectref)) {
541  $dir .= "/".$objectref;
542  }
543  $file = $dir."/".$objectref.".odt";
544 
545  if (!file_exists($dir)) {
546  if (dol_mkdir($dir) < 0) {
547  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
548  return -1;
549  }
550  }
551 
552  if (file_exists($dir)) {
553  //print "srctemplatepath=".$srctemplatepath; // Src filename
554  $newfile = basename($srctemplatepath);
555  $newfiletmp = preg_replace('/\.od[ts]/i', '', $newfile);
556  $newfiletmp = preg_replace('/template_/i', '', $newfiletmp);
557  $newfiletmp = preg_replace('/modele_/i', '', $newfiletmp);
558  $newfiletmp = $objectref . '_' . $newfiletmp;
559  //$file=$dir.'/'.$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt';
560  // Get extension (ods or odt)
561  $newfileformat = substr($newfile, strrpos($newfile, '.') + 1);
562  if (getDolGlobalInt('MAIN_DOC_USE_TIMING')) {
563  $format = getDolGlobalInt('MAIN_DOC_USE_TIMING');
564  if ($format == '1') {
565  $format = '%Y%m%d%H%M%S';
566  }
567  $filename = $newfiletmp . '-' . dol_print_date(dol_now(), $format) . '.' . $newfileformat;
568  } else {
569  $filename = $newfiletmp . '.' . $newfileformat;
570  }
571  $file = $dir . '/' . $filename;
572  //print "newdir=".$dir;
573  //print "newfile=".$newfile;
574  //print "file=".$file;
575  //print "conf->societe->dir_temp=".$conf->societe->dir_temp;
576 
577  dol_mkdir($conf->project->dir_temp);
578  if (!is_writable($conf->project->dir_temp)) {
579  $this->error = $langs->transnoentities("ErrorFailedToWriteInTempDirectory", $conf->project->dir_temp);
580  dol_syslog('Error in write_file: ' . $this->error, LOG_ERR);
581  return -1;
582  }
583 
584  // If PROJECTLEADER contact defined on project, we use it
585  $usecontact = false;
586  $arrayidcontact = $object->getIdContact('external', 'PROJECTLEADER');
587  if (count($arrayidcontact) > 0) {
588  $usecontact = true;
589  $result = $object->fetch_contact($arrayidcontact[0]);
590  }
591 
592  // Recipient name
593  $contactobject = null;
594  if (!empty($usecontact)) {
595  // if we have a PROJECTLEADER contact and we dont use it as recipient we store the contact object for later use
596  $contactobject = $object->contact;
597  }
598 
599  $socobject = $object->thirdparty;
600 
601  // Make substitution
602  $substitutionarray = array(
603  '__FROM_NAME__' => $this->emetteur->name,
604  '__FROM_EMAIL__' => $this->emetteur->email,
605  );
606  complete_substitutions_array($substitutionarray, $langs, $object);
607  // Call the ODTSubstitution hook
608  $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$substitutionarray);
609  $reshook = $hookmanager->executeHooks('ODTSubstitution', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
610 
611  // Open and load template
612  require_once ODTPHP_PATH.'odf.php';
613  try {
614  $odfHandler = new Odf(
615  $srctemplatepath,
616  array(
617  'PATH_TO_TMP' => $conf->project->dir_temp,
618  'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy.
619  'DELIMITER_LEFT' => '{',
620  'DELIMITER_RIGHT' => '}'
621  )
622  );
623  } catch (Exception $e) {
624  $this->error = $e->getMessage();
625  dol_syslog($e->getMessage(), LOG_INFO);
626  return -1;
627  }
628  // After construction $odfHandler->contentXml contains content and
629  // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by
630  // [!-- BEGIN lines --]*[!-- END lines --]
631  //print html_entity_decode($odfHandler->__toString());
632  //print exit;
633 
634 
635  // Define substitution array
636  $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
637  $array_object_from_properties = $this->get_substitutionarray_each_var_object($object, $outputlangs);
638  $array_objet = $this->get_substitutionarray_object($object, $outputlangs);
639  $array_user = $this->get_substitutionarray_user($user, $outputlangs);
640  $array_soc = $this->get_substitutionarray_mysoc($mysoc, $outputlangs);
641  $array_thirdparty = $this->get_substitutionarray_thirdparty($socobject, $outputlangs);
642  $array_other = $this->get_substitutionarray_other($outputlangs);
643  // retrieve contact information for use in object as contact_xxx tags
644  $array_project_contact = array();
645  if ($usecontact && is_object($contactobject)) {
646  $array_project_contact = $this->get_substitutionarray_contact($contactobject, $outputlangs, 'contact');
647  }
648 
649  $tmparray = array_merge($substitutionarray, $array_object_from_properties, $array_user, $array_soc, $array_thirdparty, $array_objet, $array_other, $array_project_contact);
650  complete_substitutions_array($tmparray, $outputlangs, $object);
651 
652  // Call the ODTSubstitution hook
653  $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
654  $reshook = $hookmanager->executeHooks('ODTSubstitution', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
655 
656  foreach ($tmparray as $key => $value) {
657  try {
658  if (preg_match('/logo$/', $key)) { // Image
659  if (file_exists($value)) {
660  $odfHandler->setImage($key, $value);
661  } else {
662  $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8');
663  }
664  } else // Text
665  {
666  $odfHandler->setVars($key, $value, true, 'UTF-8');
667  }
668  } catch (OdfException $e) {
669  dol_syslog($e->getMessage(), LOG_INFO);
670  }
671  }
672 
673  // Replace tags of lines for tasks
674  try {
675  $listlines = $odfHandler->setSegment('tasks');
676 
677  $taskstatic = new Task($this->db);
678 
679  // Security check
680  $socid = 0;
681  if (!empty($object->fk_soc)) {
682  $socid = $object->fk_soc;
683  }
684 
685  $tasksarray = $taskstatic->getTasksArray(0, 0, $object->id, $socid, 0);
686 
687 
688  foreach ($tasksarray as $task) {
689  $tmparray = $this->get_substitutionarray_tasks($task, $outputlangs);
690  //complete_substitutions_array($tmparray, $outputlangs, $object, $task, "completesubstitutionarray_lines");
691  foreach ($tmparray as $key => $val) {
692  try {
693  $listlines->setVars($key, $val, true, 'UTF-8');
694  } catch (OdfException $e) {
695  dol_syslog($e->getMessage(), LOG_INFO);
696  } catch (SegmentException $e) {
697  dol_syslog($e->getMessage(), LOG_INFO);
698  }
699  }
700 
701  $taskobj = new Task($this->db);
702  $taskobj->fetch($task->id);
703 
704  // Replace tags of lines for contacts task
705  $sourcearray = array('internal', 'external');
706  $contact_arrray = array();
707  foreach ($sourcearray as $source) {
708  $contact_temp = $taskobj->liste_contact(-1, $source);
709  if ((is_array($contact_temp) && count($contact_temp) > 0)) {
710  $contact_arrray = array_merge($contact_arrray, $contact_temp);
711  }
712  }
713  if ((is_array($contact_arrray) && count($contact_arrray) > 0)) {
714  $listlinestaskres = $listlines->__get('tasksressources');
715 
716  foreach ($contact_arrray as $contact) {
717  if ($contact['source'] == 'internal') {
718  $objectdetail = new User($this->db);
719  $objectdetail->fetch($contact['id']);
720  $contact['socname'] = $mysoc->name;
721  } elseif ($contact['source'] == 'external') {
722  $objectdetail = new Contact($this->db);
723  $objectdetail->fetch($contact['id']);
724 
725  $soc = new Societe($this->db);
726  $soc->fetch($contact['socid']);
727  $contact['socname'] = $soc->name;
728  }
729  $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1);
730 
731  $tmparray = $this->get_substitutionarray_tasksressource($contact, $outputlangs);
732 
733  foreach ($tmparray as $key => $val) {
734  try {
735  $listlinestaskres->setVars($key, $val, true, 'UTF-8');
736  } catch (OdfException $e) {
737  dol_syslog($e->getMessage(), LOG_INFO);
738  } catch (SegmentException $e) {
739  dol_syslog($e->getMessage(), LOG_INFO);
740  }
741  }
742  $listlinestaskres->merge();
743  }
744  }
745 
746  //Time ressources
747  $sql = "SELECT t.rowid, t.element_date as task_date, t.element_duration as task_duration, t.fk_user, t.note";
748  $sql .= ", u.lastname, u.firstname, t.thm";
749  $sql .= " FROM ".MAIN_DB_PREFIX."element_time as t";
750  $sql .= " , ".MAIN_DB_PREFIX."user as u";
751  $sql .= " WHERE t.fk_element =".((int) $task->id);
752  $sql .= " AND t.elementtype = 'task'";
753  $sql .= " AND t.fk_user = u.rowid";
754  $sql .= " ORDER BY t.element_date DESC";
755 
756  $resql = $this->db->query($sql);
757  if ($resql) {
758  $num = $this->db->num_rows($resql);
759  $i = 0;
760  $tasks = array();
761  $row = array();
762  $listlinestasktime = $listlines->__get('taskstimes');
763  if (empty($num)) {
764  $row['rowid'] = '';
765  $row['task_date'] = '';
766  $row['task_duration'] = '';
767  $row['$tasktime'] = '';
768  $row['note'] = '';
769  $row['fk_user'] = '';
770  $row['name'] = '';
771  $row['firstname'] = '';
772  $row['fullcivname'] = '';
773  $row['amountht'] = '';
774  $row['amountttc'] = '';
775  $row['thm'] = '';
776  $tmparray = $this->get_substitutionarray_taskstime($row, $outputlangs);
777  foreach ($tmparray as $key => $val) {
778  try {
779  $listlinestasktime->setVars($key, $val, true, 'UTF-8');
780  } catch (OdfException $e) {
781  dol_syslog($e->getMessage(), LOG_INFO);
782  } catch (SegmentException $e) {
783  dol_syslog($e->getMessage(), LOG_INFO);
784  }
785  }
786  $listlinestasktime->merge();
787  }
788  while ($i < $num) {
789  $row = $this->db->fetch_array($resql);
790  if (!empty($row['fk_user'])) {
791  $objectdetail = new User($this->db);
792  $objectdetail->fetch($row['fk_user']);
793  $row['fullcivname'] = $objectdetail->getFullName($outputlangs, 1);
794  } else {
795  $row['fullcivname'] = '';
796  }
797 
798  if (!empty($row['thm'])) {
799  $row['amountht'] = ($row['task_duration'] / 3600) * $row['thm'];
800  $defaultvat = get_default_tva($mysoc, $mysoc);
801  $row['amountttc'] = price2num($row['amountht'] * (1 + ($defaultvat / 100)), 'MT');
802  } else {
803  $row['amountht'] = 0;
804  $row['amountttc'] = 0;
805  $row['thm'] = 0;
806  }
807 
808  $tmparray = $this->get_substitutionarray_taskstime($row, $outputlangs);
809 
810  foreach ($tmparray as $key => $val) {
811  try {
812  $listlinestasktime->setVars($key, $val, true, 'UTF-8');
813  } catch (OdfException $e) {
814  dol_syslog($e->getMessage(), LOG_INFO);
815  } catch (SegmentException $e) {
816  dol_syslog($e->getMessage(), LOG_INFO);
817  }
818  }
819  $listlinestasktime->merge();
820  $i++;
821  }
822  $this->db->free($resql);
823  }
824 
825 
826  // Replace tags of project files
827  $listtasksfiles = $listlines->__get('tasksfiles');
828 
829  $upload_dir = $conf->project->dir_output.'/'.dol_sanitizeFileName($object->ref).'/'.dol_sanitizeFileName($task->ref);
830  $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', 'name', SORT_ASC, 1);
831 
832 
833  foreach ($filearray as $filedetail) {
834  $tmparray = $this->get_substitutionarray_task_file($filedetail, $outputlangs);
835  //dol_syslog(get_class($this).'::main $tmparray'.var_export($tmparray,true));
836  foreach ($tmparray as $key => $val) {
837  try {
838  $listtasksfiles->setVars($key, $val, true, 'UTF-8');
839  } catch (OdfException $e) {
840  dol_syslog($e->getMessage(), LOG_INFO);
841  } catch (SegmentException $e) {
842  dol_syslog($e->getMessage(), LOG_INFO);
843  }
844  }
845  $listtasksfiles->merge();
846  }
847  $listlines->merge();
848  }
849  $odfHandler->mergeSegment($listlines);
850  } catch (OdfException $e) {
851  $ExceptionTrace = $e->getTrace();
852  // no segment defined on ODT is not an error
853  if ($ExceptionTrace[0]['function'] != 'setSegment') {
854  $this->error = $e->getMessage();
855  dol_syslog($this->error, LOG_WARNING);
856  return -1;
857  }
858  }
859 
860  // Replace tags of project files
861  try {
862  $listlines = $odfHandler->setSegment('projectfiles');
863 
864  $upload_dir = $conf->project->dir_output.'/'.dol_sanitizeFileName($object->ref);
865  $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', 'name', SORT_ASC, 1);
866 
867  foreach ($filearray as $filedetail) {
868  //dol_syslog(get_class($this).'::main $filedetail'.var_export($filedetail,true));
869  $tmparray = $this->get_substitutionarray_project_file($filedetail, $outputlangs);
870 
871  foreach ($tmparray as $key => $val) {
872  try {
873  $listlines->setVars($key, $val, true, 'UTF-8');
874  } catch (OdfException $e) {
875  dol_syslog($e->getMessage(), LOG_INFO);
876  } catch (SegmentException $e) {
877  dol_syslog($e->getMessage(), LOG_INFO);
878  }
879  }
880  $listlines->merge();
881  }
882  $odfHandler->mergeSegment($listlines);
883  } catch (OdfException $e) {
884  $this->error = $e->getMessage();
885  dol_syslog($this->error, LOG_WARNING);
886  return -1;
887  }
888 
889  // Replace tags of lines for contacts
890  $sourcearray = array('internal', 'external');
891  $contact_arrray = array();
892  foreach ($sourcearray as $source) {
893  $contact_temp = $object->liste_contact(-1, $source);
894  if ((is_array($contact_temp) && count($contact_temp) > 0)) {
895  $contact_arrray = array_merge($contact_arrray, $contact_temp);
896  }
897  }
898  if ((is_array($contact_arrray) && count($contact_arrray) > 0)) {
899  try {
900  $listlines = $odfHandler->setSegment('projectcontacts');
901 
902  foreach ($contact_arrray as $contact) {
903  if ($contact['source'] == 'internal') {
904  $objectdetail = new User($this->db);
905  $objectdetail->fetch($contact['id']);
906  $contact['socname'] = $mysoc->name;
907  } elseif ($contact['source'] == 'external') {
908  $objectdetail = new Contact($this->db);
909  $objectdetail->fetch($contact['id']);
910 
911  $soc = new Societe($this->db);
912  $soc->fetch($contact['socid']);
913  $contact['socname'] = $soc->name;
914  }
915  $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1);
916 
917  $tmparray = $this->get_substitutionarray_project_contacts($contact, $outputlangs);
918  foreach ($tmparray as $key => $val) {
919  try {
920  $listlines->setVars($key, $val, true, 'UTF-8');
921  } catch (OdfException $e) {
922  dol_syslog($e->getMessage(), LOG_INFO);
923  } catch (SegmentException $e) {
924  dol_syslog($e->getMessage(), LOG_INFO);
925  }
926  }
927  $listlines->merge();
928  }
929  $odfHandler->mergeSegment($listlines);
930  } catch (OdfException $e) {
931  $this->error = $e->getMessage();
932  dol_syslog($this->error, LOG_WARNING);
933  return -1;
934  }
935  }
936 
937  //List of referent
938 
939  $listofreferent = array(
940  'propal' => array(
941  'title' => "ListProposalsAssociatedProject",
942  'class' => 'Propal',
943  'table' => 'propal',
944  'test' => isModEnabled('propal') && $user->hasRight('propal', 'lire')
945  ),
946  'order' => array(
947  'title' => "ListOrdersAssociatedProject",
948  'class' => 'Commande',
949  'table' => 'commande',
950  'test' => isModEnabled('commande') && $user->hasRight('commande', 'lire')
951  ),
952  'invoice' => array(
953  'title' => "ListInvoicesAssociatedProject",
954  'class' => 'Facture',
955  'table' => 'facture',
956  'test' => isModEnabled('facture') && $user->hasRight('facture', 'lire')
957  ),
958  'invoice_predefined' => array(
959  'title' => "ListPredefinedInvoicesAssociatedProject",
960  'class' => 'FactureRec',
961  'table' => 'facture_rec',
962  'test' => isModEnabled('facture') && $user->hasRight('facture', 'lire')
963  ),
964  'proposal_supplier' => array(
965  'title' => "ListSupplierProposalsAssociatedProject",
966  'class' => 'SupplierProposal',
967  'table' => 'supplier_proposal',
968  'test' => isModEnabled('supplier_proposal') && $user->rights->supplier_proposal->lire
969  ),
970  'order_supplier' => array(
971  'title' => "ListSupplierOrdersAssociatedProject",
972  'table' => 'commande_fournisseur',
973  'class' => 'CommandeFournisseur',
974  'test' => (isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->commande->lire) || (isModEnabled("supplier_order") && $user->rights->supplier_order->lire)
975  ),
976  'invoice_supplier' => array(
977  'title' => "ListSupplierInvoicesAssociatedProject",
978  'table' => 'facture_fourn',
979  'class' => 'FactureFournisseur',
980  'test' => (isModEnabled("fournisseur") && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->rights->fournisseur->facture->lire) || (isModEnabled("supplier_invoice") && $user->rights->supplier_invoice->lire)
981  ),
982  'contract' => array(
983  'title' => "ListContractAssociatedProject",
984  'class' => 'Contrat',
985  'table' => 'contrat',
986  'test' => isModEnabled('contrat') && $user->hasRight('contrat', 'lire')
987  ),
988  'intervention' => array(
989  'title' => "ListFichinterAssociatedProject",
990  'class' => 'Fichinter',
991  'table' => 'fichinter',
992  'disableamount' => 1,
993  'test' => isModEnabled('ficheinter') && $user->hasRight('ficheinter', 'lire')
994  ),
995  'shipping' => array(
996  'title' => "ListShippingAssociatedProject",
997  'class' => 'Expedition',
998  'table' => 'expedition',
999  'disableamount' => 1,
1000  'test' => isModEnabled('expedition') && $user->rights->expedition->lire
1001  ),
1002  'trip' => array(
1003  'title' => "ListTripAssociatedProject",
1004  'class' => 'Deplacement',
1005  'table' => 'deplacement',
1006  'disableamount' => 1,
1007  'test' => isModEnabled('deplacement') && $user->rights->deplacement->lire
1008  ),
1009  'expensereport' => array(
1010  'title' => "ListExpenseReportsAssociatedProject",
1011  'class' => 'ExpenseReportLine',
1012  'table' => 'expensereport_det',
1013  'test' => isModEnabled('expensereport') && $user->rights->expensereport->lire
1014  ),
1015  'donation' => array(
1016  'title' => "ListDonationsAssociatedProject",
1017  'class' => 'Don',
1018  'table' => 'don',
1019  'test' => isModEnabled('don') && $user->rights->don->lire
1020  ),
1021  'loan' => array(
1022  'title' => "ListLoanAssociatedProject",
1023  'class' => 'Loan',
1024  'table' => 'loan',
1025  'test' => isModEnabled('loan') && $user->rights->loan->read
1026  ),
1027  'chargesociales' => array(
1028  'title' => "ListSocialContributionAssociatedProject",
1029  'class' => 'ChargeSociales',
1030  'table' => 'chargesociales',
1031  'urlnew' => DOL_URL_ROOT.'/compta/sociales/card.php?action=create&projectid='.$object->id,
1032  'test' => isModEnabled('tax') && $user->rights->tax->charges->lire
1033  ),
1034  'stock_mouvement' => array(
1035  'title' => "ListMouvementStockProject",
1036  'class' => 'MouvementStock',
1037  'table' => 'stock_mouvement',
1038  'test' => (isModEnabled('stock') && $user->rights->stock->mouvement->lire && !empty($conf->global->STOCK_MOVEMENT_INTO_PROJECT_OVERVIEW))
1039  ),
1040  'agenda' => array(
1041  'title' => "ListActionsAssociatedProject",
1042  'class' => 'ActionComm',
1043  'table' => 'actioncomm',
1044  'disableamount' => 1,
1045  'test' => isModEnabled('agenda') && $user->rights->agenda->allactions->lire
1046  ),
1047  );
1048 
1049  //Insert reference
1050  try {
1051  $listlines = $odfHandler->setSegment('projectrefs');
1052 
1053  foreach ($listofreferent as $keyref => $valueref) {
1054  $title = $valueref['title'];
1055  $tablename = $valueref['table'];
1056  $classname = $valueref['class'];
1057  $qualified = $valueref['test'];
1058  if ($qualified) {
1059  $elementarray = $object->get_element_list($keyref, $tablename);
1060  if (count($elementarray) > 0 && is_array($elementarray)) {
1061  $total_ht = 0;
1062  $total_ttc = 0;
1063  $num = count($elementarray);
1064  for ($i = 0; $i < $num; $i++) {
1065  $ref_array = array();
1066  $ref_array['type'] = $langs->trans($classname);
1067 
1068  $element = new $classname($this->db);
1069  $element->fetch($elementarray[$i]);
1070  $element->fetch_thirdparty();
1071 
1072  //Ref object
1073  $ref_array['ref'] = $element->ref;
1074 
1075  //Date object
1076  $dateref = $element->date;
1077  if (empty($dateref)) {
1078  $dateref = $element->datep;
1079  }
1080  if (empty($dateref)) {
1081  $dateref = $element->date_contrat;
1082  }
1083  $ref_array['date'] = $dateref;
1084 
1085  //Soc object
1086  if (is_object($element->thirdparty)) {
1087  $ref_array['socname'] = $element->thirdparty->name;
1088  } else {
1089  $ref_array['socname'] = '';
1090  }
1091 
1092  //Amount object
1093  if (empty($valueref['disableamount'])) {
1094  if (!empty($element->total_ht)) {
1095  $ref_array['amountht'] = $element->total_ht;
1096  $ref_array['amountttc'] = $element->total_ttc;
1097  } else {
1098  $ref_array['amountht'] = 0;
1099  $ref_array['amountttc'] = 0;
1100  }
1101  } else {
1102  $ref_array['amountht'] = '';
1103  $ref_array['amountttc'] = '';
1104  }
1105 
1106  $ref_array['status'] = $element->getLibStatut(0);
1107 
1108  $tmparray = $this->get_substitutionarray_project_reference($ref_array, $outputlangs);
1109 
1110  foreach ($tmparray as $key => $val) {
1111  try {
1112  $listlines->setVars($key, $val, true, 'UTF-8');
1113  } catch (OdfException $e) {
1114  dol_syslog($e->getMessage(), LOG_INFO);
1115  } catch (SegmentException $e) {
1116  dol_syslog($e->getMessage(), LOG_INFO);
1117  }
1118  }
1119  $listlines->merge();
1120  }
1121  }
1122  }
1123  $odfHandler->mergeSegment($listlines);
1124  }
1125  } catch (OdfException $e) {
1126  $this->error = $e->getMessage();
1127  dol_syslog($this->error, LOG_WARNING);
1128  return -1;
1129  }
1130 
1131  // Replace labels translated
1132  $tmparray = $outputlangs->get_translations_for_substitutions();
1133  foreach ($tmparray as $key => $value) {
1134  try {
1135  $odfHandler->setVars($key, $value, true, 'UTF-8');
1136  } catch (OdfException $e) {
1137  dol_syslog($e->getMessage(), LOG_INFO);
1138  }
1139  }
1140 
1141  // Call the beforeODTSave hook
1142  $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
1143  $reshook = $hookmanager->executeHooks('beforeODTSave', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1144 
1145 
1146  // Write new file
1147  if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
1148  try {
1149  $odfHandler->exportAsAttachedPDF($file);
1150  } catch (Exception $e) {
1151  $this->error = $e->getMessage();
1152  return -1;
1153  }
1154  } else {
1155  try {
1156  $odfHandler->saveToDisk($file);
1157  } catch (Exception $e) {
1158  $this->error = $e->getMessage();
1159  dol_syslog($e->getMessage(), LOG_INFO);
1160  return -1;
1161  }
1162  }
1163  $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
1164  $reshook = $hookmanager->executeHooks('afterODTCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
1165 
1166  dolChmod($file);
1167 
1168  $odfHandler = null; // Destroy object
1169 
1170  $this->result = array('fullpath'=>$file);
1171 
1172  return 1; // Success
1173  } else {
1174  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
1175  return -1;
1176  }
1177  }
1178 
1179  return -1;
1180  }
1181 }
get_substitutionarray_each_var_object(&$object, $outputlangs, $recursive=1)
Define array with couple substitution key => substitution value.
get_substitutionarray_mysoc($mysoc, $outputlangs)
Define array with couple substitution key => substitution value.
get_substitutionarray_contact($object, $outputlangs, $array_key='object')
Define array with couple substitution key => substitution value.
get_substitutionarray_other($outputlangs)
Define array with couple substitution key => substitution value.
fill_substitutionarray_with_extrafields($object, $array_to_fill, $extrafields, $array_key, $outputlangs)
Fill array with couple extrafield key => extrafield value Note that vars into substitutions array are...
get_substitutionarray_thirdparty($object, $outputlangs, $array_key='company')
Define array with couple substitution key => substitution value For example {company_name},...
get_substitutionarray_user($user, $outputlangs)
Define array with couple substitution key => substitution value.
Class to manage contact/addresses.
Class to manage standard extra fields.
Class to manage generation of HTML components Only common components must be here.
Class to manage hooks.
Parent class for projects models.
Class to manage projects.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage tasks.
Definition: task.class.php:40
Class to manage Dolibarr users.
Definition: user.class.php:48
Class to build documents using ODF templates generator.
get_substitutionarray_tasks(Task $task, $outputlangs)
Define array with couple substitution key => substitution value.
get_substitutionarray_task_file($file, $outputlangs)
Define array with couple substitution key => substitution value.
get_substitutionarray_tasksressource($taskressource, $outputlangs)
Define array with couple substitution key => substitution value.
get_substitutionarray_project_file($file, $outputlangs)
Define array with couple substitution key => substitution value.
get_substitutionarray_taskstime($tasktime, $outputlangs)
Define array with couple substitution key => substitution value.
get_substitutionarray_project_contacts($contact, $outputlangs)
Define array with couple substitution key => substitution value.
get_substitutionarray_object($object, $outputlangs, $array_key='object')
Define array with couple substitution key => substitution value.
write_file($object, $outputlangs, $srctemplatepath)
Function to build a document on disk using the generic odt module.
get_substitutionarray_project_reference($refdetail, $outputlangs)
Define array with couple substitution key => substitution value.
info($langs)
Return description of a module.
if(isModEnabled('facture') && $user->hasRight('facture', 'lire')) if((isModEnabled('fournisseur') &&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD) && $user->hasRight("fournisseur", "facture", "lire"))||(isModEnabled('supplier_invoice') && $user->hasRight("supplier_invoice", "lire"))) if(isModEnabled('don') && $user->hasRight('don', 'lire')) if(isModEnabled('tax') &&!empty($user->rights->tax->charges->lire)) if(isModEnabled('facture') &&isModEnabled('commande') && $user->hasRight("commande", "lire") &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) $sql
Social contributions to pay.
Definition: index.php:746
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
convertSecondToTime($iSecond, $format='all', $lengthOfDay=86400, $lengthOfWeek=7)
Return, in clear text, value of a number of seconds in days, hours and minutes.
Definition: date.lib.php:239
print *****$script_file(".$version.") pid cd cd cd description as description
Only used if Module[ID]Desc translation string is not found.
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0, $nbsecondsold=0)
Scan a directory and return a list of files/directories.
Definition: files.lib.php:62
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
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='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
dolChmod($filepath, $newmask='')
Change mod of a file.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
newToken()
Return the value of token currently saved into session with name 'newtoken'.
complete_substitutions_array(&$substitutionarray, $outputlangs, $object=null, $parameters=null, $callfunc="completesubstitutionarray")
Complete the $substitutionarray with more entries coming from external module that had set the "subst...
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $object=null, $include=null)
Return array of possible common substitutions.
isModEnabled($module)
Is Dolibarr module enabled.
get_default_tva(Societe $thirdparty_seller, Societe $thirdparty_buyer, $idprod=0, $idprodfournprice=0)
Function that return vat rate of a product line (according to seller, buyer and product vat rate) VAT...
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:120
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition: repair.php:123