dolibarr 25.0.0-alpha
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
104$object = new FichinterRec($db);
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 // frequency and due date management
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->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
251 $result = $object->delete($user);
252 if ($result > 0) {
253 $id = 0;
254 header('Location: '.$_SERVER["PHP_SELF"]);
255 exit;
256 } else {
257 setEventMessages($object->error, $object->errors, 'errors');
258 }
259} elseif ($action == 'setfrequency' && $permissiontoadd) {
260 // Set frequency and unit frequency
261 $object->fetch($id);
262 $object->setFrequencyAndUnit(GETPOSTINT('frequency'), GETPOST('unit_frequency', 'alpha'));
263} elseif ($action == 'setdate_when' && $permissiontoadd) {
264 // Set next date of execution
265 $object->fetch($id);
266 $date = dol_mktime(GETPOSTINT('date_whenhour'), GETPOSTINT('date_whenmin'), 0, GETPOSTINT('date_whenmonth'), GETPOSTINT('date_whenday'), GETPOSTINT('date_whenyear'));
267 if (!empty($date)) {
268 $object->setNextDate($date);
269 }
270} elseif ($action == 'setnb_gen_max' && $permissiontoadd) {
271 // Set max period
272 $object->fetch($id);
273 $object->setMaxPeriod(GETPOSTINT('nb_gen_max'));
274}
275
276
277/*
278 * View
279 */
280
281$help_url = '';
282
283llxHeader('', $langs->trans("RepeatableIntervention"), $help_url, '', 0, 0, '', '', '', 'mod-fichinter page-card-rec');
284
285$form = new Form($db);
286$fichinterrecstatic = new FichinterRec($db);
287$companystatic = new Societe($db);
288$contratstatic = null;
289$projectstatic = null;
290if (isModEnabled('contract')) {
291 $contratstatic = new Contrat($db);
292}
293if (isModEnabled('project')) {
294 $projectstatic = new Project($db);
295}
296
297$now = dol_now();
298$tmparray = dol_getdate($now);
299$today = dol_mktime(23, 59, 59, $tmparray['mon'], $tmparray['mday'], $tmparray['year']); // Today is last second of current day
300
301
302
303// Create mode
304
305if ($action == 'create') {
306 print load_fiche_titre($langs->trans("CreateRepeatableIntervention"), '', 'intervention');
307
308 $object = new Fichinter($db); // Source invoice
309 //$object = new Managementfichinter($db); // Source invoice
310
311 if ($object->fetch($id, $ref) > 0) {
312 print '<form action="card-rec.php" method="post">';
313 print '<input type="hidden" name="token" value="'.newToken().'">';
314 print '<input type="hidden" name="action" value="add">';
315 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
316 print '<input type="hidden" name="fichinterid" value="'.$object->id.'">';
317
318 print dol_get_fiche_head();
319
320 $rowspan = 4;
321 if (isModEnabled('project') && $object->fk_project > 0) {
322 $rowspan++;
323 }
324 if (isModEnabled('contract') && $object->fk_contrat > 0) {
325 $rowspan++;
326 }
327
328 print '<table class="border centpercent">';
329
330 $object->fetch_thirdparty();
331
332 // Third party
333 print '<tr><td>'.$langs->trans("Customer").'</td><td>';
334 print $form->select_company($object->thirdparty->id, 'socid', '', 0, 1);
335
336 //.$object->thirdparty->getNomUrl(1,'customer').
337 print '</td><td>';
338 print $langs->trans("Comment");
339 print '</td></tr>';
340
341 // Title
342 print '<tr><td class="fieldrequired">'.$langs->trans("Title").'</td><td>';
343 print '<input class="flat quatrevingtpercent" type="text" name="title" value="'.dol_escape_htmltag(GETPOST("title", "alphanohtml")).'">';
344 print '</td>';
345
346 // Note
347 print '<td rowspan="'.$rowspan.'" valign="top">';
348 print '<textarea class="flat" name="description" wrap="soft" cols="60" rows="'.ROWS_4.'">';
349 print $object->description.'</textarea>';
350 print '</td></tr>';
351
352 // Author
353 print "<tr><td>".$langs->trans("Author")."</td><td>".$user->getFullName($langs)."</td></tr>";
354
355 if (!getDolGlobalString('FICHINTER_DISABLE_DETAILS') || getDolGlobalString('FICHINTER_DISABLE_DETAILS') == '2') {
356 // Duration
357 print '<tr><td>'.$langs->trans("TotalDuration").'</td>';
358 print '<td colspan="3">'.convertSecondToTime($object->duration, 'all', $conf->global->MAIN_DURATION_OF_WORKDAY).'</td>';
359 print '</tr>';
360 }
361
362 // Project
363 if (isModEnabled('project')) {
364 $formproject = new FormProjets($db);
365 print "<tr><td>".$langs->trans("Project")."</td><td>";
366 $projectid = GETPOST('projectid') ? GETPOST('projectid') : $object->fk_project;
367
368 $numprojet = $formproject->select_projects($object->thirdparty->id, $projectid, 'projectid', 0, 0, 1, 0, 0, 0, 0, '', 0, 0, '');
369 print ' &nbsp; <a href="'.DOL_URL_ROOT.'/projet/card.php?socid='.$object->thirdparty->id;
370 print '&action=create&status=1&backtopage='.urlencode($_SERVER["PHP_SELF"]).'?action=create';
371 print '&socid='.$object->thirdparty->id.(!empty($id) ? '&id='.$id : '').'">';
372 print $langs->trans("AddProject").'</a>';
373 print "</td></tr>";
374 }
375
376 // Contrat
377 if (isModEnabled('contract')) {
378 // 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
379 // So we add a hidden option to avoid to have it used and the application locked, until the select_contract is fixed.
380 if (getDolGlobalString("CONTRACT_CAN_USE_THE_BUGGED_SELECT_COMPONENT")) {
381 $formcontract = new FormContract($db);
382 print "<tr><td>".$langs->trans("Contract")."</td><td>";
383 $contractid = GETPOST('contractid') ? GETPOST('contractid') : (!empty($object->fk_contrat) ? $object->fk_contrat : 0) ;
384 $numcontract = $formcontract->select_contract($object->thirdparty->id, $contractid, 'contracttid');
385 print "</td></tr>";
386 }
387 }
388 print "</table>";
389
390 print '<br><br>';
391
393 // Autogeneration
394 $title = $langs->trans("Recurrence");
395 print load_fiche_titre($title, '', 'calendar');
396
397 print '<table class="border centpercent">';
398
399 // Frequency
400 print '<tr><td class="titlefieldcreate">';
401 print $form->textwithpicto($langs->trans("Frequency"), $langs->transnoentitiesnoconv('toolTipFrequency'));
402 print "</td><td>";
403 print '<input type="text" name="frequency" value="'.GETPOSTINT('frequency').'" size="4">&nbsp;';
404 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'));
405 print "</td></tr>";
406
407 // First date of execution for cron
408 print "<tr><td>".$langs->trans('NextDateToExecution')."</td><td>";
409 if (empty($date_next_execution)) {
410 $date_next_execution = (GETPOST('rec_month') ? dol_mktime(12, 0, 0, GETPOSTINT('rec_month'), GETPOSTINT('rec_day'), GETPOSTINT('rec_year')) : -1);
411 }
412 print $form->selectDate($date_next_execution, 'rec_', 1, 1, 0, "add", 1, 1);
413 print "</td></tr>";
414
415 // Number max of generation
416 print "<tr><td>".$langs->trans("MaxPeriodNumber")."</td><td>";
417 print '<input type="text" name="nb_gen_max" value="'.GETPOSTINT('nb_gen_max').'" size="5">';
418 print "</td></tr>";
419
420 print "</table>";
421
422 print '<br>';
423
424 $title = $langs->trans("ProductsAndServices");
425 if (!isModEnabled("service")) {
426 $title = $langs->trans("Products");
427 } elseif (!isModEnabled("product")) {
428 $title = $langs->trans("Services");
429 }
430
431 print load_fiche_titre($title, '', '');
432
433 /*
434 * Fichinter lines
435 */
436 print '<table class="notopnoleftnoright" width="100%">';
437 print '<tr><td colspan="3">';
438
439 $sql = 'SELECT l.rowid, l.description, l.duree';
440 $sql .= " FROM ".MAIN_DB_PREFIX."fichinterdet as l";
441 $sql .= " WHERE l.fk_fichinter= ".((int) $object->id);
442 //$sql.= " AND l.fk_product is null ";
443 $sql .= " ORDER BY l.rang";
444
445 $result = $db->query($sql);
446 if ($result) {
447 $num = $db->num_rows($result);
448 $i = 0;
449 $total = 0;
450
451 echo '<table class="noborder centpercent">';
452 if ($num) {
453 print '<tr class="liste_titre">';
454 print '<td>'.$langs->trans("Description").'</td>';
455 print '<td class="center">'.$langs->trans("Duration").'</td>';
456 print "</tr>\n";
457 }
458 while ($i < $num) {
459 $objp = $db->fetch_object($result);
460 print '<tr class="oddeven">';
461
462 // Show product and description
463
464 print '<td>';
465 print '<a name="'.$objp->rowid.'"></a>'; // Anchor to return to the line
466
467 $text = img_object($langs->trans('Service'), 'service');
468
469 print $text.' '.nl2br($objp->description);
470
471 // Duration
472 print '<td class="center">'.convertSecondToTime($objp->duree).'</td>';
473 print "</tr>";
474
475 $i++;
476 }
477 $db->free($result);
478 } else {
479 print $db->error();
480 }
481 print "</table>";
482
483 print '</td></tr>';
484
485 print "</table>\n";
486
487 print dol_get_fiche_end();
488
489 print $form->buttonsSaveCancel("Create");
490
491 print "</form>\n";
492 } else {
493 dol_print_error(null, "Error, no fichinter ".$object->id);
494 }
495} elseif ($action == 'selsocforcreatefrommodel') {
496 print load_fiche_titre($langs->trans("CreateRepeatableIntervention"), '', 'intervention');
497 print dol_get_fiche_head([]);
498
499 print '<form name="fichinter" action="'.$_SERVER['PHP_SELF'].'" method="POST">';
500 print '<table class="border centpercent">';
501 print '<tr><td class="fieldrequired">'.$langs->trans("ThirdParty").'</td><td>';
502 print $form->select_company('', 'socid', '', 1, 1);
503 print '</td></tr>';
504 print '</table>';
505
506 print dol_get_fiche_end();
507
508 print '<input type="hidden" name="action" value="createfrommodel">';
509 print '<input type="hidden" name="id" value="'.$id.'">';
510 print '<input type="hidden" name="token" value="'.newToken().'">';
511 print $form->buttonsSaveCancel("CreateDraftIntervention", '');
512
513 print '</form>';
514} else {
515 // View mode
516
517 if ($id > 0) {
518 if ($object->fetch($id) > 0) {
519 $object->fetch_thirdparty();
520
521 $author = new User($db);
522 $author->fetch((int) $object->user_author_id);
523
524 $head = fichinter_rec_prepare_head($object);
525
526 print dol_get_fiche_head($head, 'card', $langs->trans("PredefinedInterventional"), 0, $object->picto);
527
528 // Intervention card
529 $linkback = '<a href="card-rec.php">'.$langs->trans("BackToList").'</a>';
530
531 $morehtmlref = '<div class="refidno">';
532 // Thirdparty
533
534 $morehtmlref .= $langs->trans('ThirdParty').' : '.$object->thirdparty->getNomUrl(1);
535 // Project
536 if (isModEnabled('project')) {
537 $formproject = new FormProjets($db);
538 $langs->load("projects");
539 $morehtmlref .= '<br>'.$langs->trans('Project').' ';
540 if ($user->hasRight('ficheinter', 'creer')) {
541 if ($action != 'classify') {
542 $morehtmlref .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => $object->id], true).'">';
543 $morehtmlref .= img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> : ';
544 }
545 if ($action == 'classify') {
546 $morehtmlref .= '<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">';
547 $morehtmlref .= '<input type="hidden" name="action" value="classin">';
548 $morehtmlref .= '<input type="hidden" name="token" value="'.newToken().'">';
549 $morehtmlref .= $formproject->select_projects($object->socid, (string) $object->fk_project, 'projectid', 0, 0, 1, 0, 1, 0, 0, '', 1);
550 $morehtmlref .= '<input type="submit" class="button valignmiddle" value="'.$langs->trans("Modify").'">';
551 $morehtmlref .= '</form>';
552 } else {
553 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, (string) $object->fk_project, 'none', 0, 0, 0, 1, '', 'maxwidth300');
554 }
555 } else {
556 if (!empty($object->fk_project)) {
557 $proj = new Project($db);
558 $proj->fetch($object->fk_project);
559 $morehtmlref .= ' : '.$proj->getNomUrl(1);
560 if ($proj->title) {
561 $morehtmlref .= ' - '.$proj->title;
562 }
563 } else {
564 $morehtmlref .= '';
565 }
566 }
567 }
568 $morehtmlref .= '</div>';
569
570 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
571
572 print '<div class="fichecenter">';
573 print '<div class="fichehalfleft">';
574 print '<div class="underbanner clearboth"></div>';
575
576 print '<table class="border centpercent">';
577
578 print "<tr><td>".$langs->trans("Author").'</td><td colspan="3">'.$author->getFullName($langs)."</td></tr>";
579
580 if (!getDolGlobalString('FICHINTER_DISABLE_DETAILS') || getDolGlobalString('FICHINTER_DISABLE_DETAILS') == '2') {
581 // Duration
582 print '<tr><td class="titlefield">'.$langs->trans("TotalDuration").'</td>';
583 print '<td colspan="3">';
584 print convertSecondToTime($object->duration, 'all', $conf->global->MAIN_DURATION_OF_WORKDAY);
585 print '</td></tr>';
586 }
587
588 print '<tr><td>'.$langs->trans("Description").'</td><td colspan="3">'.nl2br($object->description)."</td></tr>";
589
590 // Contract
591 if (isModEnabled('contract') && $contratstatic !== null) {
592 // 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
593 // So we add a hidden option to avoid to have it used and the application locked, until the select_contract is fixed.
594 if (getDolGlobalString("CONTRACT_CAN_USE_THE_BUGGED_SELECT_COMPONENT")) {
595 $langs->load('contracts');
596 print '<tr>';
597 print '<td>';
598
599 print '<table class="nobordernopadding" width="100%"><tr><td>';
600 print $langs->trans('Contract');
601 print '</td>';
602 if ($action != 'contrat') {
603 print '<td class="right"><a href="'.$_SERVER["PHP_SELF"].'?action=contrat&id='.$object->id.'&token='.newToken().'">';
604 print img_edit($langs->trans('SetContract'), 1);
605 print '</a></td>';
606 }
607 print '</tr></table>';
608 print '</td><td>';
609 if ($action == 'contrat') {
610 $formcontract = new FormContract($db);
611 $formcontract->formSelectContract($_SERVER["PHP_SELF"].'?id='.$object->id, $object->socid, $object->fk_contrat, 'contratid', 0, 1);
612 } else {
613 if ($object->fk_contrat) {
614 $contratstatic = new Contrat($db);
615 $contratstatic->fetch($object->fk_contrat);
616 print $contratstatic->getNomUrl(0, 0, 1);
617 } else {
618 print "&nbsp;";
619 }
620 }
621 print '</td>';
622 print '</tr>';
623 }
624 }
625 print "</table>";
626 print '</div>';
627
628 print '<div class="fichehalfright">';
629 print '<div class="underbanner clearboth"></div>';
630
631 $title = $langs->trans("Recurrence");
632 print load_fiche_titre($title, '', 'calendar');
633
634 print '<table class="border centpercent">';
635
636 // if "frequency" is empty or = 0, the recurrence is disabled
637 print '<tr><td class="titlefield">';
638 print '<table class="nobordernopadding" width="100%"><tr><td>';
639 print $langs->trans('Frequency');
640 print '</td>';
641 if ($action != 'editfrequency' && $user->hasRight('ficheinter', 'creer')) {
642 print '<td class="right"><a href="'.$_SERVER["PHP_SELF"].'?action=editfrequency&token='.newToken().'&id='.$id.'">';
643 print img_edit($langs->trans('Edit'), 1).'</a></td>';
644 }
645 print '</tr></table>';
646 print '</td><td>';
647 if ($action == 'editfrequency') {
648 print '<form method="post" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'">';
649 print '<input type="hidden" name="action" value="setfrequency">';
650 print '<input type="hidden" name="token" value="'.newToken().'">';
651 print '<table class="nobordernopadding">';
652 print '<tr><td>';
653 print '<input type="text" name="frequency" value="'.$object->frequency.'" size="5">&nbsp;';
654 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'));
655 print '</td>';
656 print '<td class="left"><input type="submit" class="button button-edit" value="'.$langs->trans("Modify").'"></td>';
657 print '</tr></table></form>';
658 } else {
659 if ($object->frequency > 0) {
660 print $langs->trans('FrequencyPer_'.$object->unit_frequency, $object->frequency);
661 } else {
662 print $langs->trans("NotARecurringInterventionalTemplate");
663 }
664 }
665 print '</td></tr>';
666
667 // Date when
668 print '<tr><td>';
669 if ($user->hasRight('ficheinter', 'creer') && ($action == 'date_when' || $object->frequency > 0)) {
670 print $form->editfieldkey($langs->trans("NextDateToExecution"), 'date_when', $object->date_when, $object, $user->hasRight('ficheinter', 'creer'), 'day');
671 } else {
672 print $langs->trans("NextDateToExecution");
673 }
674 print '</td><td>';
675 if ($action == 'date_when' || $object->frequency > 0) {
676 print $form->editfieldval($langs->trans("NextDateToExecution"), 'date_when', $object->date_when, $object, $user->hasRight('ficheinter', 'creer'), 'day');
677 }
678 print '</td>';
679 print '</tr>';
680
681 // Max period / Rest period
682 print '<tr><td>';
683 if ($user->hasRight('ficheinter', 'creer') && ($action == 'nb_gen_max' || $object->frequency > 0)) {
684 print $form->editfieldkey($langs->trans("MaxPeriodNumber"), 'nb_gen_max', (string) $object->nb_gen_max, $object, $user->hasRight('ficheinter', 'creer'));
685 } else {
686 print $langs->trans("MaxPeriodNumber");
687 }
688
689 print '</td><td>';
690 if ($action == 'nb_gen_max' || $object->frequency > 0) {
691 print $form->editfieldval($langs->trans("MaxPeriodNumber"), 'nb_gen_max', $object->nb_gen_max ? $object->nb_gen_max : '', $object, $user->hasRight('ficheinter', 'creer'));
692 } else {
693 print '';
694 }
695
696 print '</td>';
697 print '</tr>';
698
699 print '</table>';
700
701 // Frequencry/Recurring section
702 if ($object->frequency > 0) {
703 print '<br>';
704 if (isModEnabled('cron')) {
705 $txtinfoadmin = $langs->trans("EnableAndSetupModuleCron", $langs->transnoentitiesnoconv("Module2300Name"));
706 print info_admin($txtinfoadmin);
707 }
708 print '<div class="underbanner clearboth"></div>';
709 print '<table class="border centpercent">';
710
711 // Nb of generation already done
712 print '<tr><td class="titlefield">'.$langs->trans("NbOfGenerationOfRecordDone").'</td>';
713 print '<td>';
714 print $object->nb_gen_done ? $object->nb_gen_done : '0';
715 print '</td>';
716 print '</tr>';
717
718 // Date last
719 print '<tr><td>';
720 print $langs->trans("DateLastGeneration");
721 print '</td><td>';
722 print dol_print_date($object->date_last_gen, 'dayhour');
723 print '</td>';
724 print '</tr>';
725 print '</table>';
726 print '<br>';
727 }
728
729 print '</div>';
730 print '</div>';
731
732 print '<div class="clearboth"></div><br>';
733
734 /*
735 * Lines
736 */
737
738 $title = $langs->trans("ProductsAndServices");
739 if (!isModEnabled("service")) {
740 $title = $langs->trans("Products");
741 } elseif (!isModEnabled("product")) {
742 $title = $langs->trans("Services");
743 }
744
745 print load_fiche_titre($title);
746
747 print '<table class="noborder centpercent">';
748 print '<tr class="liste_titre">';
749 print '<td>'.$langs->trans("Description").'</td>';
750 print '<td class="center">'.$langs->trans("Duration").'</td>';
751 print '</tr>';
752
753 $num = count($object->lines);
754 $i = 0;
755 while ($i < $num) {
756 $type = 0;
757 // Show product and description
758 if (isset($object->lines[$i]->product_type)) {
759 $type = $object->lines[$i]->product_type;
760 } // else { $object->lines[$i]->fk_product_type; }
761
762 // TODO: $objp is not set here, so why test?
763 if (isset($objp) && is_object($objp)) { // $objp always null @phpstan-ignore-line
764 // Try to enhance type detection using date_start and date_end for free lines when type was not saved.
765 if (!empty($objp->date_start)) {
766 $type = 1;
767 }
768 if (!empty($objp->date_end)) {
769 $type = 1;
770 }
771 }
772
773 // Show line
774 print '<tr class="oddeven">';
775 print '<td>';
776 $text = img_object($langs->trans('Service'), 'service');
777 print $text.' '.nl2br($object->lines[$i]->desc);
778 print '</td>';
779
780 print '<td class="center">'.convertSecondToTime($object->lines[$i]->duree).'</td>';
781 print "</tr>\n";
782 $i++;
783 }
784 print '</table>';
785
786 // Action bar
787 print '<div class="tabsAction">';
788
789 if ($user->hasRight('ficheinter', 'creer')) {
790 print '<div class="inline-block divButAction">';
791 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=createfrommodel&token='.newToken();
792 print '&socid='.$object->thirdparty->id.'&id='.$object->id.'">';
793 print $langs->trans("AddIntervention").'</a></div>';
794 }
795
796 // Delete
797 print dolGetButtonAction($langs->trans("Delete"), $langs->trans("Delete"), 'delete', dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id, 'action' => 'delete'], true), 'delete', $user->hasRight('ficheinter', 'supprimer'), array('attr' => array('class' => 'reposition')))."\n";
798
799 print '</div>';
800 } else {
801 print $langs->trans("ErrorRecordNotFound");
802 }
803 } else {
804 // List mode
805
806 $sql = "SELECT f.rowid as id, s.nom as name, s.rowid as socid, f.title,";
807 $sql .= " f.duree, f.fk_contrat, f.fk_projet as fk_project, f.frequency, f.nb_gen_done, f.nb_gen_max,";
808 $sql .= " f.date_last_gen, f.date_when, f.datec, f.status";
809
810 $sql .= " FROM ".MAIN_DB_PREFIX."fichinter_rec as f";
811 $sql .= " , ".MAIN_DB_PREFIX."societe as s ";
812 if (!$user->hasRight('societe', 'client', 'voir')) {
813 $sql .= " , ".MAIN_DB_PREFIX."societe_commerciaux as sc";
814 }
815 $sql .= " WHERE f.fk_soc = s.rowid";
816 $sql .= " AND f.entity = ".((int) $conf->entity);
817 if (!empty($socid)) {
818 $sql .= " AND s.rowid = ".((int) $socid);
819 }
820 if (!$user->hasRight('societe', 'client', 'voir')) {
821 $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = ".((int) $user->id);
822 }
823 /*
824 if (!empty($search_ref)) {
825 $sql .= natural_search('f.title', $search_ref);
826 }
827 */
828 if (!empty($search_societe)) {
829 $sql .= natural_search('s.nom', $search_societe);
830 }
831 if (!empty($search_frequency) && $search_frequency == '1') {
832 $sql .= ' AND f.frequency > 0';
833 }
834 if (isset($search_frequency) && (string) $search_frequency == '0') {
835 $sql .= ' AND (f.frequency IS NULL or f.frequency = 0)';
836 }
837
838
839 //$sql .= " ORDER BY $sortfield $sortorder, rowid DESC ";
840 // $sql .= $db->plimit($limit + 1, $offset);
841
842 $resql = $db->query($sql);
843 if ($resql) {
844 $num = $db->num_rows($resql);
845
846 print_barre_liste($langs->trans("RepeatableIntervention"), $page, $_SERVER['PHP_SELF'], "&socid=$socid", $sortfield, $sortorder, '', $num, '', 'intervention');
847
848 print '<div class="info"><span class="">'.$langs->trans("ToCreateAPredefinedIntervention").'</span></div><br>';
849
850 $i = 0;
851 print '<table class="noborder centpercent">';
852 print '<tr class="liste_titre">';
853 print_liste_field_titre("Ref", $_SERVER['PHP_SELF'], "f.title", "", "", 'width="200px"', $sortfield, $sortorder, 'left ');
854 print_liste_field_titre("Company", $_SERVER['PHP_SELF'], "s.nom", "", "", 'width="200px"', $sortfield, $sortorder, 'left ');
855 if (isModEnabled('contract')) {
856 print_liste_field_titre("Contract", $_SERVER['PHP_SELF'], "f.fk_contrat", "", "", 'width="100px"', $sortfield, $sortorder, 'left ');
857 }
858 if (isModEnabled('project')) {
859 print_liste_field_titre("Project", $_SERVER['PHP_SELF'], "f.fk_project", "", "", 'width="100px"', $sortfield, $sortorder, 'left ');
860 }
861 print_liste_field_titre("Duration", $_SERVER['PHP_SELF'], 'f.duree', '', '', 'width="50px"', $sortfield, $sortorder, 'right ');
862 // Recurring or not
863 print_liste_field_titre("Frequency", $_SERVER['PHP_SELF'], "f.frequency", "", "", 'width="100px"', $sortfield, $sortorder, 'center ');
864 print_liste_field_titre("NbOfGenerationDoneShort", $_SERVER['PHP_SELF'], "f.nb_gen_done", "", "", 'width="100px"', $sortfield, $sortorder, 'center ');
865 print_liste_field_titre("DateLastGeneration", $_SERVER['PHP_SELF'], "f.date_last_gen", "", "", 'width="100px"', $sortfield, $sortorder, 'center ');
866 print_liste_field_titre("NextDateToIntervention", $_SERVER['PHP_SELF'], "f.date_when", "", "", 'width="100px"', $sortfield, $sortorder, 'center ');
867 print '<th width="100px"></th>';
868 print "</tr>\n";
869
870
871 // TODO filters
872
873 if ($num > 0) {
874 while ($i < min($num, $limit)) {
875 $objp = $db->fetch_object($resql);
876 $fichinterrecstatic->id = $objp->id;
877 $fichinterrecstatic->ref = $objp->title;
878 $fichinterrecstatic->title = $objp->title;
879
880 print '<tr class="oddeven">';
881 print '<td>'.$fichinterrecstatic->getNomUrl(1)."</td>\n";
882 if ($objp->socid) {
883 $companystatic->id = $objp->socid;
884 $companystatic->name = $objp->name;
885 print '<td>'.$companystatic->getNomUrl(1, 'customer').'</td>';
886 } else {
887 print '<td>'.$langs->trans("None").'</td>';
888 }
889
890 if (isModEnabled('contract') && $contratstatic !== null) {
891 print '<td>';
892 if ($objp->fk_contrat > 0) {
893 $contratstatic->fetch($objp->fk_contrat);
894 print $contratstatic->getNomUrl(1);
895 }
896 print '</td>';
897 }
898 if (isModEnabled('project') && $projectstatic !== null) {
899 print '<td>';
900 if ($objp->fk_project > 0) {
901 $projectstatic->fetch($objp->fk_project);
902 print $projectstatic->getNomUrl(1);
903 }
904 print '</td>';
905 }
906
907 print '<td class=right>'.convertSecondToTime($objp->duree).'</td>';
908
909 print '<td class="center">'.yn($objp->frequency ? 1 : 0).'</td>';
910
911 print '<td class="center">';
912 if ($objp->frequency) {
913 print $objp->nb_gen_done.($objp->nb_gen_max > 0 ? ' / '.$objp->nb_gen_max : '');
914 print '</td>';
915
916 print '<td class="center">';
917 print dol_print_date($db->jdate($objp->date_last_gen), 'day');
918 print '</td>';
919
920 print '<td class="center">';
921 print dol_print_date($db->jdate($objp->date_when), 'day');
922 print '</td>';
923 } else {
924 print '<span class="opacitymedium">'.$langs->trans('NA').'</span>';
925 print '</td>';
926 print '<td class="center">';
927 print '<span class="opacitymedium">'.$langs->trans('NA').'</span>';
928 print '</td>';
929 print '<td class="center">';
930 print '<span class="opacitymedium">'.$langs->trans('NA').'</span>';
931 print '</td>';
932 }
933
934 if ($user->hasRight('ficheinter', 'creer')) {
935 // Action column
936 print '<td class="center">';
937 if ($user->hasRight('ficheinter', 'creer')) {
938 if (empty($objp->frequency) || $db->jdate($objp->date_when) <= $today) {
939 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?action=createfrommodel';
940 print '&socid='.$objp->socid.'&id='.$objp->id.'&token='.newToken().'">';
941 print $langs->trans("NewIntervention").'</a>';
942 } else {
943 print $langs->trans("DateIsNotEnough");
944 }
945 } else {
946 print "&nbsp;";
947 }
948
949 print "</td>";
950
951 print "</tr>\n";
952 $i++;
953 }
954 }
955 } else {
956 print '<tr class="oddeven"><td colspan="10"><span class="opacitymedium">'.$langs->trans("None").'</span></td></tr>';
957 }
958
959 print "</table>";
960 $db->free($resql);
961 } else {
962 dol_print_error($db);
963 }
964 }
965}
966llxFooter();
967$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:253
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
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...
dolBuildUrl($url, $params=[], $addtoken=false, $anchor='')
Return path of url.
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...
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0, $nodefault=0)
Return value of a param into GET or POST supervariable.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
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).
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
dol_getdate($timestamp, $fast=false, $forcetimezone='')
Return an array with locale date info.
print_liste_field_titre($name, $file="", $field="", $begin="", $param="", $moreattrib="", $sortfield="", $sortorder="", $prefix="", $tooltip="", $forcenowrapcolumntitle=0)
Show title line of an array.
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.
Definition html.lib.php:540
dol_get_fiche_end($notab=0)
Return tab footer of a card.
Definition html.lib.php:738
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='', $morecssonpicto='widthpictotitle')
Load a title with picto.
info_admin($text, $infoonimgalt=0, $nodiv=0, $admin='1', $morecss='hideonsmartphone', $textfordropdown='', $picto='', $textonpictotooltip='', $cssfordropdown='info_admin')
Show information in HTML for admin users or standard users.
restrictedArea(User $user, $features, $object=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0, $nodie=0, $mode='')
Check permissions of a user to show a page and an object.