dolibarr  19.0.0-dev
doc_generic_task_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  * 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.'/core/modules/project/task/modules_task.php';
32 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
33 require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php';
34 require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php';
35 require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
36 require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php';
37 require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php';
38 require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
39 require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
40 require_once DOL_DOCUMENT_ROOT.'/core/lib/doc.lib.php';
41 require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
42 if (isModEnabled("propal")) {
43  require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
44 }
45 if (isModEnabled('facture')) {
46  require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
47 }
48 if (isModEnabled('facture')) {
49  require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php';
50 }
51 if (isModEnabled('commande')) {
52  require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
53 }
54 if (isModEnabled("supplier_invoice")) {
55  require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
56 }
57 if (isModEnabled("supplier_order")) {
58  require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
59 }
60 if (isModEnabled('contrat')) {
61  require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
62 }
63 if (isModEnabled('ficheinter')) {
64  require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
65 }
66 if (isModEnabled('deplacement')) {
67  require_once DOL_DOCUMENT_ROOT.'/compta/deplacement/class/deplacement.class.php';
68 }
69 if (isModEnabled('agenda')) {
70  require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
71 }
72 
73 
78 {
83  public $emetteur;
84 
89  public $version = 'dolibarr';
90 
91 
97  public function __construct($db)
98  {
99  global $conf, $langs, $mysoc;
100 
101  // Load translation files required by the page
102  $langs->loadLangs(array("main", "companies"));
103 
104  $this->db = $db;
105  $this->name = "ODT templates";
106  $this->description = $langs->trans("DocumentModelOdt");
107  $this->scandir = 'PROJECT_TASK_ADDON_PDF_ODT_PATH'; // Name of constant that is used to save list of directories to scan
108 
109  // Page size for A4 format
110  $this->type = 'odt';
111  $this->page_largeur = 0;
112  $this->page_hauteur = 0;
113  $this->format = array($this->page_largeur, $this->page_hauteur);
114  $this->marge_gauche = 0;
115  $this->marge_droite = 0;
116  $this->marge_haute = 0;
117  $this->marge_basse = 0;
118 
119  $this->option_logo = 1; // Display logo
120  $this->option_tva = 0; // Manage the vat option COMMANDE_TVAOPTION
121  $this->option_modereg = 0; // Display payment mode
122  $this->option_condreg = 0; // Display payment terms
123  $this->option_multilang = 0; // Available in several languages
124  $this->option_escompte = 0; // Displays if there has been a discount
125  $this->option_credit_note = 0; // Support credit notes
126  $this->option_freetext = 1; // Support add of a personalised text
127  $this->option_draft_watermark = 0; // Support add of a watermark on drafts
128 
129  // Get source company
130  $this->emetteur = $mysoc;
131  if (!$this->emetteur->country_code) {
132  $this->emetteur->country_code = substr($langs->defaultlang, -2); // By default, if was not defined
133  }
134  }
135 
136 
137  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
146  public function get_substitutionarray_object($object, $outputlangs, $array_key = 'object')
147  {
148  // phpcs:enable
149  global $conf, $extrafields;
150 
151  $resarray = array(
152  $array_key.'_id'=>$object->id,
153  $array_key.'_ref'=>$object->ref,
154  $array_key.'_title'=>$object->title,
155  $array_key.'_description'=>$object->description,
156  $array_key.'_date_creation'=>dol_print_date($object->date_c, 'day'),
157  $array_key.'_date_modification'=>dol_print_date($object->date_m, 'day'),
158  $array_key.'_date_start'=>dol_print_date($object->date_start, 'day'),
159  $array_key.'_date_end'=>dol_print_date($object->date_end, 'day'),
160  $array_key.'_note_private'=>$object->note_private,
161  $array_key.'_note_public'=>$object->note_public,
162  $array_key.'_public'=>$object->public,
163  $array_key.'_statut'=>$object->getLibStatut()
164  );
165 
166  // Retrieve extrafields
167  if (is_array($object->array_options) && count($object->array_options)) {
168  $object->fetch_optionals();
169 
170  $resarray = $this->fill_substitutionarray_with_extrafields($object, $resarray, $extrafields, $array_key, $outputlangs);
171  }
172 
173  return $resarray;
174  }
175 
176  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
185  public function get_substitutionarray_tasks($task, $outputlangs, $array_key = 'task')
186  {
187  // phpcs:enable
188  global $conf, $extrafields;
189 
190  $resarray = array(
191  'task_ref'=>$task->ref,
192  'task_fk_project'=>$task->fk_project,
193  'task_projectref'=>$task->projectref,
194  'task_projectlabel'=>$task->projectlabel,
195  'task_label'=>$task->label,
196  'task_description'=>$task->description,
197  'task_fk_parent'=>$task->fk_task_parent,
198  'task_duration'=>$task->duration_effective,
199  'task_duration_formated'=>convertSecondToTime($task->duration_effective, 'allhourmin'),
200  'task_planned_workload'=>$task->planned_workload,
201  'task_planned_workload_formated'=>convertSecondToTime($task->planned_workload, 'allhourmin'),
202  'task_progress'=>$task->progress,
203  'task_public'=>$task->public,
204  'task_date_start'=>dol_print_date($task->date_start, 'day'),
205  'task_date_end'=>dol_print_date($task->date_end, 'day'),
206  'task_note_private'=>$task->note_private,
207  'task_note_public'=>$task->note_public
208  );
209 
210  // Retrieve extrafields
211  if (is_array($task->array_options) && count($task->array_options)) {
212  $task->fetch_optionals();
213 
214  $resarray = $this->fill_substitutionarray_with_extrafields($task, $resarray, $extrafields, $array_key, $outputlangs);
215  }
216 
217  return $resarray;
218  }
219 
220  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
228  public function get_substitutionarray_project_contacts($contact, $outputlangs)
229  {
230  // phpcs:enable
231  global $conf;
232 
233  return array(
234  'projcontacts_id'=>$contact['id'],
235  'projcontacts_rowid'=>$contact['rowid'],
236  'projcontacts_role'=>$contact['libelle'],
237  'projcontacts_lastname'=>$contact['lastname'],
238  'projcontacts_firstname'=>$contact['firstname'],
239  'projcontacts_fullcivname'=>$contact['fullname'],
240  'projcontacts_socname'=>$contact['socname'],
241  'projcontacts_email'=>$contact['email']
242  );
243  }
244 
245  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
253  public function get_substitutionarray_project_file($file, $outputlangs)
254  {
255  // phpcs:enable
256  global $conf;
257 
258  return array(
259  'projfile_name'=>$file['name'],
260  'projfile_date'=>dol_print_date($file['date'], 'day'),
261  'projfile_size'=>$file['size']
262  );
263  }
264 
265  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
273  public function get_substitutionarray_project_reference($refdetail, $outputlangs)
274  {
275  // phpcs:enable
276  global $conf;
277 
278  return array(
279  'projref_type'=>$refdetail['type'],
280  'projref_ref'=>$refdetail['ref'],
281  'projref_date'=>dol_print_date($refdetail['date'], 'day'),
282  'projref_socname'=>$refdetail['socname'],
283  'projref_amountht'=>price($refdetail['amountht'], 0, $outputlangs),
284  'projref_amountttc'=>price($refdetail['amountttc'], 0, $outputlangs),
285  'projref_status'=>$refdetail['status']
286  );
287  }
288 
289  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
297  public function get_substitutionarray_tasksressource($taskressource, $outputlangs)
298  {
299  // phpcs:enable
300  global $conf;
301  //dol_syslog(get_class($this).'::get_substitutionarray_tasksressource taskressource='.var_export($taskressource,true),LOG_DEBUG);
302  return array(
303  'taskressource_rowid'=>$taskressource['rowid'],
304  'taskressource_role'=>$taskressource['libelle'],
305  'taskressource_lastname'=>$taskressource['lastname'],
306  'taskressource_firstname'=>$taskressource['firstname'],
307  'taskressource_fullcivname'=>$taskressource['fullname'],
308  'taskressource_socname'=>$taskressource['socname'],
309  'taskressource_email'=>$taskressource['email']
310  );
311  }
312 
313  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
321  public function get_substitutionarray_taskstime($tasktime, $outputlangs)
322  {
323  // phpcs:enable
324  global $conf;
325 
326  return array(
327  'tasktime_rowid'=>$tasktime['rowid'],
328  'tasktime_task_date'=>dol_print_date($tasktime['task_date'], 'day'),
329  'tasktime_task_duration'=>convertSecondToTime($tasktime['task_duration'], 'all'),
330  'tasktime_note'=>$tasktime['note'],
331  'tasktime_fk_user'=>$tasktime['fk_user'],
332  'tasktime_user_name'=>$tasktime['name'],
333  'tasktime_user_first'=>$tasktime['firstname'],
334  'tasktime_fullcivname'=>$tasktime['fullcivname']
335  );
336  }
337 
338  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
346  public function get_substitutionarray_task_file($file, $outputlangs)
347  {
348  // phpcs:enable
349  global $conf;
350 
351  return array(
352  'tasksfile_name'=>$file['name'],
353  'tasksfile_date'=>dol_print_date($file['date'], 'day'),
354  'tasksfile_size'=>$file['size']
355  );
356  }
357 
358 
365  public function info($langs)
366  {
367  global $conf, $langs;
368 
369  // Load translation files required by the page
370  $langs->loadLangs(array("errors", "companies"));
371 
372  $form = new Form($this->db);
373 
374  $texte = $this->description.".<br>\n";
375  $texte .= '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
376  $texte .= '<input type="hidden" name="token" value="'.newToken().'">';
377  $texte .= '<input type="hidden" name="page_y" value="">';
378  $texte .= '<input type="hidden" name="action" value="setModuleOptions">';
379  $texte .= '<input type="hidden" name="param1" value="PROJECT_TASK_ADDON_PDF_ODT_PATH">';
380  $texte .= '<table class="nobordernopadding" width="100%">';
381 
382  // List of directories area
383  $texte .= '<tr><td>';
384  $texttitle = $langs->trans("ListOfDirectories");
385  $listofdir = explode(',', preg_replace('/[\r\n]+/', ',', trim($conf->global->PROJECT_TASK_ADDON_PDF_ODT_PATH)));
386  $listoffiles = array();
387  foreach ($listofdir as $key => $tmpdir) {
388  $tmpdir = trim($tmpdir);
389  $tmpdir = preg_replace('/DOL_DATA_ROOT/', DOL_DATA_ROOT, $tmpdir);
390  if (!$tmpdir) {
391  unset($listofdir[$key]);
392  continue;
393  }
394  if (!is_dir($tmpdir)) {
395  $texttitle .= img_warning($langs->trans("ErrorDirNotFound", $tmpdir), 0);
396  } else {
397  $tmpfiles = dol_dir_list($tmpdir, 'files', 0, '\.(ods|odt)');
398  if (count($tmpfiles)) {
399  $listoffiles = array_merge($listoffiles, $tmpfiles);
400  }
401  }
402  }
403  $texthelp = $langs->trans("ListOfDirectoriesForModelGenODT");
404  // Add list of substitution keys
405  $texthelp .= '<br>'.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'<br>';
406  $texthelp .= $langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it
407 
408  $texte .= $form->textwithpicto($texttitle, $texthelp, 1, 'help', '', 1);
409  $texte .= '<div><div style="display: inline-block; min-width: 100px; vertical-align: middle;">';
410  $texte .= '<textarea class="flat" cols="60" name="value1">';
411  $texte .= $conf->global->PROJECT_TASK_ADDON_PDF_ODT_PATH;
412  $texte .= '</textarea>';
413  $texte .= '</div><div style="display: inline-block; vertical-align: middle;">';
414  $texte .= '<input type="submit" class="button small reposition" name="modify" value="'.$langs->trans("Modify").'">';
415  $texte .= '<br></div></div>';
416 
417  // Scan directories
418  $nbofiles = count($listoffiles);
419  if (!empty($conf->global->PROJECT_TASK_ADDON_PDF_ODT_PATH)) {
420  $texte .= $langs->trans("NumberOfModelFilesFound").': <b>';
421  //$texte.=$nbofiles?'<a id="a_'.get_class($this).'" href="#">':'';
422  $texte .= $nbofiles;
423  //$texte.=$nbofiles?'</a>':'';
424  $texte .= '</b>';
425  }
426 
427  if ($nbofiles) {
428  $texte .= '<div id="div_'.get_class($this).'" class="hiddenx">';
429  // Show list of found files
430  foreach ($listoffiles as $file) {
431  $texte .= '- '.$file['name'].' <a href="'.DOL_URL_ROOT.'/document.php?modulepart=doctemplates&file=tasks/'.urlencode(basename($file['name'])).'">'.img_picto('', 'listlight').'</a>';
432  $texte .= ' &nbsp; <a class="reposition" href="'.$_SERVER["PHP_SELF"].'?modulepart=doctemplates&keyforuploaddir=PROJECT_TASK_ADDON_PDF_ODT_PATH&action=deletefile&token='.newToken().'&file='.urlencode(basename($file['name'])).'">'.img_picto('', 'delete').'</a>';
433  $texte .= '<br>';
434  }
435  $texte .= '</div>';
436  }
437 
438  $texte .= '</td>';
439 
440  $texte .= '<td rowspan="2" class="tdtop hideonsmartphone">';
441  $texte .= '<span class="opacitymedium">';
442  $texte .= $langs->trans("ExampleOfDirectoriesForModelGen");
443  $texte .= '</span>';
444  $texte .= '</td>';
445  $texte .= '</tr>';
446 
447  $texte .= '</table>';
448  $texte .= '</form>';
449 
450  return $texte;
451  }
452 
453  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
462  public function write_file($object, $outputlangs, $srctemplatepath)
463  {
464  // phpcs:enable
465  global $user, $langs, $conf, $mysoc, $hookmanager;
466 
467  if (empty($srctemplatepath)) {
468  dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING);
469  return -1;
470  }
471 
472  if (!is_object($outputlangs)) {
473  $outputlangs = $langs;
474  }
475  $sav_charset_output = $outputlangs->charset_output;
476  $outputlangs->charset_output = 'UTF-8';
477 
478  // Load translation files required by the page
479  $outputlangs->loadLangs(array("main", "dict", "companies", "projects"));
480 
481  if ($conf->project->dir_output) {
482  // If $object is id instead of object
483  if (!is_object($object)) {
484  $id = $object;
485  $object = new Task($this->db);
486  $result = $object->fetch($id);
487  if ($result < 0) {
488  dol_print_error($this->db, $object->error);
489  return -1;
490  }
491  }
492  $project = new Project($this->db);
493  $project->fetch($object->fk_project);
494  $project->fetch_thirdparty();
495 
496  $dir = $conf->project->dir_output."/".$project->ref."/";
497  $objectref = dol_sanitizeFileName($object->ref);
498  if (!preg_match('/specimen/i', $objectref)) {
499  $dir .= "/".$objectref;
500  }
501  $file = $dir."/".$objectref.".odt";
502 
503  if (!file_exists($dir)) {
504  if (dol_mkdir($dir) < 0) {
505  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
506  return -1;
507  }
508  }
509 
510 
511  if (file_exists($dir)) {
512  //print "srctemplatepath=".$srctemplatepath; // Src filename
513  $newfile = basename($srctemplatepath);
514  $newfiletmp = preg_replace('/\.(ods|odt)/i', '', $newfile);
515  $newfiletmp = preg_replace('/template_/i', '', $newfiletmp);
516  $newfiletmp = preg_replace('/modele_/i', '', $newfiletmp);
517  $newfiletmp = $objectref . '_' . $newfiletmp;
518  //$file=$dir.'/'.$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt';
519  $file = $dir . '/' . $newfiletmp . '.odt';
520  //print "newdir=".$dir;
521  //print "newfile=".$newfile;
522  //print "file=".$file;
523  //print "conf->societe->dir_temp=".$conf->societe->dir_temp;
524 
525  dol_mkdir($conf->project->dir_temp);
526  if (!is_writable($conf->project->dir_temp)) {
527  $this->error = $langs->transnoentities("ErrorFailedToWriteInTempDirectory", $conf->project->dir_temp);
528  dol_syslog('Error in write_file: ' . $this->error, LOG_ERR);
529  return -1;
530  }
531 
532  $socobject = $project->thirdparty;
533 
534  // Make substitution
535  $substitutionarray = array(
536  '__FROM_NAME__' => $this->emetteur->name,
537  '__FROM_EMAIL__' => $this->emetteur->email,
538  );
539  complete_substitutions_array($substitutionarray, $langs, $object);
540  // Call the ODTSubstitution hook
541  $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
542  $reshook = $hookmanager->executeHooks('ODTSubstitution', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
543 
544  // Open and load template
545  require_once ODTPHP_PATH.'odf.php';
546  try {
547  $odfHandler = new Odf(
548  $srctemplatepath,
549  array(
550  'PATH_TO_TMP' => $conf->project->dir_temp,
551  'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy.
552  'DELIMITER_LEFT' => '{',
553  'DELIMITER_RIGHT' => '}'
554  )
555  );
556  } catch (Exception $e) {
557  $this->error = $e->getMessage();
558  return -1;
559  }
560  // After construction $odfHandler->contentXml contains content and
561  // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by
562  // [!-- BEGIN lines --]*[!-- END lines --]
563  //print html_entity_decode($odfHandler->__toString());
564  //print exit;
565 
566 
567  // Define substitution array
568  $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
569  $array_object_from_properties = $this->get_substitutionarray_each_var_object($object, $outputlangs);
570  $array_objet = $this->get_substitutionarray_object($project, $outputlangs);
571  $array_user = $this->get_substitutionarray_user($user, $outputlangs);
572  $array_soc = $this->get_substitutionarray_mysoc($mysoc, $outputlangs);
573  $array_thirdparty = $this->get_substitutionarray_thirdparty($socobject, $outputlangs);
574  $array_other = $this->get_substitutionarray_other($outputlangs);
575 
576  $tmparray = array_merge($substitutionarray, $array_object_from_properties, $array_user, $array_soc, $array_thirdparty, $array_objet, $array_other);
577  complete_substitutions_array($tmparray, $outputlangs, $object);
578 
579  foreach ($tmparray as $key => $value) {
580  try {
581  if (preg_match('/logo$/', $key)) { // Image
582  if (file_exists($value)) {
583  $odfHandler->setImage($key, $value);
584  } else {
585  $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8');
586  }
587  } else // Text
588  {
589  $odfHandler->setVars($key, $value, true, 'UTF-8');
590  }
591  } catch (OdfException $e) {
592  dol_syslog($e->getMessage(), LOG_INFO);
593  }
594  }
595 
596  // Replace tags of lines for tasks
597  try {
598  // Security check
599  $socid = 0;
600  if (!empty($project->fk_soc)) {
601  $socid = $project->fk_soc;
602  }
603 
604  $tmparray = $this->get_substitutionarray_tasks($object, $outputlangs);
605  complete_substitutions_array($tmparray, $outputlangs, $object);
606  foreach ($tmparray as $key => $val) {
607  try {
608  $odfHandler->setVars($key, $val, true, 'UTF-8');
609  } catch (OdfException $e) {
610  dol_syslog($e->getMessage(), LOG_INFO);
611  } catch (SegmentException $e) {
612  dol_syslog($e->getMessage(), LOG_INFO);
613  }
614  }
615 
616  // Replace tags of lines for contacts task
617  $sourcearray = array('internal', 'external');
618  $contact_arrray = array();
619  foreach ($sourcearray as $source) {
620  $contact_temp = $object->liste_contact(-1, $source);
621  if ((is_array($contact_temp) && count($contact_temp) > 0)) {
622  $contact_arrray = array_merge($contact_arrray, $contact_temp);
623  }
624  }
625  if ((is_array($contact_arrray) && count($contact_arrray) > 0)) {
626  $listlinestaskres = $odfHandler->setSegment('tasksressources');
627 
628  foreach ($contact_arrray as $contact) {
629  if ($contact['source'] == 'internal') {
630  $objectdetail = new User($this->db);
631  $objectdetail->fetch($contact['id']);
632  $contact['socname'] = $mysoc->name;
633  } elseif ($contact['source'] == 'external') {
634  $objectdetail = new Contact($this->db);
635  $objectdetail->fetch($contact['id']);
636 
637  $soc = new Societe($this->db);
638  $soc->fetch($contact['socid']);
639  $contact['socname'] = $soc->name;
640  }
641  $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1);
642 
643  $tmparray = $this->get_substitutionarray_tasksressource($contact, $outputlangs);
644 
645  foreach ($tmparray as $key => $val) {
646  try {
647  $listlinestaskres->setVars($key, $val, true, 'UTF-8');
648  } catch (OdfException $e) {
649  dol_syslog($e->getMessage(), LOG_INFO);
650  } catch (SegmentException $e) {
651  dol_syslog($e->getMessage(), LOG_INFO);
652  }
653  }
654  $listlinestaskres->merge();
655  }
656  $odfHandler->mergeSegment($listlinestaskres);
657  }
658 
659  // Time ressources
660  $sql = "SELECT t.rowid, t.element_date as task_date, t.element_duration as task_duration, t.fk_user, t.note";
661  $sql .= ", u.lastname, u.firstname";
662  $sql .= " FROM ".MAIN_DB_PREFIX."element_time as t";
663  $sql .= " , ".MAIN_DB_PREFIX."user as u";
664  $sql .= " WHERE t.fk_element =".((int) $object->id);
665  $sql .= " AND t.elementtype = 'task'";
666  $sql .= " AND t.fk_user = u.rowid";
667  $sql .= " ORDER BY t.element_date DESC";
668 
669  $resql = $this->db->query($sql);
670  if ($resql) {
671  $num = $this->db->num_rows($resql);
672  $i = 0;
673  $tasks = array();
674  $listlinestasktime = $odfHandler->setSegment('taskstimes');
675  while ($i < $num) {
676  $row = $this->db->fetch_array($resql);
677  if (!empty($row['fk_user'])) {
678  $objectdetail = new User($this->db);
679  $objectdetail->fetch($row['fk_user']);
680  // TODO Use a cache to aoid fetch for same user
681  $row['fullcivname'] = $objectdetail->getFullName($outputlangs, 1);
682  } else {
683  $row['fullcivname'] = '';
684  }
685 
686  $tmparray = $this->get_substitutionarray_taskstime($row, $outputlangs);
687 
688  foreach ($tmparray as $key => $val) {
689  try {
690  $listlinestasktime->setVars($key, $val, true, 'UTF-8');
691  } catch (OdfException $e) {
692  dol_syslog($e->getMessage(), LOG_INFO);
693  } catch (SegmentException $e) {
694  dol_syslog($e->getMessage(), LOG_INFO);
695  }
696  }
697  $listlinestasktime->merge();
698  $i++;
699  }
700  $this->db->free($resql);
701 
702  $odfHandler->mergeSegment($listlinestasktime);
703  }
704 
705 
706  // Replace tags of project files
707  $listtasksfiles = $odfHandler->setSegment('tasksfiles');
708 
709  $upload_dir = $conf->project->dir_output.'/'.dol_sanitizeFileName($project->ref).'/'.dol_sanitizeFileName($object->ref);
710  $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', 'name', SORT_ASC, 1);
711 
712 
713  foreach ($filearray as $filedetail) {
714  $tmparray = $this->get_substitutionarray_task_file($filedetail, $outputlangs);
715  //dol_syslog(get_class($this).'::main $tmparray'.var_export($tmparray,true));
716  foreach ($tmparray as $key => $val) {
717  try {
718  $listtasksfiles->setVars($key, $val, true, 'UTF-8');
719  } catch (OdfException $e) {
720  dol_syslog($e->getMessage(), LOG_INFO);
721  } catch (SegmentException $e) {
722  dol_syslog($e->getMessage(), LOG_INFO);
723  }
724  }
725  $listtasksfiles->merge();
726  }
727  //$listlines->merge();
728 
729  $odfHandler->mergeSegment($listtasksfiles);
730  } catch (OdfException $e) {
731  $this->error = $e->getMessage();
732  dol_syslog($this->error, LOG_WARNING);
733  return -1;
734  }
735 
736 
737 
738  // Replace tags of project files
739  try {
740  $listlines = $odfHandler->setSegment('projectfiles');
741 
742  $upload_dir = $conf->project->dir_output.'/'.dol_sanitizeFileName($object->ref);
743  $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', 'name', SORT_ASC, 1);
744 
745 
746  foreach ($filearray as $filedetail) {
747  //dol_syslog(get_class($this).'::main $filedetail'.var_export($filedetail,true));
748  $tmparray = $this->get_substitutionarray_project_file($filedetail, $outputlangs);
749 
750  foreach ($tmparray as $key => $val) {
751  try {
752  $listlines->setVars($key, $val, true, 'UTF-8');
753  } catch (OdfException $e) {
754  dol_syslog($e->getMessage(), LOG_INFO);
755  } catch (SegmentException $e) {
756  dol_syslog($e->getMessage(), LOG_INFO);
757  }
758  }
759  $listlines->merge();
760  }
761  $odfHandler->mergeSegment($listlines);
762  } catch (OdfException $e) {
763  $this->error = $e->getMessage();
764  dol_syslog($this->error, LOG_WARNING);
765  return -1;
766  }
767 
768  // Replace tags of lines for contacts
769  $sourcearray = array('internal', 'external');
770  $contact_arrray = array();
771  foreach ($sourcearray as $source) {
772  $contact_temp = $project->liste_contact(-1, $source);
773  if ((is_array($contact_temp) && count($contact_temp) > 0)) {
774  $contact_arrray = array_merge($contact_arrray, $contact_temp);
775  }
776  }
777  if ((is_array($contact_arrray) && count($contact_arrray) > 0)) {
778  try {
779  $listlines = $odfHandler->setSegment('projectcontacts');
780 
781  foreach ($contact_arrray as $contact) {
782  if ($contact['source'] == 'internal') {
783  $objectdetail = new User($this->db);
784  $objectdetail->fetch($contact['id']);
785  $contact['socname'] = $mysoc->name;
786  } elseif ($contact['source'] == 'external') {
787  $objectdetail = new Contact($this->db);
788  $objectdetail->fetch($contact['id']);
789 
790  $soc = new Societe($this->db);
791  $soc->fetch($contact['socid']);
792  $contact['socname'] = $soc->name;
793  }
794  $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1);
795 
796  $tmparray = $this->get_substitutionarray_project_contacts($contact, $outputlangs);
797 
798  foreach ($tmparray as $key => $val) {
799  try {
800  $listlines->setVars($key, $val, true, 'UTF-8');
801  } catch (OdfException $e) {
802  dol_syslog($e->getMessage(), LOG_INFO);
803  } catch (SegmentException $e) {
804  dol_syslog($e->getMessage(), LOG_INFO);
805  }
806  }
807  $listlines->merge();
808  }
809  $odfHandler->mergeSegment($listlines);
810  } catch (OdfException $e) {
811  $this->error = $e->getMessage();
812  dol_syslog($this->error, LOG_WARNING);
813  return -1;
814  }
815  }
816 
817 
818  // Call the beforeODTSave hook
819  $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
820  $reshook = $hookmanager->executeHooks('beforeODTSave', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
821 
822 
823  // Write new file
824  if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
825  try {
826  $odfHandler->exportAsAttachedPDF($file);
827  } catch (Exception $e) {
828  $this->error = $e->getMessage();
829  dol_syslog($e->getMessage(), LOG_INFO);
830  return -1;
831  }
832  } else {
833  try {
834  $odfHandler->saveToDisk($file);
835  } catch (Exception $e) {
836  $this->error = $e->getMessage();
837  dol_syslog($e->getMessage(), LOG_INFO);
838  return -1;
839  }
840  }
841  $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
842  $reshook = $hookmanager->executeHooks('afterODTCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
843 
844  dolChmod($file);
845 
846  $odfHandler = null; // Destroy object
847 
848  $this->result = array('fullpath'=>$file);
849 
850  return 1; // Success
851  } else {
852  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
853  return -1;
854  }
855  }
856 
857  return -1;
858  }
859 }
doc_generic_task_odt\get_substitutionarray_tasksressource
get_substitutionarray_tasksressource($taskressource, $outputlangs)
Define array with couple substitution key => substitution value.
Definition: doc_generic_task_odt.modules.php:297
doc_generic_task_odt\get_substitutionarray_object
get_substitutionarray_object($object, $outputlangs, $array_key='object')
Define array with couple substitution key => substitution value.
Definition: doc_generic_task_odt.modules.php:146
Societe
Class to manage third parties objects (customers, suppliers, prospects...)
Definition: societe.class.php:51
dol_sanitizeFileName
dol_sanitizeFileName($str, $newstr='_', $unaccent=1)
Clean a string to use it as a file name.
Definition: functions.lib.php:1323
description
print *****$script_file(".$version.") pid cd cd cd description as description
Definition: email_expire_services_to_customers.php:83
Project
Class to manage projects.
Definition: project.class.php:36
dol_print_error
dol_print_error($db='', $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
Definition: functions.lib.php:5107
CommonDocGenerator\get_substitutionarray_user
get_substitutionarray_user($user, $outputlangs)
Define array with couple substitution key => substitution value.
Definition: commondocgenerator.class.php:140
dol_dir_list
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
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
Definition: functions.lib.php:4784
Task
Class to manage tasks.
Definition: task.class.php:39
$form
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
Definition: card.php:143
name
$conf db name
Definition: repair.php:123
doc_generic_task_odt\info
info($langs)
Return description of a module.
Definition: doc_generic_task_odt.modules.php:365
doc_generic_task_odt
Class to build documents using ODF templates generator.
Definition: doc_generic_task_odt.modules.php:77
ModelePDFTask
Parent class for projects models.
Definition: modules_task.php:33
convertSecondToTime
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
dol_print_date
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
Definition: functions.lib.php:2675
doc_generic_task_odt\get_substitutionarray_task_file
get_substitutionarray_task_file($file, $outputlangs)
Define array with couple substitution key => substitution value.
Definition: doc_generic_task_odt.modules.php:346
img_picto
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
Definition: functions.lib.php:4135
dolChmod
dolChmod($filepath, $newmask='')
Change mod of a file.
Definition: functions.lib.php:7007
Exception
doc_generic_task_odt\__construct
__construct($db)
Constructor.
Definition: doc_generic_task_odt.modules.php:97
CommonDocGenerator\fill_substitutionarray_with_extrafields
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...
Definition: commondocgenerator.class.php:944
doc_generic_task_odt\get_substitutionarray_tasks
get_substitutionarray_tasks($task, $outputlangs, $array_key='task')
Define array with couple substitution key => substitution value.
Definition: doc_generic_task_odt.modules.php:185
CommonDocGenerator\get_substitutionarray_thirdparty
get_substitutionarray_thirdparty($object, $outputlangs, $array_key='company')
Define array with couple substitution key => substitution value For example {company_name},...
Definition: commondocgenerator.class.php:292
doc_generic_task_odt\get_substitutionarray_project_file
get_substitutionarray_project_file($file, $outputlangs)
Define array with couple substitution key => substitution value.
Definition: doc_generic_task_odt.modules.php:253
CommonDocGenerator\get_substitutionarray_each_var_object
get_substitutionarray_each_var_object(&$object, $outputlangs, $recursive=1)
Define array with couple substitution key => substitution value.
Definition: commondocgenerator.class.php:899
dol_syslog
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
Definition: functions.lib.php:1741
Contact
Class to manage contact/addresses.
Definition: contact.class.php:42
doc_generic_task_odt\get_substitutionarray_taskstime
get_substitutionarray_taskstime($tasktime, $outputlangs)
Define array with couple substitution key => substitution value.
Definition: doc_generic_task_odt.modules.php:321
doc_generic_task_odt\get_substitutionarray_project_contacts
get_substitutionarray_project_contacts($contact, $outputlangs)
Define array with couple substitution key => substitution value.
Definition: doc_generic_task_odt.modules.php:228
CommonDocGenerator\get_substitutionarray_mysoc
get_substitutionarray_mysoc($mysoc, $outputlangs)
Define array with couple substitution key => substitution value.
Definition: commondocgenerator.class.php:233
$sql
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
newToken
newToken()
Return the value of token currently saved into session with name 'newtoken'.
Definition: functions.lib.php:11654
isModEnabled
isModEnabled($module)
Is Dolibarr module enabled.
Definition: functions.lib.php:207
User
Class to manage Dolibarr users.
Definition: user.class.php:47
Form
Class to manage generation of HTML components Only common components must be here.
Definition: html.form.class.php:53
price
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.
Definition: functions.lib.php:5829
doc_generic_task_odt\get_substitutionarray_project_reference
get_substitutionarray_project_reference($refdetail, $outputlangs)
Define array with couple substitution key => substitution value.
Definition: doc_generic_task_odt.modules.php:273
dol_mkdir
dol_mkdir($dir, $dataroot='', $newmask='')
Creation of a directory (this can create recursive subdir)
Definition: functions.lib.php:6936
type
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:120
getCommonSubstitutionArray
getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $object=null, $include=null)
Return array of possible common substitutions.
Definition: functions.lib.php:7762
complete_substitutions_array
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...
Definition: functions.lib.php:8489
CommonDocGenerator\get_substitutionarray_other
get_substitutionarray_other($outputlangs)
Define array with couple substitution key => substitution value.
Definition: commondocgenerator.class.php:415
doc_generic_task_odt\write_file
write_file($object, $outputlangs, $srctemplatepath)
Function to build a document on disk using the generic odt module.
Definition: doc_generic_task_odt.modules.php:462