dolibarr 24.0.0-beta
card-rec.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2002-2003 Rodolphe Quiedeville <rodolphe@quiedeville.org>
3 * Copyright (C) 2004-2015 Laurent Destailleur <eldy@users.sourceforge.net>
4 * Copyright (C) 2005-2012 Regis Houssin <regis.houssin@inodbox.com>
5 * Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
6 * Copyright (C) 2013 Juanjo Menent <jmenent@2byte.es>
7 * Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
8 * Copyright (C) 2012 Cedric Salvador <csalvador@gpcsolutions.fr>
9 * Copyright (C) 2015 Alexandre Spangaro <aspangaro@open-dsi.fr>
10 * Copyright (C) 2016-2026 Charlene Benke <charlene@patas-monkey.com>
11 * Copyright (C) 2018-2026 Frédéric France <frederic.france@free.fr>
12 * Copyright (C) 2024 William Mead <william.mead@manchenumerique.fr>
13 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 3 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program. If not, see <https://www.gnu.org/licenses/>.
27 */
28
35// Load Dolibarr environment
36require '../main.inc.php';
45require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php';
46require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinterrec.class.php';
47require_once DOL_DOCUMENT_ROOT.'/core/lib/fichinter.lib.php';
48
49require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php';
50require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
51if (isModEnabled('project')) {
52 require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
53 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
54}
55if (isModEnabled('contract')) {
56 require_once DOL_DOCUMENT_ROOT.'/contrat/class/contrat.class.php';
57 require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcontract.class.php';
58}
59
60
61// Load translation files required by the page
62$langs->loadLangs(array("interventions", "admin", "compta", "bills"));
63
64// Security check
65$id = (GETPOSTINT('fichinterid') ? GETPOSTINT('fichinterid') : GETPOSTINT('id'));
66$ref = GETPOST('ref', 'alpha');
67$date_next_execution = GETPOST('date_next_execution', 'alpha');
68$action = GETPOST('action', 'aZ09');
69$cancel = GETPOST('cancel');
70$backtopage = GETPOST('backtopage', 'alpha');
71$socid = GETPOSTINT('socid');
72if ($user->isExternalUser()) {
73 $socid = $user->isExternalUser();
74}
75$objecttype = 'fichinter_rec';
76if ($action == "create" || $action == "add") {
77 $objecttype = '';
78}
79
80// Load variable for pagination
81$limit = GETPOSTINT('limit') ? GETPOSTINT('limit') : $conf->liste_limit;
82$sortfield = GETPOST('sortfield', 'aZ09comma');
83$sortorder = GETPOST('sortorder', 'aZ09comma');
84$page = GETPOSTISSET('pageplusone') ? (GETPOSTINT('pageplusone') - 1) : GETPOSTINT("page");
85if (empty($page) || $page < 0 || GETPOST('button_search', 'alpha') || GETPOST('button_removefilter', 'alpha')) {
86 // If $page is not defined, or '' or -1 or if we click on clear filters
87 $page = 0;
88}
89$offset = $limit * $page;
90$pageprev = $page - 1;
91$pagenext = $page + 1;
92
93
94$sortorder = GETPOST('sortorder', 'aZ09comma');
95$sortfield = GETPOST('sortfield', 'aZ09comma');
96if ($sortorder == "") {
97 $sortorder = "DESC";
98}
99
100if ($sortfield == "") {
101 $sortfield = "f.datec";
102}
103
105
106$arrayfields = array(
107 'f.title' => array('label' => "Ref", 'checked' => 1),
108 's.nom' => array('label' => "ThirdParty", 'checked' => 1),
109 'f.fk_contrat' => array('label' => "Contract", 'checked' => 1),
110 'f.duree' => array('label' => "Duration", 'checked' => 1),
111 'f.total_ttc' => array('label' => "AmountTTC", 'checked' => 1),
112 'f.frequency' => array('label' => "RecurringInvoiceTemplate", 'checked' => 1),
113 'f.nb_gen_done' => array('label' => "NbOfGenerationDoneShort", 'checked' => 1),
114 'f.date_last_gen' => array('label' => "DateLastGeneration", 'checked' => 1),
115 'f.date_when' => array('label' => "NextDateToExecution", 'checked' => 1),
116 'f.datec' => array('label' => "DateCreation", 'checked' => 0, 'position' => 500),
117 'f.tms' => array('label' => "DateModificationShort", 'checked' => 0, 'position' => 500),
118);
119
120$result = restrictedArea($user, 'ficheinter', $id, $objecttype);
121
122$permissiontoadd = $user->hasRight('ficheinter', 'creer');
123$permissiontodelete = $user->hasRight('ficheinter', 'supprimer');
124$objp = null;
125
126/*
127 * Actions
128 */
129$error = 0;
130
131if ($cancel) {
132 if (!empty($backtopageforcancel)) {
133 header("Location: ".$backtopageforcancel);
134 exit;
135 } elseif (!empty($backtopage)) {
136 header("Location: ".$backtopage);
137 exit;
138 }
139 $action = '';
140}
141
142// Create predefined intervention
143if ($action == 'add' && $permissiontoadd) {
144 if (!GETPOST('title')) {
145 setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->trans("Title")), null, 'errors');
146 $action = "create";
147 $error++;
148 }
149
150 if (!GETPOST('socid')) {
151 setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->trans("Customer")), null, 'errors');
152 $action = "create";
153 $error++;
154 }
155
156 // gestion des fréquences et des échéances
157 $frequency = GETPOSTINT('frequency');
158 $rec_year = GETPOST('rec_year');
159 $rec_month = GETPOST('rec_month');
160 $rec_day = GETPOST('rec_day');
161 $rec_hour = GETPOST('rec_hour');
162 $rec_min = GETPOST('rec_min');
163 $nb_gen_max = GETPOSTINT('nb_gen_max');
164 if ($frequency) {
165 if (empty($rec_year) || empty($rec_month) || empty($rec_day)) {
166 setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->trans("Date")), null, 'errors');
167 $action = "create";
168 $error++;
169 } else {
170 $date_next_execution = dol_mktime((int) $rec_hour, (int) $rec_min, 0, (int) $rec_month, (int) $rec_day, (int) $rec_year);
171 }
172 if ($nb_gen_max === 0) {
173 setEventMessages($langs->transnoentities("ErrorFieldRequired", $langs->trans("MaxPeriodNumber")), null, 'errors');
174 $action = "create";
175 $error++;
176 }
177 }
178
179 if (!$error) {
180 $object->id_origin = $id;
181 $object->title = GETPOST('title', 'alpha');
182 $object->description = GETPOST('description', 'restricthtml');
183 $object->socid = GETPOSTINT('socid');
184 $object->fk_project = GETPOSTINT('projectid');
185 $object->fk_contrat = GETPOSTINT('contractid');
186
187 $object->frequency = $frequency;
188 $object->unit_frequency = GETPOST('unit_frequency', 'alpha');
189 $object->nb_gen_max = $nb_gen_max;
190 $object->auto_validate = GETPOSTINT('auto_validate');
191
192 $object->date_when = $date_next_execution;
193
194 if ($object->create($user) > 0) {
195 $id = $object->id;
196 $action = '';
197 } else {
198 setEventMessages($object->error, $object->errors, 'errors');
199 $action = "create";
200 }
201 }
202} elseif ($action == 'createfrommodel' && $permissiontoadd) {
203 $newinter = new Fichinter($db);
204
205 // Fetch the stored data
206 $object->fetch($id);
207 $res = $object->fetch_lines();
208 // Transfer the data from one to the other
209 if ($object->socid > 0) {
210 $newinter->socid = $object->socid;
211 $newinter->fk_project = $object->fk_project;
212 $newinter->fk_contrat = $object->fk_contrat;
213 } else {
214 $newinter->socid = GETPOSTINT("socid");
215 }
216
217 $newinter->entity = $object->entity;
218 $newinter->duration = $object->duration;
219
220 $newinter->description = $object->description;
221 $newinter->note_private = $object->note_private;
222 $newinter->note_public = $object->note_public;
223
224 // Create a new intervention
225 $extrafields->fetch_name_optionals_label($newinter->table_element);
226
227 $array_options = $extrafields->getOptionalsFromPost($newinter->table_element);
228 $newinter->array_options = $array_options;
229
230 $newfichinterid = $newinter->create($user);
231
232 if ($newfichinterid > 0) {
233 // Now we add line of details
234 foreach ($object->lines as $line) {
235 $newinter->addline($user, $newfichinterid, $line->desc, dol_now(), $line->duree, array());
236 }
237
238 // Update the number of interventions created from the template (model)
239 $object->updateNbGenDone();
240 // Redirect to the newly created interventions report
241 header('Location: '.DOL_URL_ROOT.'/fichinter/card.php?id='.$newfichinterid);
242 exit;
243 } else {
244 setEventMessages($newinter->error, $newinter->errors, 'errors');
245 $action = '';
246 }
247} elseif ($action == 'delete' && $permissiontodelete) {
248 // delete modele
249 $object->fetch($id);
250 $object->delete($user);
251 $id = 0;
252 header('Location: '.$_SERVER["PHP_SELF"]);
253 exit;
254} elseif ($action == 'setfrequency' && $permissiontoadd) {
255 // Set frequency and unit frequency
256 $object->fetch($id);
257 $object->setFrequencyAndUnit(GETPOSTINT('frequency'), GETPOST('unit_frequency', 'alpha'));
258} elseif ($action == 'setdate_when' && $permissiontoadd) {
259 // Set next date of execution
260 $object->fetch($id);
261 $date = dol_mktime(GETPOSTINT('date_whenhour'), GETPOSTINT('date_whenmin'), 0, GETPOSTINT('date_whenmonth'), GETPOSTINT('date_whenday'), GETPOSTINT('date_whenyear'));
262 if (!empty($date)) {
263 $object->setNextDate($date);
264 }
265} elseif ($action == 'setnb_gen_max' && $permissiontoadd) {
266 // Set max period
267 $object->fetch($id);
268 $object->setMaxPeriod(GETPOSTINT('nb_gen_max'));
269}
270
271
272/*
273 * View
274 */
275
276$help_url = '';
277
278llxHeader('', $langs->trans("RepeatableIntervention"), $help_url, '', 0, 0, '', '', '', 'mod-fichinter page-card-rec');
279
280$form = new Form($db);
281$fichinterrecstatic = new FichinterRec($db);
282$companystatic = new Societe($db);
283$contratstatic = null;
284$projectstatic = null;
285if (isModEnabled('contract')) {
286 $contratstatic = new Contrat($db);
287}
288if (isModEnabled('project')) {
289 $projectstatic = new Project($db);
290}
291
292$now = dol_now();
293$tmparray = dol_getdate($now);
294$today = dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray['year']); // Today is last second of current day
295
296
297
298// Create mode
299
300if ($action == 'create') {
301 print load_fiche_titre($langs->trans("CreateRepeatableIntervention"), '', 'intervention');
302
303 $object = new Fichinter($db); // Source invoice
304 //$object = new Managementfichinter($db); // Source invoice
305
306 if ($object->fetch($id, $ref) > 0) {
307 print '<form action="card-rec.php" method="post">';
308 print '<input type="hidden" name="token" value="'.newToken().'">';
309 print '<input type="hidden" name="action" value="add">';
310 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
311 print '<input type="hidden" name="fichinterid" value="'.$object->id.'">';
312
313 print dol_get_fiche_head();
314
315 $rowspan = 4;
316 if (isModEnabled('project') && $object->fk_project > 0) {
317 $rowspan++;
318 }
319 if (isModEnabled('contract') && $object->fk_contrat > 0) {
320 $rowspan++;
321 }
322
323 print '<table class="border centpercent">';
324
325 $object->fetch_thirdparty();
326
327 // Third party
328 print '<tr><td>'.$langs->trans("Customer").'</td><td>';
329 print $form->select_company($object->thirdparty->id, 'socid', '', 0, 1);
330
331 //.$object->thirdparty->getNomUrl(1,'customer').
332 print '</td><td>';
333 print $langs->trans("Comment");
334 print '</td></tr>';
335
336 // Title
337 print '<tr><td class="fieldrequired">'.$langs->trans("Title").'</td><td>';
338 print '<input class="flat quatrevingtpercent" type="text" name="title" value="'.dol_escape_htmltag(GETPOST("title", "alphanohtml")).'">';
339 print '</td>';
340
341 // Note
342 print '<td rowspan="'.$rowspan.'" valign="top">';
343 print '<textarea class="flat" name="description" wrap="soft" cols="60" rows="'.ROWS_4.'">';
344 print $object->description.'</textarea>';
345 print '</td></tr>';
346
347 // Author
348 print "<tr><td>".$langs->trans("Author")."</td><td>".$user->getFullName($langs)."</td></tr>";
349
350 if (!getDolGlobalString('FICHINTER_DISABLE_DETAILS') || getDolGlobalString('FICHINTER_DISABLE_DETAILS') == '2') {
351 // Duration
352 print '<tr><td>'.$langs->trans("TotalDuration").'</td>';
353 print '<td colspan="3">'.convertSecondToTime($object->duration, 'all', $conf->global->MAIN_DURATION_OF_WORKDAY).'</td>';
354 print '</tr>';
355 }
356
357 // Project
358 if (isModEnabled('project')) {
359 $formproject = new FormProjets($db);
360 print "<tr><td>".$langs->trans("Project")."</td><td>";
361 $projectid = GETPOST('projectid') ? GETPOST('projectid') : $object->fk_project;
362
363 $numprojet = $formproject->select_projects($object->thirdparty->id, $projectid, 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0, 0, '');
364 print ' &nbsp; <a href="'.DOL_URL_ROOT.'/projet/card.php?socid='.$object->thirdparty->id;
365 print '&action=create&status=1&backtopage='.urlencode($_SERVER["PHP_SELF"]).'?action=create';
366 print '&socid='.$object->thirdparty->id.(!empty($id) ? '&id='.$id : '').'">';
367 print $langs->trans("AddProject").'</a>';
368 print "</td></tr>";
369 }
370
371 // Contrat
372 if (isModEnabled('contract')) {
373 // This feature hang the application on large list of contracts, because the select component is not complete: it does not work like select of thirdparty or product to support large lists
374 // So we add a hidden option to avoid to have it used and the application locked, until the select_contract is fixed.
375 if (getDolGlobalString("CONTRACT_CAN_USE_THE_BUGGED_SELECT_COMPONENT")) {
376 $formcontract = new FormContract($db);
377 print "<tr><td>".$langs->trans("Contract")."</td><td>";
378 $contractid = GETPOST('contractid') ? GETPOST('contractid') : (!empty($object->fk_contrat) ? $object->fk_contrat : 0) ;
379 $numcontract = $formcontract->select_contract($object->thirdparty->id, $contractid, 'contracttid');
380 print "</td></tr>";
381 }
382 }
383 print "</table>";
384
385 print '<br><br>';
386
388 // Autogeneration
389 $title = $langs->trans("Recurrence");
390 print load_fiche_titre($title, '', 'calendar');
391
392 print '<table class="border centpercent">';
393
394 // Frequency
395 print '<tr><td class="titlefieldcreate">';
396 print $form->textwithpicto($langs->trans("Frequency"), $langs->transnoentitiesnoconv('toolTipFrequency'));
397 print "</td><td>";
398 print '<input type="text" name="frequency" value="'.GETPOSTINT('frequency').'" size="4">&nbsp;';
399 print $form->selectarray('unit_frequency', array('d' => $langs->trans('Day'), 'm' => $langs->trans('Month'), 'y' => $langs->trans('Year')), (GETPOST('unit_frequency') ? GETPOST('unit_frequency') : 'm'));
400 print "</td></tr>";
401
402 // First date of execution for cron
403 print "<tr><td>".$langs->trans('NextDateToExecution')."</td><td>";
404 if (empty($date_next_execution)) {
405 $date_next_execution = (GETPOST('rec_month') ? dol_mktime(12, 0, 0, GETPOSTINT('rec_month'), GETPOSTINT('rec_day'), GETPOSTINT('rec_year')) : -1);
406 }
407 print $form->selectDate($date_next_execution, 'rec_', 1, 1, 0, "add", 1, 1);
408 print "</td></tr>";
409
410 // Number max of generation
411 print "<tr><td>".$langs->trans("MaxPeriodNumber")."</td><td>";
412 print '<input type="text" name="nb_gen_max" value="'.GETPOSTINT('nb_gen_max').'" size="5">';
413 print "</td></tr>";
414
415 print "</table>";
416
417 print '<br>';
418
419 $title = $langs->trans("ProductsAndServices");
420 if (!isModEnabled("service")) {
421 $title = $langs->trans("Products");
422 } elseif (!isModEnabled("product")) {
423 $title = $langs->trans("Services");
424 }
425
426 print load_fiche_titre($title, '', '');
427
428 /*
429 * Fichinter lines
430 */
431 print '<table class="notopnoleftnoright" width="100%">';
432 print '<tr><td colspan="3">';
433
434 $sql = 'SELECT l.rowid, l.description, l.duree';
435 $sql .= " FROM ".MAIN_DB_PREFIX."fichinterdet as l";
436 $sql .= " WHERE l.fk_fichinter= ".((int) $object->id);
437 //$sql.= " AND l.fk_product is null ";
438 $sql .= " ORDER BY l.rang";
439
440 $result = $db->query($sql);
441 if ($result) {
442 $num = $db->num_rows($result);
443 $i = 0;
444 $total = 0;
445
446 echo '<table class="noborder centpercent">';
447 if ($num) {
448 print '<tr class="liste_titre">';
449 print '<td>'.$langs->trans("Description").'</td>';
450 print '<td class="center">'.$langs->trans("Duration").'</td>';
451 print "</tr>\n";
452 }
453 while ($i < $num) {
454 $objp = $db->fetch_object($result);
455 print '<tr class="oddeven">';
456
457 // Show product and description
458
459 print '<td>';
460 print '<a name="'.$objp->rowid.'"></a>'; // Anchor to return to the line
461
462 $text = img_object($langs->trans('Service'), 'service');
463
464 print $text.' '.nl2br($objp->description);
465
466 // Duration
467 print '<td class="center">'.convertSecondToTime($objp->duree).'</td>';
468 print "</tr>";
469
470 $i++;
471 }
472 $db->free($result);
473 } else {
474 print $db->error();
475 }
476 print "</table>";
477
478 print '</td></tr>';
479
480 print "</table>\n";
481
482 print dol_get_fiche_end();
483
484 print $form->buttonsSaveCancel("Create");
485
486 print "</form>\n";
487 } else {
488 dol_print_error(null, "Error, no fichinter ".$object->id);
489 }
490} elseif ($action == 'selsocforcreatefrommodel') {
491 print load_fiche_titre($langs->trans("CreateRepeatableIntervention"), '', 'intervention');
492 print dol_get_fiche_head([]);
493
494 print '<form name="fichinter" action="'.$_SERVER['PHP_SELF'].'" method="POST">';
495 print '<table class="border centpercent">';
496 print '<tr><td class="fieldrequired">'.$langs->trans("ThirdParty").'</td><td>';
497 print $form->select_company('', 'socid', '', 1, 1);
498 print '</td></tr>';
499 print '</table>';
500
501 print dol_get_fiche_end();
502
503 print '<input type="hidden" name="action" value="createfrommodel">';
504 print '<input type="hidden" name="id" value="'.$id.'">';
505 print '<input type="hidden" name="token" value="'.newToken().'">';
506 print $form->buttonsSaveCancel("CreateDraftIntervention", '');
507
508 print '</form>';
509} else {
510 // View mode
511
512 if ($id > 0) {
513 if ($object->fetch($id) > 0) {
514 $object->fetch_thirdparty();
515
516 $author = new User($db);
517 $author->fetch((int) $object->user_author_id);
518
519 $head = fichinter_rec_prepare_head($object);
520
521 print dol_get_fiche_head($head, 'card', $langs->trans("PredefinedInterventional"), 0, $object->picto);
522
523 // Intervention card
524 $linkback = '<a href="card-rec.php">'.$langs->trans("BackToList").'</a>';
525
526 $morehtmlref = '<div class="refidno">';
527 // Thirdparty
528
529 $morehtmlref .= $langs->trans('ThirdParty').' : '.$object->thirdparty->getNomUrl(1);
530 // Project
531 if (isModEnabled('project')) {
532 $formproject = new FormProjets($db);
533 $langs->load("projects");
534 $morehtmlref .= '<br>'.$langs->trans('Project').' ';
535 if ($user->hasRight('ficheinter', 'creer')) {
536 if ($action != 'classify') {
537 $morehtmlref .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => $object->id], true).'">';
538 $morehtmlref .= img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> : ';
539 }
540 if ($action == 'classify') {
541 $morehtmlref .= '<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
542 $morehtmlref .= '<input type="hidden" name="action" value="classin">';
543 $morehtmlref .= '<input type="hidden" name="token" value="'.newToken().'">';
544 $morehtmlref .= $formproject->select_projects($object->socid, (string) $object->fk_project, 'projectid', 0, 0, 1, 0, 1, 0, 0, '', 1);
545 $morehtmlref .= '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
546 $morehtmlref .= '</form>';
547 } else {
548 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, (string) $object->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300');
549 }
550 } else {
551 if (!empty($object->fk_project)) {
552 $proj = new Project($db);
553 $proj->fetch($object->fk_project);
554 $morehtmlref .= ' : '.$proj->getNomUrl(1);
555 if ($proj->title) {
556 $morehtmlref .= ' - '.$proj->title;
557 }
558 } else {
559 $morehtmlref .= '';
560 }
561 }
562 }
563 $morehtmlref .= '</div>';
564
565 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
566
567 print '<div class="fichecenter">';
568 print '<div class="fichehalfleft">';
569 print '<div class="underbanner clearboth"></div>';
570
571 print '<table class="border centpercent">';
572
573 print "<tr><td>".$langs->trans("Author").'</td><td colspan="3">'.$author->getFullName($langs)."</td></tr>";
574
575 if (!getDolGlobalString('FICHINTER_DISABLE_DETAILS') || getDolGlobalString('FICHINTER_DISABLE_DETAILS') == '2') {
576 // Duration
577 print '<tr><td class="titlefield">'.$langs->trans("TotalDuration").'</td>';
578 print '<td colspan="3">';
579 print convertSecondToTime($object->duration, 'all', $conf->global->MAIN_DURATION_OF_WORKDAY);
580 print '</td></tr>';
581 }
582
583 print '<tr><td>'.$langs->trans("Description").'</td><td colspan="3">'.nl2br($object->description)."</td></tr>";
584
585 // Contract
586 if (isModEnabled('contract') && $contratstatic !== null) {
587 // This feature hang the application on large list of contracts, because the select component is not complete: it does not work like select of thirdparty or product to support large lists
588 // So we add a hidden option to avoid to have it used and the application locked, until the select_contract is fixed.
589 if (getDolGlobalString("CONTRACT_CAN_USE_THE_BUGGED_SELECT_COMPONENT")) {
590 $langs->load('contracts');
591 print '<tr>';
592 print '<td>';
593
594 print '<table class="nobordernopadding" width="100%"><tr><td>';
595 print $langs->trans('Contract');
596 print '</td>';
597 if ($action != 'contrat') {
598 print '<td class="right"><a href="'.$_SERVER["PHP_SELF"].'?action=contrat&id='.$object->id.'&token='.newToken().'">';
599 print img_edit($langs->trans('SetContract'), 1);
600 print '</a></td>';
601 }
602 print '</tr></table>';
603 print '</td><td>';
604 if ($action == 'contrat') {
605 $formcontract = new FormContract($db);
606 $formcontract->formSelectContract($_SERVER["PHP_SELF"].'?id='.$object->id, $object->socid, $object->fk_contrat, 'contratid', 0, 1);
607 } else {
608 if ($object->fk_contrat) {
609 $contratstatic = new Contrat($db);
610 $contratstatic->fetch($object->fk_contrat);
611 print $contratstatic->getNomUrl(0, 0, 1);
612 } else {
613 print "&nbsp;";
614 }
615 }
616 print '</td>';
617 print '</tr>';
618 }
619 }
620 print "</table>";
621 print '</div>';
622
623 print '<div class="fichehalfright">';
624 print '<div class="underbanner clearboth"></div>';
625
626 $title = $langs->trans("Recurrence");
627 print load_fiche_titre($title, '', 'calendar');
628
629 print '<table class="border centpercent">';
630
631 // if "frequency" is empty or = 0, the recurrence is disabled
632 print '<tr><td class="titlefield">';
633 print '<table class="nobordernopadding" width="100%"><tr><td>';
634 print $langs->trans('Frequency');
635 print '</td>';
636 if ($action != 'editfrequency' && $user->hasRight('ficheinter', 'creer')) {
637 print '<td class="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editfrequency&token='.newToken().'&id='.$id.'">';
638 print img_edit($langs->trans('Edit'), 1).'</a></td>';
639 }
640 print '</tr></table>';
641 print '</td><td>';
642 if ($action == 'editfrequency') {
643 print '<form method="post" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'">';
644 print '<input type="hidden" name="action" value="setfrequency">';
645 print '<input type="hidden" name="token" value="'.newToken().'">';
646 print '<table class="nobordernopadding">';
647 print '<tr><td>';
648 print '<input type="text" name="frequency" value="'.$object->frequency.'" size="5">&nbsp;';
649 print $form->selectarray('unit_frequency', array('d' => $langs->trans('Day'), 'm' => $langs->trans('Month'), 'y' => $langs->trans('Year')), ($object->unit_frequency ? $object->unit_frequency : 'm'));
650 print '</td>';
651 print '<td class="left"><input type="submit" class="button button-edit" value="'.$langs->trans("Modify").'"></td>';
652 print '</tr></table></form>';
653 } else {
654 if ($object->frequency > 0) {
655 print $langs->trans('FrequencyPer_'.$object->unit_frequency, $object->frequency);
656 } else {
657 print $langs->trans("NotARecurringInterventionalTemplate");
658 }
659 }
660 print '</td></tr>';
661
662 // Date when
663 print '<tr><td>';
664 if ($user->hasRight('ficheinter', 'creer') && ($action == 'date_when' || $object->frequency > 0)) {
665 print $form->editfieldkey($langs->trans("NextDateToExecution"), 'date_when', $object->date_when, $object, $user->hasRight('ficheinter', 'creer'), 'day');
666 } else {
667 print $langs->trans("NextDateToExecution");
668 }
669 print '</td><td>';
670 if ($action == 'date_when' || $object->frequency > 0) {
671 print $form->editfieldval($langs->trans("NextDateToExecution"), 'date_when', $object->date_when, $object, $user->hasRight('ficheinter', 'creer'), 'day');
672 }
673 print '</td>';
674 print '</tr>';
675
676 // Max period / Rest period
677 print '<tr><td>';
678 if ($user->hasRight('ficheinter', 'creer') && ($action == 'nb_gen_max' || $object->frequency > 0)) {
679 print $form->editfieldkey($langs->trans("MaxPeriodNumber"), 'nb_gen_max', (string) $object->nb_gen_max, $object, $user->hasRight('ficheinter', 'creer'));
680 } else {
681 print $langs->trans("MaxPeriodNumber");
682 }
683
684 print '</td><td>';
685 if ($action == 'nb_gen_max' || $object->frequency > 0) {
686 print $form->editfieldval($langs->trans("MaxPeriodNumber"), 'nb_gen_max', $object->nb_gen_max ? $object->nb_gen_max : '', $object, $user->hasRight('ficheinter', 'creer'));
687 } else {
688 print '';
689 }
690
691 print '</td>';
692 print '</tr>';
693
694 print '</table>';
695
696 // Frequencry/Recurring section
697 if ($object->frequency > 0) {
698 print '<br>';
699 if (isModEnabled('cron')) {
700 $txtinfoadmin = $langs->trans("EnableAndSetupModuleCron", $langs->transnoentitiesnoconv("Module2300Name"));
701 print info_admin($txtinfoadmin);
702 }
703 print '<div class="underbanner clearboth"></div>';
704 print '<table class="border centpercent">';
705
706 // Nb of generation already done
707 print '<tr><td class="titlefield">'.$langs->trans("NbOfGenerationOfRecordDone").'</td>';
708 print '<td>';
709 print $object->nb_gen_done ? $object->nb_gen_done : '0';
710 print '</td>';
711 print '</tr>';
712
713 // Date last
714 print '<tr><td>';
715 print $langs->trans("DateLastGeneration");
716 print '</td><td>';
717 print dol_print_date($object->date_last_gen, 'dayhour');
718 print '</td>';
719 print '</tr>';
720 print '</table>';
721 print '<br>';
722 }
723
724 print '</div>';
725 print '</div>';
726
727 print '<div class="clearboth"></div><br>';
728
729 /*
730 * Lines
731 */
732
733 $title = $langs->trans("ProductsAndServices");
734 if (!isModEnabled("service")) {
735 $title = $langs->trans("Products");
736 } elseif (!isModEnabled("product")) {
737 $title = $langs->trans("Services");
738 }
739
740 print load_fiche_titre($title);
741
742 print '<table class="noborder centpercent">';
743 print '<tr class="liste_titre">';
744 print '<td>'.$langs->trans("Description").'</td>';
745 print '<td class="center">'.$langs->trans("Duration").'</td>';
746 print '</tr>';
747
748 $num = count($object->lines);
749 $i = 0;
750 while ($i < $num) {
751 $type =0;
752 // Show product and description
753 if (isset($object->lines[$i]->product_type)) {
754 $type = $object->lines[$i]->product_type;
755 } // else { $object->lines[$i]->fk_product_type; }
756
757 // TODO: $objp is not set here, so why test?
758 if (isset($objp) && is_object($objp)) { // $objp always null @phpstan-ignore-line
759 // Try to enhance type detection using date_start and date_end for free lines when type was not saved.
760 if (!empty($objp->date_start)) {
761 $type = 1;
762 }
763 if (!empty($objp->date_end)) {
764 $type = 1;
765 }
766 }
767
768 // Show line
769 print '<tr class="oddeven">';
770 print '<td>';
771 $text = img_object($langs->trans('Service'), 'service');
772 print $text.' '.nl2br($object->lines[$i]->desc);
773 print '</td>';
774
775 print '<td class="center">'.convertSecondToTime($object->lines[$i]->duree).'</td>';
776 print "</tr>\n";
777 $i++;
778 }
779 print '</table>';
780
781 // Action bar
782 print '<div class="tabsAction">';
783
784 if ($user->hasRight('ficheinter', 'creer')) {
785 print '<div class="inline-block divButAction">';
786 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=createfrommodel&token='.newToken();
787 print '&socid='.$object->thirdparty->id.'&id='.$object->id.'">';
788 print $langs->trans("AddIntervention").'</a></div>';
789 }
790
791 // Delete
792 print dolGetButtonAction($langs->trans("Delete"), '', 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), 'delete', $user->hasRight('ficheinter', 'supprimer'));
793
794 print '</div>';
795 } else {
796 print $langs->trans("ErrorRecordNotFound");
797 }
798 } else {
799 // List mode
800
801 $sql = "SELECT f.rowid as id, s.nom as name, s.rowid as socid, f.title,";
802 $sql .= " f.duree, f.fk_contrat, f.fk_projet as fk_project, f.frequency, f.nb_gen_done, f.nb_gen_max,";
803 $sql .= " f.date_last_gen, f.date_when, f.datec, f.status";
804
805 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter_rec as f";
806 $sql .= " , ".MAIN_DB_PREFIX."societe as s ";
807 if (!$user->hasRight('societe', 'client', 'voir')) {
808 $sql .= " , ".MAIN_DB_PREFIX."societe_commerciaux as sc";
809 }
810 $sql .= " WHERE f.fk_soc = s.rowid";
811 $sql .= " AND f.entity = ".$conf->entity;
812 if (!empty($socid)) {
813 $sql .= " AND s.rowid = ".((int) $socid);
814 }
815 if (!$user->hasRight('societe', 'client', 'voir')) {
816 $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
817 }
818 /*
819 if (!empty($search_ref)) {
820 $sql .= natural_search('f.title', $search_ref);
821 }
822 */
823 if (!empty($search_societe)) {
824 $sql .= natural_search('s.nom', $search_societe);
825 }
826 if (!empty($search_frequency) && $search_frequency == '1') {
827 $sql .= ' AND f.frequency > 0';
828 }
829 if (isset($search_frequency) && (string) $search_frequency == '0') {
830 $sql .= ' AND (f.frequency IS NULL or f.frequency = 0)';
831 }
832
833
834 //$sql .= " ORDER BY $sortfield $sortorder, rowid DESC ";
835 // $sql .= $db->plimit($limit + 1, $offset);
836
837 $resql = $db->query($sql);
838 if ($resql) {
839 $num = $db->num_rows($resql);
840
841 print_barre_liste($langs->trans("RepeatableIntervention"), $page, $_SERVER['PHP_SELF'], "&socid=$socid", $sortfield, $sortorder, '', $num, '', 'intervention');
842
843 print '<span class="opacitymedium">'.$langs->trans("ToCreateAPredefinedIntervention").'</span><br><br>';
844
845 $i = 0;
846 print '<table class="noborder centpercent">';
847 print '<tr class="liste_titre">';
848 print_liste_field_titre("Ref", $_SERVER['PHP_SELF'], "f.title", "", "", 'width="200px"', $sortfield, $sortorder, 'left ');
849 print_liste_field_titre("Company", $_SERVER['PHP_SELF'], "s.nom", "", "", 'width="200px"', $sortfield, $sortorder, 'left ');
850 if (isModEnabled('contract')) {
851 print_liste_field_titre("Contract", $_SERVER['PHP_SELF'], "f.fk_contrat", "", "", 'width="100px"', $sortfield, $sortorder, 'left ');
852 }
853 if (isModEnabled('project')) {
854 print_liste_field_titre("Project", $_SERVER['PHP_SELF'], "f.fk_project", "", "", 'width="100px"', $sortfield, $sortorder, 'left ');
855 }
856 print_liste_field_titre("Duration", $_SERVER['PHP_SELF'], 'f.duree', '', '', 'width="50px"', $sortfield, $sortorder, 'right ');
857 // Recurring or not
858 print_liste_field_titre("Frequency", $_SERVER['PHP_SELF'], "f.frequency", "", "", 'width="100px"', $sortfield, $sortorder, 'center ');
859 print_liste_field_titre("NbOfGenerationDoneShort", $_SERVER['PHP_SELF'], "f.nb_gen_done", "", "", 'width="100px"', $sortfield, $sortorder, 'center ');
860 print_liste_field_titre("DateLastGeneration", $_SERVER['PHP_SELF'], "f.date_last_gen", "", "", 'width="100px"', $sortfield, $sortorder, 'center ');
861 print_liste_field_titre("NextDateToIntervention", $_SERVER['PHP_SELF'], "f.date_when", "", "", 'width="100px"', $sortfield, $sortorder, 'center ');
862 print '<th width="100px"></th>';
863 print "</tr>\n";
864
865
866 // TODO filters
867
868 if ($num > 0) {
869 while ($i < min($num, $limit)) {
870 $objp = $db->fetch_object($resql);
871 $fichinterrecstatic->id = $objp->id;
872 $fichinterrecstatic->ref = $objp->title;
873 $fichinterrecstatic->title = $objp->title;
874
875 print '<tr class="oddeven">';
876 print '<td>'.$fichinterrecstatic->getNomUrl(1)."</td>\n";
877 if ($objp->socid) {
878 $companystatic->id = $objp->socid;
879 $companystatic->name = $objp->name;
880 print '<td>'.$companystatic->getNomUrl(1, 'customer').'</td>';
881 } else {
882 print '<td>'.$langs->trans("None").'</td>';
883 }
884
885 if (isModEnabled('contract') && $contratstatic !== null) {
886 print '<td>';
887 if ($objp->fk_contrat > 0) {
888 $contratstatic->fetch($objp->fk_contrat);
889 print $contratstatic->getNomUrl(1);
890 }
891 print '</td>';
892 }
893 if (isModEnabled('project') && $projectstatic !== null) {
894 print '<td>';
895 if ($objp->fk_project > 0) {
896 $projectstatic->fetch($objp->fk_project);
897 print $projectstatic->getNomUrl(1);
898 }
899 print '</td>';
900 }
901
902 print '<td class=right>'.convertSecondToTime($objp->duree).'</td>';
903
904 print '<td class="center">'.yn($objp->frequency ? 1 : 0).'</td>';
905
906 print '<td class="center">';
907 if ($objp->frequency) {
908 print $objp->nb_gen_done.($objp->nb_gen_max > 0 ? ' / '.$objp->nb_gen_max : '');
909 print '</td>';
910
911 print '<td class="center">';
912 print dol_print_date($db->jdate($objp->date_last_gen), 'day');
913 print '</td>';
914
915 print '<td class="center">';
916 print dol_print_date($db->jdate($objp->date_when), 'day');
917 print '</td>';
918 } else {
919 print '<span class="opacitymedium">'.$langs->trans('NA').'</span>';
920 print '</td>';
921 print '<td class="center">';
922 print '<span class="opacitymedium">'.$langs->trans('NA').'</span>';
923 print '</td>';
924 print '<td class="center">';
925 print '<span class="opacitymedium">'.$langs->trans('NA').'</span>';
926 print '</td>';
927 }
928
929 if ($user->hasRight('ficheinter', 'creer')) {
930 // Action column
931 print '<td class="center">';
932 if ($user->hasRight('ficheinter', 'creer')) {
933 if (empty($objp->frequency) || $db->jdate($objp->date_when) <= $today) {
934 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=createfrommodel';
935 print '&socid='.$objp->socid.'&id='.$objp->id.'&token='.newToken().'">';
936 print $langs->trans("NewIntervention").'</a>';
937 } else {
938 print $langs->trans("DateIsNotEnough");
939 }
940 } else {
941 print "&nbsp;";
942 }
943
944 print "</td>";
945
946 print "</tr>\n";
947 $i++;
948 }
949 }
950 } else {
951 print '<tr class="oddeven"><td colspan="10"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
952 }
953
954 print "</table>";
955 $db->free($resql);
956 } else {
958 }
959 }
960}
961llxFooter();
962$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:47
if(! $sortfield) if(! $sortorder) $object
Definition account.php:100
llxFooter($comment='', $zone='private', $disabledoutputofmessages=0)
Empty footer.
Definition wrapper.php:91
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader($head='', $title='', $help_url='', $target='', $disablejs=0, $disablehead=0, $arrayofjs='', $arrayofcss='', $morequerystring='', $morecssonbody='', $replacemainareaby='', $disablenofollow=0, $disablenoindex=0)
Empty header.
Definition wrapper.php:73
Class to manage recurring interventions.
Class to manage generation of HTML components for contract module.
Class to manage generation of HTML components Only common components must be here.
Class to manage building of HTML components.
Class to manage projects.
Class to manage third parties objects (customers, suppliers, prospects...)
Class to manage Dolibarr users.
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:248
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
fichinter_rec_prepare_head($object)
Prepare array with list of tabs.
dol_now($mode='gmt')
Return date for now.
dol_mktime($hour, $minute, $second, $month, $day, $year, $gm='auto', $check=1)
Return a timestamp date built from detailed information (by default a local PHP server timestamp) Rep...
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
print_liste_field_titre($name, $file="", $field="", $begin="", $param="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
print_barre_liste($title, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='generic', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $selectlimitsuffix=0, $hidenavigation=0, $pagenavastextinput=0, $morehtmlrightbeforearrow='')
Print a title with navigation controls for pagination.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='', $textonpictotooltip='')
Show information in HTML for admin users or standard users.
GETPOSTINT($paramname, $method=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $picto='', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limittoshow=0, $moretabssuffix='', $dragdropfile=0, $morecssdiv='')
Show tabs of a record.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
img_object($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $allowothertags=array())
Show a picto called object_picto (generic function)
natural_search($fields, $value, $mode=0, $nofirstand=0, $sqltoadd='')
Generate natural SQL search string for a criteria (this criteria can be tested on one or several fiel...
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false, $decorate=0)
Output date in a string format according to outputlangs (or langs if not defined).
dol_print_error($db=null, $error='', $errors=null)
Displays error message system with all the information to facilitate the diagnosis and the escalation...
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $mode=0)
Check permissions of a user to show a page and an object.