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