dolibarr  13.0.2
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  *
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.'/core/modules/project/task/modules_task.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 (!empty($conf->propal->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php';
42 if (!empty($conf->facture->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php';
43 if (!empty($conf->facture->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture-rec.class.php';
44 if (!empty($conf->commande->enabled)) require_once DOL_DOCUMENT_ROOT.'/commande/class/commande.class.php';
45 if (!empty($conf->fournisseur->enabled)) require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php';
46 if (!empty($conf->fournisseur->enabled)) require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php';
47 if (!empty($conf->contrat->enabled)) require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
48 if (!empty($conf->ficheinter->enabled)) require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
49 if (!empty($conf->deplacement->enabled)) require_once DOL_DOCUMENT_ROOT.'/compta/deplacement/class/deplacement.class.php';
50 if (!empty($conf->agenda->enabled)) require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
51 
52 
57 {
62  public $emetteur;
63 
68  public $phpmin = array(5, 6);
69 
74  public $version = 'dolibarr';
75 
76 
82  public function __construct($db)
83  {
84  global $conf, $langs, $mysoc;
85 
86  // Load translation files required by the page
87  $langs->loadLangs(array("main", "companies"));
88 
89  $this->db = $db;
90  $this->name = "ODT templates";
91  $this->description = $langs->trans("DocumentModelOdt");
92  $this->scandir = 'PROJECT_TASK_ADDON_PDF_ODT_PATH'; // Name of constant that is used to save list of directories to scan
93 
94  // Page size for A4 format
95  $this->type = 'odt';
96  $this->page_largeur = 0;
97  $this->page_hauteur = 0;
98  $this->format = array($this->page_largeur, $this->page_hauteur);
99  $this->marge_gauche = 0;
100  $this->marge_droite = 0;
101  $this->marge_haute = 0;
102  $this->marge_basse = 0;
103 
104  $this->option_logo = 1; // Affiche logo
105  $this->option_tva = 0; // Gere option tva COMMANDE_TVAOPTION
106  $this->option_modereg = 0; // Affiche mode reglement
107  $this->option_condreg = 0; // Affiche conditions reglement
108  $this->option_codeproduitservice = 0; // Affiche code produit-service
109  $this->option_multilang = 0; // Dispo en plusieurs langues
110  $this->option_escompte = 0; // Affiche si il y a eu escompte
111  $this->option_credit_note = 0; // Support credit notes
112  $this->option_freetext = 1; // Support add of a personalised text
113  $this->option_draft_watermark = 0; // Support add of a watermark on drafts
114 
115  // Recupere emetteur
116  $this->emetteur = $mysoc;
117  if (!$this->emetteur->pays_code) $this->emetteur->pays_code = substr($langs->defaultlang, -2); // Par defaut, si n'etait pas defini
118  }
119 
120 
121  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
130  public function get_substitutionarray_object($object, $outputlangs, $array_key = 'object')
131  {
132  // phpcs:enable
133  global $conf, $extrafields;
134 
135  $resarray = array(
136  $array_key.'_id'=>$object->id,
137  $array_key.'_ref'=>$object->ref,
138  $array_key.'_title'=>$object->title,
139  $array_key.'_description'=>$object->description,
140  $array_key.'_date_creation'=>dol_print_date($object->date_c, 'day'),
141  $array_key.'_date_modification'=>dol_print_date($object->date_m, 'day'),
142  $array_key.'_date_start'=>dol_print_date($object->date_start, 'day'),
143  $array_key.'_date_end'=>dol_print_date($object->date_end, 'day'),
144  $array_key.'_note_private'=>$object->note_private,
145  $array_key.'_note_public'=>$object->note_public,
146  $array_key.'_public'=>$object->public,
147  $array_key.'_statut'=>$object->getLibStatut()
148  );
149 
150  // Retrieve extrafields
151  if (is_array($object->array_options) && count($object->array_options))
152  {
153  $object->fetch_optionals();
154 
155  $resarray = $this->fill_substitutionarray_with_extrafields($object, $resarray, $extrafields, $array_key, $outputlangs);
156  }
157 
158  return $resarray;
159  }
160 
161  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
170  public function get_substitutionarray_tasks($task, $outputlangs, $array_key = 'task')
171  {
172  // phpcs:enable
173  global $conf, $extrafields;
174 
175  $resarray = array(
176  'task_ref'=>$task->ref,
177  'task_fk_project'=>$task->fk_project,
178  'task_projectref'=>$task->projectref,
179  'task_projectlabel'=>$task->projectlabel,
180  'task_label'=>$task->label,
181  'task_description'=>$task->description,
182  'task_fk_parent'=>$task->fk_parent,
183  'task_duration'=>$task->duration_effective,
184  'task_duration_formated'=>convertSecondToTime($task->duration_effective, 'allhourmin'),
185  'task_planned_workload'=>$task->planned_workload,
186  'task_planned_workload_formated'=>convertSecondToTime($task->planned_workload, 'allhourmin'),
187  'task_progress'=>$task->progress,
188  'task_public'=>$task->public,
189  'task_date_start'=>dol_print_date($task->date_start, 'day'),
190  'task_date_end'=>dol_print_date($task->date_end, 'day'),
191  'task_note_private'=>$task->note_private,
192  'task_note_public'=>$task->note_public
193  );
194 
195  // Retrieve extrafields
196  if (is_array($task->array_options) && count($task->array_options))
197  {
198  $task->fetch_optionals();
199 
200  $resarray = $this->fill_substitutionarray_with_extrafields($task, $resarray, $extrafields, $array_key, $outputlangs);
201  }
202 
203  return $resarray;
204  }
205 
206  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
214  public function get_substitutionarray_project_contacts($contact, $outputlangs)
215  {
216  // phpcs:enable
217  global $conf;
218 
219  return array(
220  'projcontacts_id'=>$contact['id'],
221  'projcontacts_rowid'=>$contact['rowid'],
222  'projcontacts_role'=>$contact['libelle'],
223  'projcontacts_lastname'=>$contact['lastname'],
224  'projcontacts_firstname'=>$contact['firstname'],
225  'projcontacts_fullcivname'=>$contact['fullname'],
226  'projcontacts_socname'=>$contact['socname'],
227  'projcontacts_email'=>$contact['email']
228  );
229  }
230 
231  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
239  public function get_substitutionarray_project_file($file, $outputlangs)
240  {
241  // phpcs:enable
242  global $conf;
243 
244  return array(
245  'projfile_name'=>$file['name'],
246  'projfile_date'=>dol_print_date($file['date'], 'day'),
247  'projfile_size'=>$file['size']
248  );
249  }
250 
251  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
259  public function get_substitutionarray_project_reference($refdetail, $outputlangs)
260  {
261  // phpcs:enable
262  global $conf;
263 
264  return array(
265  'projref_type'=>$refdetail['type'],
266  'projref_ref'=>$refdetail['ref'],
267  'projref_date'=>dol_print_date($refdetail['date'], 'day'),
268  'projref_socname'=>$refdetail['socname'],
269  'projref_amountht'=>price($refdetail['amountht'], 0, $outputlangs),
270  'projref_amountttc'=>price($refdetail['amountttc'], 0, $outputlangs),
271  'projref_status'=>$refdetail['status']
272  );
273  }
274 
275  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
283  public function get_substitutionarray_tasksressource($taskressource, $outputlangs)
284  {
285  // phpcs:enable
286  global $conf;
287  //dol_syslog(get_class($this).'::get_substitutionarray_tasksressource taskressource='.var_export($taskressource,true),LOG_DEBUG);
288  return array(
289  'taskressource_rowid'=>$taskressource['rowid'],
290  'taskressource_role'=>$taskressource['libelle'],
291  'taskressource_lastname'=>$taskressource['lastname'],
292  'taskressource_firstname'=>$taskressource['firstname'],
293  'taskressource_fullcivname'=>$taskressource['fullname'],
294  'taskressource_socname'=>$taskressource['socname'],
295  'taskressource_email'=>$taskressource['email']
296  );
297  }
298 
299  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
307  public function get_substitutionarray_taskstime($tasktime, $outputlangs)
308  {
309  // phpcs:enable
310  global $conf;
311 
312  return array(
313  'tasktime_rowid'=>$tasktime['rowid'],
314  'tasktime_task_date'=>dol_print_date($tasktime['task_date'], 'day'),
315  'tasktime_task_duration'=>convertSecondToTime($tasktime['task_duration'], 'all'),
316  'tasktime_note'=>$tasktime['note'],
317  'tasktime_fk_user'=>$tasktime['fk_user'],
318  'tasktime_user_name'=>$tasktime['name'],
319  'tasktime_user_first'=>$tasktime['firstname'],
320  'tasktime_fullcivname'=>$tasktime['fullcivname']
321  );
322  }
323 
324  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
332  public function get_substitutionarray_task_file($file, $outputlangs)
333  {
334  // phpcs:enable
335  global $conf;
336 
337  return array(
338  'tasksfile_name'=>$file['name'],
339  'tasksfile_date'=>dol_print_date($file['date'], 'day'),
340  'tasksfile_size'=>$file['size']
341  );
342  }
343 
344 
351  public function info($langs)
352  {
353  global $conf, $langs;
354 
355  // Load translation files required by the page
356  $langs->loadLangs(array("errors", "companies"));
357 
358  $form = new Form($this->db);
359 
360  $texte = $this->description.".<br>\n";
361  $texte .= '<form action="'.$_SERVER["PHP_SELF"].'" method="POST">';
362  $texte .= '<input type="hidden" name="token" value="'.newToken().'">';
363  $texte .= '<input type="hidden" name="action" value="setModuleOptions">';
364  $texte .= '<input type="hidden" name="param1" value="PROJECT_TASK_ADDON_PDF_ODT_PATH">';
365  $texte .= '<table class="nobordernopadding" width="100%">';
366 
367  // List of directories area
368  $texte .= '<tr><td>';
369  $texttitle = $langs->trans("ListOfDirectories");
370  $listofdir = explode(',', preg_replace('/[\r\n]+/', ',', trim($conf->global->PROJECT_TASK_ADDON_PDF_ODT_PATH)));
371  $listoffiles = array();
372  foreach ($listofdir as $key=>$tmpdir)
373  {
374  $tmpdir = trim($tmpdir);
375  $tmpdir = preg_replace('/DOL_DATA_ROOT/', DOL_DATA_ROOT, $tmpdir);
376  if (!$tmpdir) {
377  unset($listofdir[$key]); continue;
378  }
379  if (!is_dir($tmpdir)) $texttitle .= img_warning($langs->trans("ErrorDirNotFound", $tmpdir), 0);
380  else {
381  $tmpfiles = dol_dir_list($tmpdir, 'files', 0, '\.(ods|odt)');
382  if (count($tmpfiles)) $listoffiles = array_merge($listoffiles, $tmpfiles);
383  }
384  }
385  $texthelp = $langs->trans("ListOfDirectoriesForModelGenODT");
386  // Add list of substitution keys
387  $texthelp .= '<br>'.$langs->trans("FollowingSubstitutionKeysCanBeUsed").'<br>';
388  $texthelp .= $langs->transnoentitiesnoconv("FullListOnOnlineDocumentation"); // This contains an url, we don't modify it
389 
390  $texte .= $form->textwithpicto($texttitle, $texthelp, 1, 'help', '', 1);
391  $texte .= '<div><div style="display: inline-block; min-width: 100px; vertical-align: middle;">';
392  $texte .= '<textarea class="flat" cols="60" name="value1">';
393  $texte .= $conf->global->PROJECT_TASK_ADDON_PDF_ODT_PATH;
394  $texte .= '</textarea>';
395  $texte .= '</div><div style="display: inline-block; vertical-align: middle;">';
396  $texte .= '<input type="submit" class="button" value="'.$langs->trans("Modify").'" name="Button">';
397  $texte .= '<br></div></div>';
398 
399  // Scan directories
400  $nbofiles = count($listoffiles);
401  if (!empty($conf->global->PROJECT_TASK_ADDON_PDF_ODT_PATH))
402  {
403  $texte .= $langs->trans("NumberOfModelFilesFound").': <b>';
404  //$texte.=$nbofiles?'<a id="a_'.get_class($this).'" href="#">':'';
405  $texte .= $nbofiles;
406  //$texte.=$nbofiles?'</a>':'';
407  $texte .= '</b>';
408  }
409 
410  if ($nbofiles)
411  {
412  $texte .= '<div id="div_'.get_class($this).'" class="hiddenx">';
413  // Show list of found files
414  foreach ($listoffiles as $file) {
415  $texte .= '- '.$file['name'].' <a href="'.DOL_URL_ROOT.'/document.php?modulepart=doctemplates&file=tasks/'.urlencode(basename($file['name'])).'">'.img_picto('', 'listlight').'</a><br>';
416  }
417  $texte .= '</div>';
418  }
419 
420  $texte .= '</td>';
421 
422  $texte .= '<td rowspan="2" class="tdtop hideonsmartphone">';
423  $texte .= $langs->trans("ExampleOfDirectoriesForModelGen");
424  $texte .= '</td>';
425  $texte .= '</tr>';
426 
427  $texte .= '</table>';
428  $texte .= '</form>';
429 
430  return $texte;
431  }
432 
433  // phpcs:disable PEAR.NamingConventions.ValidFunctionName.ScopeNotCamelCaps
442  public function write_file($object, $outputlangs, $srctemplatepath)
443  {
444  // phpcs:enable
445  global $user, $langs, $conf, $mysoc, $hookmanager;
446 
447  if (empty($srctemplatepath))
448  {
449  dol_syslog("doc_generic_odt::write_file parameter srctemplatepath empty", LOG_WARNING);
450  return -1;
451  }
452 
453  if (!is_object($outputlangs)) $outputlangs = $langs;
454  $sav_charset_output = $outputlangs->charset_output;
455  $outputlangs->charset_output = 'UTF-8';
456 
457  // Load translation files required by the page
458  $outputlangs->loadLangs(array("main", "dict", "companies", "projects"));
459 
460  if ($conf->projet->dir_output)
461  {
462  // If $object is id instead of object
463  if (!is_object($object))
464  {
465  $id = $object;
466  $object = new Task($this->db);
467  $result = $object->fetch($id);
468  if ($result < 0)
469  {
470  dol_print_error($this->db, $object->error);
471  return -1;
472  }
473  }
474  $project = new Project($this->db);
475  $project->fetch($object->fk_project);
476  $project->fetch_thirdparty();
477 
478  $dir = $conf->projet->dir_output."/".$project->ref."/";
479  $objectref = dol_sanitizeFileName($object->ref);
480  if (!preg_match('/specimen/i', $objectref)) $dir .= "/".$objectref;
481  $file = $dir."/".$objectref.".odt";
482 
483  if (!file_exists($dir))
484  {
485  if (dol_mkdir($dir) < 0)
486  {
487  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
488  return -1;
489  }
490  }
491 
492 
493  if (file_exists($dir))
494  {
495  //print "srctemplatepath=".$srctemplatepath; // Src filename
496  $newfile = basename($srctemplatepath);
497  $newfiletmp = preg_replace('/\.(ods|odt)/i', '', $newfile);
498  $newfiletmp = preg_replace('/template_/i', '', $newfiletmp);
499  $newfiletmp = preg_replace('/modele_/i', '', $newfiletmp);
500  $newfiletmp = $objectref.'_'.$newfiletmp;
501  //$file=$dir.'/'.$newfiletmp.'.'.dol_print_date(dol_now(),'%Y%m%d%H%M%S').'.odt';
502  $file = $dir.'/'.$newfiletmp.'.odt';
503  //print "newdir=".$dir;
504  //print "newfile=".$newfile;
505  //print "file=".$file;
506  //print "conf->societe->dir_temp=".$conf->societe->dir_temp;
507 
508  dol_mkdir($conf->projet->dir_temp);
509 
510  $socobject = $project->thirdparty;
511 
512  // Make substitution
513  $substitutionarray = array(
514  '__FROM_NAME__' => $this->emetteur->name,
515  '__FROM_EMAIL__' => $this->emetteur->email,
516  );
517  complete_substitutions_array($substitutionarray, $langs, $object);
518  // Call the ODTSubstitution hook
519  $parameters = array('file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
520  $reshook = $hookmanager->executeHooks('ODTSubstitution', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
521 
522  // Open and load template
523  require_once ODTPHP_PATH.'odf.php';
524  try {
525  $odfHandler = new odf(
526  $srctemplatepath,
527  array(
528  'PATH_TO_TMP' => $conf->projet->dir_temp,
529  'ZIP_PROXY' => 'PclZipProxy', // PhpZipProxy or PclZipProxy. Got "bad compression method" error when using PhpZipProxy.
530  'DELIMITER_LEFT' => '{',
531  'DELIMITER_RIGHT' => '}'
532  )
533  );
534  } catch (Exception $e)
535  {
536  $this->error = $e->getMessage();
537  return -1;
538  }
539  // After construction $odfHandler->contentXml contains content and
540  // [!-- BEGIN row.lines --]*[!-- END row.lines --] has been replaced by
541  // [!-- BEGIN lines --]*[!-- END lines --]
542  //print html_entity_decode($odfHandler->__toString());
543  //print exit;
544 
545 
546  // Define substitution array
547  $substitutionarray = getCommonSubstitutionArray($outputlangs, 0, null, $object);
548  $array_object_from_properties = $this->get_substitutionarray_each_var_object($object, $outputlangs);
549  $array_objet = $this->get_substitutionarray_object($project, $outputlangs);
550  $array_user = $this->get_substitutionarray_user($user, $outputlangs);
551  $array_soc = $this->get_substitutionarray_mysoc($mysoc, $outputlangs);
552  $array_thirdparty = $this->get_substitutionarray_thirdparty($socobject, $outputlangs);
553  $array_other = $this->get_substitutionarray_other($outputlangs);
554 
555  $tmparray = array_merge($substitutionarray, $array_object_from_properties, $array_user, $array_soc, $array_thirdparty, $array_objet, $array_other);
556  complete_substitutions_array($tmparray, $outputlangs, $object);
557 
558  foreach ($tmparray as $key=>$value)
559  {
560  try {
561  if (preg_match('/logo$/', $key)) // Image
562  {
563  if (file_exists($value)) $odfHandler->setImage($key, $value);
564  else $odfHandler->setVars($key, 'ErrorFileNotFound', true, 'UTF-8');
565  } else // Text
566  {
567  $odfHandler->setVars($key, $value, true, 'UTF-8');
568  }
569  } catch (OdfException $e) {
570  dol_syslog($e->getMessage(), LOG_INFO);
571  }
572  }
573 
574  // Replace tags of lines for tasks
575  try {
576  // Security check
577  $socid = 0;
578  if (!empty($project->fk_soc)) $socid = $project->fk_soc;
579 
580  $tmparray = $this->get_substitutionarray_tasks($object, $outputlangs);
581  complete_substitutions_array($tmparray, $outputlangs, $object);
582  foreach ($tmparray as $key => $val)
583  {
584  try {
585  $odfHandler->setVars($key, $val, true, 'UTF-8');
586  } catch (OdfException $e) {
587  dol_syslog($e->getMessage(), LOG_INFO);
588  } catch (SegmentException $e) {
589  dol_syslog($e->getMessage(), LOG_INFO);
590  }
591  }
592 
593  // Replace tags of lines for contacts task
594  $sourcearray = array('internal', 'external');
595  $contact_arrray = array();
596  foreach ($sourcearray as $source) {
597  $contact_temp = $object->liste_contact(-1, $source);
598  if ((is_array($contact_temp) && count($contact_temp) > 0))
599  {
600  $contact_arrray = array_merge($contact_arrray, $contact_temp);
601  }
602  }
603  if ((is_array($contact_arrray) && count($contact_arrray) > 0))
604  {
605  $listlinestaskres = $odfHandler->setSegment('tasksressources');
606 
607  foreach ($contact_arrray as $contact)
608  {
609  if ($contact['source'] == 'internal') {
610  $objectdetail = new User($this->db);
611  $objectdetail->fetch($contact['id']);
612  $contact['socname'] = $mysoc->name;
613  } elseif ($contact['source'] == 'external') {
614  $objectdetail = new Contact($this->db);
615  $objectdetail->fetch($contact['id']);
616 
617  $soc = new Societe($this->db);
618  $soc->fetch($contact['socid']);
619  $contact['socname'] = $soc->name;
620  }
621  $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1);
622 
623  $tmparray = $this->get_substitutionarray_tasksressource($contact, $outputlangs);
624 
625  foreach ($tmparray as $key => $val)
626  {
627  try {
628  $listlinestaskres->setVars($key, $val, true, 'UTF-8');
629  } catch (OdfException $e) {
630  dol_syslog($e->getMessage(), LOG_INFO);
631  } catch (SegmentException $e) {
632  dol_syslog($e->getMessage(), LOG_INFO);
633  }
634  }
635  $listlinestaskres->merge();
636  }
637  $odfHandler->mergeSegment($listlinestaskres);
638  }
639 
640  // Time ressources
641  $sql = "SELECT t.rowid, t.task_date, t.task_duration, t.fk_user, t.note";
642  $sql .= ", u.lastname, u.firstname";
643  $sql .= " FROM ".MAIN_DB_PREFIX."projet_task_time as t";
644  $sql .= " , ".MAIN_DB_PREFIX."user as u";
645  $sql .= " WHERE t.fk_task =".$object->id;
646  $sql .= " AND t.fk_user = u.rowid";
647  $sql .= " ORDER BY t.task_date DESC";
648 
649  $resql = $this->db->query($sql);
650  if ($resql)
651  {
652  $num = $this->db->num_rows($resql);
653  $i = 0;
654  $tasks = array();
655  $listlinestasktime = $odfHandler->setSegment('taskstimes');
656  while ($i < $num)
657  {
658  $row = $this->db->fetch_array($resql);
659  if (!empty($row['fk_user'])) {
660  $objectdetail = new User($this->db);
661  $objectdetail->fetch($row['fk_user']);
662  // TODO Use a cache to aoid fetch for same user
663  $row['fullcivname'] = $objectdetail->getFullName($outputlangs, 1);
664  } else {
665  $row['fullcivname'] = '';
666  }
667 
668  $tmparray = $this->get_substitutionarray_taskstime($row, $outputlangs);
669 
670  foreach ($tmparray as $key => $val)
671  {
672  try {
673  $listlinestasktime->setVars($key, $val, true, 'UTF-8');
674  } catch (OdfException $e)
675  {
676  dol_syslog($e->getMessage(), LOG_INFO);
677  } catch (SegmentException $e)
678  {
679  dol_syslog($e->getMessage(), LOG_INFO);
680  }
681  }
682  $listlinestasktime->merge();
683  $i++;
684  }
685  $this->db->free($resql);
686 
687  $odfHandler->mergeSegment($listlinestasktime);
688  }
689 
690 
691  // Replace tags of project files
692  $listtasksfiles = $odfHandler->setSegment('tasksfiles');
693 
694  $upload_dir = $conf->projet->dir_output.'/'.dol_sanitizeFileName($project->ref).'/'.dol_sanitizeFileName($object->ref);
695  $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', 'name', SORT_ASC, 1);
696 
697 
698  foreach ($filearray as $filedetail)
699  {
700  $tmparray = $this->get_substitutionarray_task_file($filedetail, $outputlangs);
701  //dol_syslog(get_class($this).'::main $tmparray'.var_export($tmparray,true));
702  foreach ($tmparray as $key => $val)
703  {
704  try {
705  $listtasksfiles->setVars($key, $val, true, 'UTF-8');
706  } catch (OdfException $e)
707  {
708  dol_syslog($e->getMessage(), LOG_INFO);
709  } catch (SegmentException $e)
710  {
711  dol_syslog($e->getMessage(), LOG_INFO);
712  }
713  }
714  $listtasksfiles->merge();
715  }
716  //$listlines->merge();
717 
718  $odfHandler->mergeSegment($listtasksfiles);
719  } catch (OdfException $e)
720  {
721  $this->error = $e->getMessage();
722  dol_syslog($this->error, LOG_WARNING);
723  return -1;
724  }
725 
726 
727 
728  // Replace tags of project files
729  try {
730  $listlines = $odfHandler->setSegment('projectfiles');
731 
732  $upload_dir = $conf->projet->dir_output.'/'.dol_sanitizeFileName($object->ref);
733  $filearray = dol_dir_list($upload_dir, "files", 0, '', '(\.meta|_preview.*\.png)$', 'name', SORT_ASC, 1);
734 
735 
736  foreach ($filearray as $filedetail)
737  {
738  //dol_syslog(get_class($this).'::main $filedetail'.var_export($filedetail,true));
739  $tmparray = $this->get_substitutionarray_project_file($filedetail, $outputlangs);
740 
741  foreach ($tmparray as $key => $val)
742  {
743  try {
744  $listlines->setVars($key, $val, true, 'UTF-8');
745  } catch (OdfException $e)
746  {
747  dol_syslog($e->getMessage(), LOG_INFO);
748  } catch (SegmentException $e)
749  {
750  dol_syslog($e->getMessage(), LOG_INFO);
751  }
752  }
753  $listlines->merge();
754  }
755  $odfHandler->mergeSegment($listlines);
756  } catch (OdfException $e)
757  {
758  $this->error = $e->getMessage();
759  dol_syslog($this->error, LOG_WARNING);
760  return -1;
761  }
762 
763  // Replace tags of lines for contacts
764  $sourcearray = array('internal', 'external');
765  $contact_arrray = array();
766  foreach ($sourcearray as $source) {
767  $contact_temp = $project->liste_contact(-1, $source);
768  if ((is_array($contact_temp) && count($contact_temp) > 0))
769  {
770  $contact_arrray = array_merge($contact_arrray, $contact_temp);
771  }
772  }
773  if ((is_array($contact_arrray) && count($contact_arrray) > 0))
774  {
775  try {
776  $listlines = $odfHandler->setSegment('projectcontacts');
777 
778  foreach ($contact_arrray as $contact)
779  {
780  if ($contact['source'] == 'internal') {
781  $objectdetail = new User($this->db);
782  $objectdetail->fetch($contact['id']);
783  $contact['socname'] = $mysoc->name;
784  } elseif ($contact['source'] == 'external') {
785  $objectdetail = new Contact($this->db);
786  $objectdetail->fetch($contact['id']);
787 
788  $soc = new Societe($this->db);
789  $soc->fetch($contact['socid']);
790  $contact['socname'] = $soc->name;
791  }
792  $contact['fullname'] = $objectdetail->getFullName($outputlangs, 1);
793 
794  $tmparray = $this->get_substitutionarray_project_contacts($contact, $outputlangs);
795 
796  foreach ($tmparray as $key => $val)
797  {
798  try {
799  $listlines->setVars($key, $val, true, 'UTF-8');
800  } catch (OdfException $e)
801  {
802  dol_syslog($e->getMessage(), LOG_INFO);
803  } catch (SegmentException $e)
804  {
805  dol_syslog($e->getMessage(), LOG_INFO);
806  }
807  }
808  $listlines->merge();
809  }
810  $odfHandler->mergeSegment($listlines);
811  } catch (OdfException $e)
812  {
813  $this->error = $e->getMessage();
814  dol_syslog($this->error, LOG_WARNING);
815  return -1;
816  }
817  }
818 
819 
820  // Call the beforeODTSave hook
821  $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
822  $reshook = $hookmanager->executeHooks('beforeODTSave', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
823 
824 
825  // Write new file
826  if (!empty($conf->global->MAIN_ODT_AS_PDF)) {
827  try {
828  $odfHandler->exportAsAttachedPDF($file);
829  } catch (Exception $e) {
830  $this->error = $e->getMessage();
831  dol_syslog($e->getMessage(), LOG_INFO);
832  return -1;
833  }
834  } else {
835  try {
836  $odfHandler->saveToDisk($file);
837  } catch (Exception $e) {
838  $this->error = $e->getMessage();
839  dol_syslog($e->getMessage(), LOG_INFO);
840  return -1;
841  }
842  }
843  $parameters = array('odfHandler'=>&$odfHandler, 'file'=>$file, 'object'=>$object, 'outputlangs'=>$outputlangs, 'substitutionarray'=>&$tmparray);
844  $reshook = $hookmanager->executeHooks('afterODTCreation', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks
845 
846  if (!empty($conf->global->MAIN_UMASK))
847  @chmod($file, octdec($conf->global->MAIN_UMASK));
848 
849  $odfHandler = null; // Destroy object
850 
851  $this->result = array('fullpath'=>$file);
852 
853  return 1; // Success
854  } else {
855  $this->error = $langs->transnoentities("ErrorCanNotCreateDir", $dir);
856  return -1;
857  }
858  }
859 
860  return -1;
861  }
862 }
get_substitutionarray_tasks($task, $outputlangs, $array_key= 'task')
Define array with couple substitution key =&gt; substitution value.
get_substitutionarray_tasksressource($taskressource, $outputlangs)
Define array with couple substitution key =&gt; substitution value.
</td > param sortfield sortorder printFieldListOption< tdclass="liste_titremaxwidthsearchright"></td ></tr >< trclass="liste_titre">< inputtype="checkbox"onClick="toggle(this)"/> Ref p ref Label p label Duration p duration center DesiredStock p desiredstock right StockLimitShort p seuil_stock_alerte right stock_physique right stock_real_warehouse right Ordered right StockToBuy right SupplierRef right param sortfield sortorder printFieldListTitle warehouseinternal SELECT description FROM product_lang WHERE qty< br > qty qty qty StockTooLow StockTooLow help help help< trclass="oddeven">< td >< inputtype="checkbox"class="check"name="choose'.$i.'"></td >< tdclass="nowrap"> stock</td >< td >< inputtype="hidden"name="desc'.$i.'"value="'.dol_escape_htmltag($objp-> description
Only used if Module[ID]Desc translation string is not found.
Definition: replenish.php:750
Class to manage contact/addresses.
get_substitutionarray_each_var_object(&$object, $outputlangs, $recursive=true)
Define array with couple substitution key =&gt; substitution value.
Parent class for projects models.
Class to manage Dolibarr users.
Definition: user.class.php:44
get_substitutionarray_user($user, $outputlangs)
Define array with couple substitution key =&gt; substitution value.
get_substitutionarray_object($object, $outputlangs, $array_key= 'object')
Define array with couple substitution key =&gt; substitution value.
Class to build documents using ODF templates generator.
$conf db name
Only used if Module[ID]Name translation string is not found.
Definition: repair.php:108
info($langs)
Return description of a module.
$conf db
API class for accounts.
Definition: inc.php:54
img_warning($titlealt= 'default', $moreatt= '', $morecss= 'pictowarning')
Show warning logo.
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...
getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $object=null)
Return array of possible common substitutions.
get_substitutionarray_task_file($file, $outputlangs)
Define array with couple substitution key =&gt; substitution value.
Class to manage generation of HTML components Only common components must be here.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage projects.
get_substitutionarray_project_file($file, $outputlangs)
Define array with couple substitution key =&gt; substitution value.
get_substitutionarray_thirdparty($object, $outputlangs, $array_key= 'company')
Define array with couple substitution key =&gt; substitution value.
img_picto($titlealt, $picto, $moreatt= '', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt= '', $morecss= '', $marginleftonlyshort=2)
Show picto whatever it&#39;s its name (generic function)
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename= '', $restricttologhandler= '', $logcontext=null)
Write log message into outputs.
get_substitutionarray_mysoc($mysoc, $outputlangs)
Define array with couple substitution key =&gt; substitution value.
get_substitutionarray_project_contacts($contact, $outputlangs)
Define array with couple substitution key =&gt; substitution value.
dol_sanitizeFileName($str, $newstr= '_', $unaccent=1)
Clean a string to use it as a file name.
dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefilter=null, $sortcriteria="name", $sortorder=SORT_ASC, $mode=0, $nohook=0, $relativename="", $donotfollowsymlinks=0)
Scan a directory and return a list of files/directories.
Definition: files.lib.php:60
get_substitutionarray_taskstime($tasktime, $outputlangs)
Define array with couple substitution key =&gt; substitution value.
Class to manage tasks.
Definition: task.class.php:35
dol_print_date($time, $format= '', $tzoutput= 'auto', $outputlangs= '', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
fill_substitutionarray_with_extrafields($object, $array_to_fill, $extrafields, $array_key, $outputlangs)
Fill array with couple extrafield key =&gt; extrafield value.
if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) if(!empty($conf->don->enabled)&&$user->rights->don->lire) if(!empty($conf->tax->enabled)&&$user->rights->tax->charges->lire) if(!empty($conf->facture->enabled)&&!empty($conf->commande->enabled)&&$user->rights->commande->lire &&empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) if(!empty($conf->facture->enabled)&&$user->rights->facture->lire) if((!empty($conf->fournisseur->enabled)&&empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)||!empty($conf->supplier_invoice->enabled))&&$user->rights->fournisseur->facture->lire) $resql
Social contributions to pay.
Definition: index.php:1232
dol_print_error($db= '', $error= '', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
get_substitutionarray_project_reference($refdetail, $outputlangs)
Define array with couple substitution key =&gt; substitution value.
get_substitutionarray_other($outputlangs)
Define array with couple substitution key =&gt; substitution value.
write_file($object, $outputlangs, $srctemplatepath)
Function to build a document on disk using the generic odt module.
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
Definition: repair.php:105
dol_mkdir($dir, $dataroot= '', $newmask=null)
Creation of a directory (this can create recursive subdir)
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:180
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 &quot;subst...