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