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