dolibarr 25.0.0-alpha
mo_card.php
Go to the documentation of this file.
1<?php
2/* Copyright (C) 2017-2020 Laurent Destailleur <eldy@users.sourceforge.net>
3 * Copyright (C) 2024 Alexandre Spangaro <alexandre@inovea-conseil.com>
4 * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
5 * Copyright (C) 2024-2026 MDW <mdeweerd@users.noreply.github.com>
6 *
7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 3 of the License, or
10 * (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 * GNU General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program. If not, see <https://www.gnu.org/licenses/>.
19 */
20
28// Load Dolibarr environment
29require '../main.inc.php';
39require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
40require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
41require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
42require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php';
43require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
44require_once DOL_DOCUMENT_ROOT.'/mrp/class/mo.class.php';
45require_once DOL_DOCUMENT_ROOT.'/mrp/lib/mrp_mo.lib.php';
46require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
47require_once DOL_DOCUMENT_ROOT.'/bom/lib/bom.lib.php';
48
49if (isModEnabled('workstation')) {
50 require_once DOL_DOCUMENT_ROOT.'/workstation/class/workstation.class.php';
51}
52
53// Load translation files required by the page
54$langs->loadLangs(array('mrp', 'other'));
55
56
57// Get parameters
58$id = GETPOSTINT('id');
59$ref = GETPOST('ref', 'alpha');
60$action = GETPOST('action', 'aZ09');
61$confirm = GETPOST('confirm', 'alpha');
62$cancel = GETPOST('cancel');
63$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'mocard'; // To manage different context of search
64$backtopage = GETPOST('backtopage', 'alpha');
65$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
66$TBomLineId = GETPOST('bomlineid', 'array:int');
67$lineid = GETPOSTINT('lineid');
68$socid = GETPOSTINT("socid");
69
70// Initialize a technical objects
71$object = new Mo($db);
72$objectbom = new BOM($db);
73
74$diroutputmassaction = $conf->mrp->dir_output.'/temp/massgeneration/'.$user->id;
75$hookmanager->initHooks(array('mocard', 'globalcard')); // Note that conf->hooks_modules contains array
76
77// Fetch optionals attributes and labels
78$extrafields->fetch_name_optionals_label($object->table_element);
79
80$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
81
82// Initialize array of search criteria
83$search_all = GETPOST("search_all", 'alpha');
84$search = array();
85foreach ($object->fields as $key => $val) {
86 if (GETPOST('search_'.$key, 'alpha')) {
87 $search[$key] = GETPOST('search_'.$key, 'alpha');
88 }
89}
90
91if (empty($action) && empty($id) && empty($ref)) {
92 $action = 'view';
93}
94
95// Load object
96include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be 'include', not 'include_once'.
97
98if (GETPOSTINT('fk_bom') > 0) {
99 $objectbom->fetch(GETPOSTINT('fk_bom'));
100
101 if ($action != 'add') {
102 // We force calling parameters if we are not in the submit of creation of MO
103 $_POST['fk_product'] = $objectbom->fk_product;
104 $_POST['qty'] = $objectbom->qty;
105 $_POST['mrptype'] = $objectbom->bomtype;
106 $_POST['fk_warehouse'] = $objectbom->fk_warehouse;
107 $_POST['note_private'] = $objectbom->note_private;
108 }
109}
110
111// Security check - Protection if external user
112//if ($user->socid > 0) accessforbidden();
113//if ($user->socid > 0) $socid = $user->socid;
114$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
115$result = restrictedArea($user, 'mrp', $object->id, 'mrp_mo', '', 'fk_soc', 'rowid', $isdraft);
116
117// Permissions
118$permissionnote = $user->hasRight('mrp', 'write'); // Used by the include of actions_setnotes.inc.php
119$permissiondellink = $user->hasRight('mrp', 'write'); // Used by the include of actions_dellink.inc.php
120$permissiontoadd = $user->hasRight('mrp', 'write'); // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
121$permissiontodelete = $user->hasRight('mrp', 'delete') || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
122$upload_dir = $conf->mrp->multidir_output[isset($object->entity) ? $object->entity : 1];
123
124
125/*
126 * Actions
127 */
128
129$parameters = array();
130$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
131if ($reshook < 0) {
132 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
133}
134
135if (empty($reshook)) {
136 $error = 0;
137
138 $backurlforlist = dol_buildpath('/mrp/mo_list.php', 1);
139
140 $object->oldQty = (float) $object->qty;
141
142 if (empty($backtopage) || ($cancel && empty($id))) {
143 if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
144 if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
145 $backtopage = $backurlforlist;
146 } else {
147 $backtopage = DOL_URL_ROOT.'/mrp/mo_card.php?id='.($id > 0 ? $id : '__ID__');
148 }
149 }
150 }
151 if ($cancel && !empty($backtopageforcancel)) {
152 $backtopage = $backtopageforcancel;
153 }
154 $triggermodname = 'MO_MODIFY'; // Name of trigger action code to execute when we modify record
155
156 // Create MO with Children
157 if ($action == 'add' && empty($id) && !empty($TBomLineId) && $permissiontoadd) {
158 $noback = 1;
159 // Sub-BOM lines the user checked "Generate Child MO" for must not be flattened into their
160 // raw materials on the parent MO: keep a single consume line anchored on the sub-assembly
161 // product instead, so it can be found below to create the child MO.
162 $object->noFlattenBomLineIds = array_map('intval', $TBomLineId);
163 include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
164
165 $mo_parent = $object;
166
167 $moline = new MoLine($db);
168 $objectbomchildline = new BOMLine($db);
169
170 foreach ($TBomLineId as $id_bom_line) {
171 $object = new Mo($db); // modified by the actions_addupdatedelete.inc.php
172
173 $objectbomchildline->fetch((int) $id_bom_line);
174
175 // Find the consume line of the parent MO generated from this BOM line.
176 // The lookup must be scoped to the parent MO and use an exact match on origin_id/origin_type,
177 // otherwise the default 'origin_id LIKE %..%' filter can return an unrelated line (or none),
178 // which would let the child MO be created from the leftover parent POST data (duplicate MO).
179 $filter = '(fk_mo:=:'.((int) $mo_parent->id).') AND (origin_id:=:'.((int) $id_bom_line).") AND (origin_type:=:'bomline')";
180 $TMoLines = $moline->fetchAll('DESC', 'rowid', 1, 0, $filter);
181
182 if (empty($TMoLines)) {
183 continue;
184 }
185
186 foreach ($TMoLines as $tmpmoline) {
187 $_POST['fk_bom'] = $objectbomchildline->fk_bom_child;
188 $_POST['fk_parent_line'] = $tmpmoline->id;
189 $_POST['qty'] = $tmpmoline->qty;
190 $_POST['fk_product'] = $tmpmoline->fk_product;
191 }
192
193 include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
194
195 $res = $object->add_object_linked('mo', $mo_parent->id);
196 }
197
198 header("Location: ".dol_buildpath('/mrp/mo_card.php?id='.((int) $mo_parent->id), 1));
199 exit;
200 } elseif ($action == 'confirm_cancel' && $confirm == 'yes' && !empty($permissiontoadd)) {
201 $also_cancel_consumed_and_produced_lines = (GETPOST('alsoCancelConsumedAndProducedLines', 'alpha') ? 1 : 0);
202 $result = $object->cancel($user, 0, (bool) $also_cancel_consumed_and_produced_lines);
203 if ($result > 0) {
204 header("Location: " . dol_buildpath('/mrp/mo_card.php?id=' . $object->id, 1));
205 exit;
206 } else {
207 $action = '';
208 setEventMessages($object->error, $object->errors, 'errors');
209 }
210 } elseif ($action == 'confirm_delete' && $confirm == 'yes' && !empty($permissiontodelete)) {
211 $also_cancel_consumed_and_produced_lines = (GETPOST('alsoCancelConsumedAndProducedLines', 'alpha') ? 1 : 0);
212 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
213 $result = $object->delete($user, 0, (bool) $also_cancel_consumed_and_produced_lines);
214 if ($result > 0) {
215 header("Location: " . $backurlforlist);
216 exit;
217 } else {
218 $action = '';
219 setEventMessages($object->error, $object->errors, 'errors');
220 }
221 } elseif ($action == 'settags' && isModEnabled('category') && $permissiontoadd) {
222 $result = $object->setCategories(GETPOST('categories', 'array'));
223 if ($result < 0) {
224 setEventMessages($object->error, $object->errors, 'errors');
225 }
226 }
227
228 if ($action == 'confirm_delete' && !empty($permissiontodelete)) {
229 if (!($object->id > 0)) {
230 dol_print_error(null, 'Error, object must be fetched before being deleted');
231 exit;
232 }
233
234 $error = 0;
235 $deleteChilds = GETPOST('deletechilds', 'aZ');
236
237 // Start the database transaction
238 $db->begin();
239
240 if ($deleteChilds === 'on') {
241 $TMoChildren = $object->getAllMoChilds();
242
243 foreach ($TMoChildren as $id => $childObject) {
244 if ($childObject->delete($user) == -1) {
245 $error++;
246 if (!empty($childObject->errors)) {
247 setEventMessages(null, $childObject->errors, 'errors');
248 } else {
249 setEventMessages($childObject->error, null, 'errors');
250 }
251 }
252 }
253 }
254
255 if (!$error) {
256 $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty
257 $result = $object->delete($user);
258
259 if ($result > 0) {
260 setEventMessages("RecordDeleted", null, 'mesgs');
261
262 if ($deleteChilds === 'on') {
263 setEventMessages("MoChildsDeleted", null, 'mesgs');
264 }
265
266 if (empty($noback)) {
267 header("Location: " . $backurlforlist);
268 exit;
269 }
270 } else {
271 $error++;
272 if (!empty($object->errors)) {
273 setEventMessages(null, $object->errors, 'errors');
274 } else {
275 setEventMessages($object->error, null, 'errors');
276 }
277 }
278 }
279
280 // Commit or rollback the database transaction based on whether there was an error
281 if ($error) {
282 $db->rollback();
283 } else {
284 $db->commit();
285 }
286 }
287
288
289 // Allow editing qty while MO is still in draft status.
290 // IMPORTANT: this handler MUST run BEFORE actions_addupdatedelete.inc.php,
291 // which has a generic 'set<key>' matcher that would intercept 'setqty' and
292 // call $object->fetch() + update() without setting $object->oldQty, so
293 // Mo::updateProduction() would skip the line scaling (its condition is
294 // !empty($this->oldQty)).
295 if ($action == 'setqty' && $permissiontoadd && $object->status == Mo::STATUS_DRAFT) {
296 $newqty = GETPOSTFLOAT('qty');
297 if ($newqty > 0) {
298 $object->oldQty = (float) $object->qty;
299 $object->qty = $newqty;
300 $res = $object->update($user);
301 if ($res > 0) {
302 // Enforce invariant: the 'toproduce' line for the MO's main product
303 // must equal the MO qty. Mo::updateProduction() scales by ratio
304 // (newQty/oldQty) which can drift if the line state was already
305 // inconsistent (e.g. legacy data from before this patch). Realign
306 // the main product line, leaving sub-products and frozen lines
307 // untouched.
308 $object->fetchLines();
309 foreach ($object->lines as $line) {
310 if ($line->role === 'toproduce'
311 && (int) $line->fk_product === (int) $object->fk_product
312 && empty($line->qty_frozen)
313 && (float) $line->qty != (float) $object->qty) {
314 $line->qty = (float) $object->qty;
315 $resultline = $line->update($user);
316 if ($resultline < 0) {
317 setEventMessages($line->error, $line->errors, 'errors');
318 }
319 }
320 }
321 setEventMessages($langs->trans("RecordSaved"), null, 'mesgs');
322 } else {
323 setEventMessages($object->error, $object->errors, 'errors');
324 }
325 } else {
326 setEventMessages($langs->trans("ErrorFieldRequired", $langs->trans("Qty")), null, 'errors');
327 }
328 header("Location: ".$_SERVER["PHP_SELF"]."?id=".$object->id);
329 exit;
330 }
331
332 // Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen
333 include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
334
335 // Actions when linking object each other
336 include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php';
337
338 // Actions when printing a doc from card
339 include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
340
341 // Action to build doc
342 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
343
344 if ($action == 'set_thirdparty' && $permissiontoadd) {
345 $object->setValueFrom('fk_soc', GETPOSTINT('fk_soc'), '', null, 'date', '', $user, $triggermodname);
346 }
347 if ($action == 'classin' && $permissiontoadd) {
348 $object->setProject(GETPOSTINT('projectid'));
349 }
350
351 // Actions to send emails
352 $triggersendname = 'MO_SENTBYMAIL';
353 $autocopy = 'MAIN_MAIL_AUTOCOPY_MO_TO';
354 $trackid = 'mo'.$object->id;
355 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
356
357 // Action to move up and down lines of object
358 //include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; // Must be 'include', not 'include_once'
359
360 // Action close produced
361 if ($action == 'confirm_produced' && $confirm == 'yes' && $permissiontoadd) {
362 $result = $object->setStatut($object::STATUS_PRODUCED, 0, '', 'MRP_MO_PRODUCED');
363 if ($result >= 0) {
364 // Define output language
365 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
366 $outputlangs = $langs;
367 $newlang = '';
368 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
369 $newlang = GETPOST('lang_id', 'aZ09');
370 }
371 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
372 $newlang = $object->thirdparty->default_lang;
373 }
374 if (!empty($newlang)) {
375 $outputlangs = new Translate("", $conf);
376 $outputlangs->setDefaultLang($newlang);
377 }
378 $model = $object->model_pdf;
379 $ret = $object->fetch($id); // Reload to get new records
380
381 $object->generateDocument($model, $outputlangs, 0, 0, 0);
382 }
383 } else {
384 setEventMessages($object->error, $object->errors, 'errors');
385 }
386 }
387}
388
389
390
391
392/*
393 * View
394 */
395
396$form = new Form($db);
397$formfile = new FormFile($db);
398$formproject = new FormProjets($db);
399
400$title = $langs->trans('ManufacturingOrder')." - ".$langs->trans("Card");
401$help_url = 'EN:Module_Manufacturing_Orders|FR:Module_Ordres_de_Fabrication|DE:Modul_Fertigungsauftrag';
402
403llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-mrp page-card');
404
405
406// Part to create
407if ($action == 'create') {
408 $titlelist = null;
409 if (GETPOSTINT('fk_bom') > 0) {
410 $titlelist = $langs->trans("ToConsume");
411 if ($objectbom->bomtype == 1) {
412 $titlelist = $langs->trans("ToObtain");
413 }
414 }
415
416 print load_fiche_titre($langs->trans("NewObject", $langs->transnoentitiesnoconv("Mo")), '', 'mrp');
417
418 print '<form method="POST" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
419 print '<input type="hidden" name="token" value="'.newToken().'">';
420 print '<input type="hidden" name="action" value="add">';
421 if ($backtopage) {
422 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
423 }
424 if ($backtopageforcancel) {
425 print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
426 }
427
428 print dol_get_fiche_head(array(), '');
429
430 print '<table class="border centpercent tableforfieldcreate">'."\n";
431
432 // Common attributes
433 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php';
434
435 // Other attributes
436 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
437
438 if (isModEnabled('category')) {
439 // Categories
440 print '<tr><td>'.$langs->trans("Categories").'</td><td>';
441 print $form->selectCategories(Categorie::TYPE_MO, 'categories', $object);
442 print '</td></tr>';
443 }
444
445 print '</table>'."\n";
446
447 print dol_get_fiche_end();
448
450 <script>
451 $(document).ready(function () {
452 jQuery('#fk_bom').change(function() {
453 console.log('We change value of BOM with BOM of id '+jQuery('#fk_bom').val());
454 if (jQuery('#fk_bom').val() > 0)
455 {
456 // Redirect to page with fk_bom set
457 window.location.href = '<?php echo $_SERVER["PHP_SELF"] ?>?action=create&token=<?php echo newToken(); ?>&fk_bom='+jQuery('#fk_bom').val();
458 /*
459 $.getJSON('<?php echo DOL_URL_ROOT ?>/mrp/ajax/ajax_bom.php?action=getBoms&idbom='+jQuery('#fk_bom').val(), function(data) {
460 console.log(data);
461 if (typeof data.rowid != "undefined") {
462 console.log("New BOM loaded, we set values in form");
463 console.log(data);
464 $('#qty').val(data.qty);
465 $("#mrptype").val(data.bomtype); // We set bomtype into mrptype
466 $('#mrptype').trigger('change'); // Notify any JS components that the value changed
467 $("#fk_product").val(data.fk_product);
468 $('#fk_product').trigger('change'); // Notify any JS components that the value changed
469 $('#note_private').val(data.description);
470 $('#note_private').trigger('change'); // Notify any JS components that the value changed
471 $('#fk_warehouse').val(data.fk_warehouse);
472 $('#fk_warehouse').trigger('change'); // Notify any JS components that the value changed
473 if (typeof CKEDITOR != "undefined") {
474 if (typeof CKEDITOR.instances != "undefined") {
475 if (typeof CKEDITOR.instances.note_private != "undefined") {
476 console.log(CKEDITOR.instances.note_private);
477 CKEDITOR.instances.note_private.setData(data.description);
478 }
479 }
480 }
481 } else {
482 console.log("Failed to get BOM");
483 }
484 });*/
485 }
486 else if (jQuery('#fk_bom').val() < 0) {
487 // Redirect to page with all fields defined except fk_bom set
488 console.log(jQuery('#fk_product').val());
489 window.location.href = '<?php echo $_SERVER["PHP_SELF"] ?>?action=create&token=<?php echo newToken(); ?>&qty='+jQuery('#qty').val()+'&mrptype='+jQuery('#mrptype').val()+'&fk_product='+jQuery('#fk_product').val()+'&label='+jQuery('#label').val()+'&fk_project='+jQuery('#fk_project').val()+'&fk_warehouse='+jQuery('#fk_warehouse').val();
490 /*
491 $('#qty').val('');
492 $("#fk_product").val('');
493 $('#fk_product').trigger('change'); // Notify any JS components that the value changed
494 $('#note_private').val('');
495 $('#note_private').trigger('change'); // Notify any JS components that the value changed
496 $('#fk_warehouse').val('');
497 $('#fk_warehouse').trigger('change'); // Notify any JS components that the value changed
498 */
499 }
500 });
501
502 //jQuery('#fk_bom').trigger('change');
503 })
504 </script>
505 <?php
506
507 print $form->buttonsSaveCancel("Create");
508
509 if ($objectbom->id > 0) {
510 print load_fiche_titre((string) $titlelist);
511
512 print '<!-- list of product/services to consume -->'."\n";
513 print '<div class="div-table-responsive-no-min">';
514 print '<table class="noborder centpercent">';
515
516 $arrayOfMoLines = array();
517 foreach ($objectbom->lines as $key => $val) {
518 $moLine = new MoLine($db);
519 $moLine->id = $objectbom->lines[$key]->id;
520 $moLine->position = $objectbom->lines[$key]->position;
521 $moLine->fk_product = $objectbom->lines[$key]->fk_product;
522 $moLine->fk_unit = $objectbom->lines[$key]->fk_unit;
523 $moLine->qty = $objectbom->lines[$key]->qty;
524 $moLine->qty_frozen = $objectbom->lines[$key]->qty_frozen;
525 $moLine->disable_stock_change = $objectbom->lines[$key]->disable_stock_change;
526 $moLine->fk_bom_child = $objectbom->lines[$key]->fk_bom_child;
527
528 $arrayOfMoLines[] = $moLine;
529 }
530 $object->lines = $arrayOfMoLines;
531 $object->mrptype = $objectbom->bomtype;
532 $object->bom = $objectbom;
533
534 $object->printOriginLinesList('', array());
535
536 print '</table>';
537 print '</div>';
538 }
539
540 print '</form>';
541}
542
543// Part to edit record
544if (($id || $ref) && $action == 'edit') {
545 print load_fiche_titre($langs->trans("ManufacturingOrder"), '', 'mrp');
546
547 print '<form method="POST" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
548 print '<input type="hidden" name="token" value="'.newToken().'">';
549 print '<input type="hidden" name="action" value="update">';
550 print '<input type="hidden" name="id" value="'.$object->id.'">';
551 if ($backtopage) {
552 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
553 }
554 if ($backtopageforcancel) {
555 print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
556 }
557
558 print dol_get_fiche_head();
559
560 $object->fields['fk_bom']['disabled'] = 1;
561
562 print '<table class="border centpercent tableforfieldedit">'."\n";
563
564 // Common attributes
565 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_edit.tpl.php';
566
567 // Other attributes
568 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php';
569
570 if (isModEnabled('category')) {
571 // Categories
572 print '<tr><td>'.$langs->trans("Categories").'</td><td>';
573 print $form->selectCategories(Categorie::TYPE_MO, 'categories', $object);
574 print '</td></tr>';
575 }
576
577 print '</table>';
578
579 print dol_get_fiche_end();
580
581 print $form->buttonsSaveCancel();
582
583 print '</form>';
584}
585
586// Part to show record
587if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
588 $res = $object->fetch_thirdparty();
589
590 $head = moPrepareHead($object);
591
592 print dol_get_fiche_head($head, 'card', $langs->trans("ManufacturingOrder"), -1, $object->picto, 0, '', '', 0, '', 1);
593
594 $formconfirm = '';
595
596 // Confirmation to delete
597 if ($action == 'delete') {
598 $numberofmochilds = count($object->getAllMoChilds());
599
600 if ($numberofmochilds > 0) {
601 $label = $langs->trans("DeleteMoChild", '('.strval($numberofmochilds).')');
602 } else {
603 $label = $langs->trans("DeleteMoChild");
604 }
605
606 $formquestion = array(
607 array('type' => 'checkbox', 'name' => 'deletechilds', 'label' => $label, 'value' => 0),
608 array(
609 'label' => $langs->trans('MoCancelConsumedAndProducedLines'),
610 'name' => 'alsoCancelConsumedAndProducedLines',
611 'type' => 'checkbox',
612 'value' => !getDolGlobalString('MO_ALSO_CANCEL_CONSUMED_AND_PRODUCED_LINES_BY_DEFAULT') ? 0 : 1
613 )
614 );
615 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteMo'), $langs->trans('ConfirmDeleteMo'), 'confirm_delete', $formquestion, 0, 1);
616 }
617 // Confirmation to delete line
618 if ($action == 'deleteline') {
619 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1);
620 }
621
622 // Reload BOM to consume and produce
623 if ($action == 'reload') {
624 $object->createProduction($user, 0);
625 }
626
627 // Confirmation of validation
628 if ($action == 'validate') {
629 // We check that object has a temporary ref
630 $ref = substr($object->ref, 1, 4);
631 if ($ref == 'PROV') {
632 $object->fetch_product();
633 $numref = $object->getNextNumRef($object->product);
634 } else {
635 $numref = (string) $object->ref;
636 }
637
638 $text = $langs->trans('ConfirmValidateMo', $numref);
639 /*if (isModEnabled('notification'))
640 {
641 require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php';
642 $notify = new Notify($db);
643 $text .= '<br>';
644 $text .= $notify->confirmMessage('BOM_VALIDATE', $object->socid, $object);
645 }*/
646
647 $formquestion = array();
648 if (isModEnabled('mrp')) {
649 $langs->load("mrp");
650 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
651 $formproduct = new FormProduct($db);
652 $forcecombo = 0;
653 if ($conf->browser->name == 'ie') {
654 $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
655 }
656 $formquestion = array(
657 // 'text' => $langs->trans("ConfirmClone"),
658 // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
659 // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
660 );
661 }
662
663 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Validate'), $text, 'confirm_validate', $formquestion, 0, 1, 220);
664 }
665
666 // Confirmation to cancel
667 if ($action == 'cancel') {
668 $formquestion = array(
669 array(
670 'label' => $langs->trans('MoCancelConsumedAndProducedLines'),
671 'name' => 'alsoCancelConsumedAndProducedLines',
672 'type' => 'checkbox',
673 'value' => 0
674 ),
675 );
676 $formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans('CancelMo'), $langs->trans('ConfirmCancelMo'), 'confirm_cancel', $formquestion, 0, 1);
677 }
678
679 // Clone confirmation
680 if ($action == 'clone') {
681 // Create an array for form
682 $formquestion = array();
683 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneMo', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
684 }
685
686 // Call Hook formConfirm
687 $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
688 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
689 if (empty($reshook)) {
690 $formconfirm .= $hookmanager->resPrint;
691 } elseif ($reshook > 0) {
692 $formconfirm = $hookmanager->resPrint;
693 }
694
695 // Print form confirm
696 print $formconfirm;
697
698
699 // Object card
700 // ------------------------------------------------------------
701 $linkback = '<a href="'.dol_buildpath('/mrp/mo_list.php', 1).'?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
702
703 $morehtmlref = '<div class="refidno">';
704 /*
705 // Ref bis
706 $morehtmlref.=$form->editfieldkey("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->mrp->creer, 'string', '', 0, 1);
707 $morehtmlref.=$form->editfieldval("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->mrp->creer, 'string', '', null, null, '', 1);*/
708 // Thirdparty
709 if (is_object($object->thirdparty)) {
710 $morehtmlref .= $object->thirdparty->getNomUrl(1, 'customer');
711 if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
712 $morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherOrders").'</a>)';
713 }
714 }
715 // Project
716 if (isModEnabled('project')) {
717 $langs->load("projects");
718 if (is_object($object->thirdparty)) {
719 $morehtmlref .= '<br>';
720 }
721 if ($permissiontoadd) {
722 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
723 if ($action != 'classify') {
724 $morehtmlref .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => $object->id], true).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
725 }
726 $morehtmlref .= $form->form_project($_SERVER['PHP_SELF'].'?id='.$object->id, $object->socid, (string) $object->fk_project, ($action == 'classify' ? 'projectid' : 'none'), 0, 0, 0, 1, '', 'maxwidth300');
727 } else {
728 if (!empty($object->fk_project)) {
729 $proj = new Project($db);
730 $proj->fetch($object->fk_project);
731 $morehtmlref .= $proj->getNomUrl(1);
732 if ($proj->title) {
733 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
734 }
735 }
736 }
737 }
738 $morehtmlref .= '</div>';
739
740
741 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
742
743
744 print '<div class="fichecenter">';
745 print '<div class="fichehalfleft">';
746 print '<div class="underbanner clearboth"></div>';
747 print '<table class="border centpercent tableforfield">'."\n";
748
749 //Mo Parent
750 $mo_parent = $object->getMoParent();
751 if (is_object($mo_parent)) {
752 print '<tr class="field_fk_mo_parent">';
753 print '<td class="titlefield fieldname_fk_mo_parent">' . $langs->trans('ParentMo') . '</td>';
754 print '<td class="valuefield fieldname_fk_mo_parent">' .$mo_parent->getNomUrl(1).'</td>';
755 print '</tr>';
756 }
757
758 // Common attributes
759 $keyforbreak = 'fk_warehouse';
760 unset($object->fields['fk_project']);
761 unset($object->fields['fk_soc']);
762 // Allow inline edit of qty while MO is in draft status.
763 // Note: editfieldval() does not handle type 'real' (no <input> rendered, only
764 // Save/Cancel buttons appear). So we override the type to 'numeric' only when
765 // the user has actually clicked the edit pencil (action=editqty). This keeps
766 // the read-mode rendering (price() format) untouched.
767 if ($object->status == Mo::STATUS_DRAFT && $permissiontoadd && isset($object->fields['qty'])) {
768 $object->fields['qty']['alwayseditable'] = 1;
769 if ($action == 'editqty') {
770 $object->fields['qty']['type'] = 'numeric';
771 }
772 }
773
774 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php';
775
776 // Tags-Categories
777 if (isModEnabled('category')) {
778 print '<tr><td>';
779 print '<table class="nobordernopadding centpercent"><tr><td>';
780 print $langs->trans("Categories");
781 print '<td><td class="right">';
782 if ($permissiontoadd) {
783 print '<a class="editfielda" href="' . DOL_URL_ROOT . '/mrp/mo_card.php?id=' . $object->id . '&action=edittags&token=' . newToken() . '">' . img_edit() . '</a>';
784 } else {
785 print '&nbsp;';
786 }
787 print '</td></tr></table>';
788 print '</td>';
789 print '<td>';
790 if ($action == 'edittags') {
791 print '<form method="POST" action="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '">';
792 print '<input type="hidden" name="action" value="settags">';
793 print '<input type="hidden" name="token" value="' . newToken() . '">';
794 print $form->selectCategories(Categorie::TYPE_MO, 'categories', $object);
795 print '<input type="submit" class="button valignmiddle smallpaddingimp" value="' . $langs->trans("Modify") . '">';
796 print '</form>';
797 } else {
798 print $form->showCategories($object->id, Categorie::TYPE_MO, 1);
799 }
800 print "</td></tr>";
801 }
802
803 // Other attributes
804 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
805
806 print '</table>';
807 print '</div>';
808 print '</div>';
809
810 print '<div class="clearboth"></div>';
811
812 print dol_get_fiche_end();
813
814
815 /*
816 * Lines
817 */
818
819 if (!empty($object->table_element_line)) {
820 // Show object lines
821 //$result = $object->getLinesArray();
822 $object->fetchLines();
823
824 print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '' : '#line_'.GETPOSTINT('lineid')).'" method="POST">
825 <input type="hidden" name="token" value="' . newToken().'">
826 <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
827 <input type="hidden" name="mode" value="">
828 <input type="hidden" name="page_y" value="">
829 <input type="hidden" name="id" value="' . $object->id.'">
830 ';
831
832 /*if (!empty($conf->use_javascript_ajax) && $object->status == 0) {
833 include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
834 }*/
835
836 if (!empty($object->lines)) {
837 print '<div class="div-table-responsive-no-min">';
838 print '<table id="tablelines" class="noborder noshadow" width="100%">';
839
840 print '<tr class="liste_titre">';
841 print '<td class="liste_titre">'.$langs->trans("Summary").'</td>';
842 print '<td></td>';
843 print '</tr>';
844
845 print '<tr class="oddeven">';
846 print '<td>'.$langs->trans("ProductsToConsume").'</td>';
847 print '<td>';
848 if (!empty($object->lines)) {
849 $i = 0;
850 foreach ($object->lines as $line) {
851 if ($line->role == 'toconsume') {
852 if ($i) {
853 print ', ';
854 }
855 $tmpproduct = new Product($db);
856 $tmpproduct->fetch($line->fk_product);
857 print $tmpproduct->getNomUrl(1);
858 $i++;
859 }
860 }
861 }
862 print '</td>';
863 print '</tr>';
864
865 print '<tr class="oddeven">';
866 print '<td>'.$langs->trans("ProductsToProduce").'</td>';
867 print '<td>';
868 if (!empty($object->lines)) {
869 $i = 0;
870 foreach ($object->lines as $line) {
871 if ($line->role == 'toproduce') {
872 if ($i) {
873 print ', ';
874 }
875 $tmpproduct = new Product($db);
876 $tmpproduct->fetch($line->fk_product);
877 print $tmpproduct->getNomUrl(1);
878 $i++;
879 }
880 }
881 }
882 print '</td>';
883 print '</tr>';
884
885 print '</table>';
886 print '</div>';
887 }
888
889 print "</form>\n";
890 }
891
892
893 // Buttons for actions
894
895 if ($action != 'presend' && $action != 'editline') {
896 print '<div class="tabsAction">'."\n";
897 $parameters = array();
898 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
899 if ($reshook < 0) {
900 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
901 }
902
903 if (empty($reshook)) {
904 // Send
905 //if (empty($user->socid)) {
906 // print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=presend&mode=init#formmailbeforetitle">' . $langs->trans('SendMail') . '</a>'."\n";
907 //}
908
909 // Back to draft
910 if ($object->status == $object::STATUS_VALIDATED) {
911 if ($permissiontoadd) {
912 // TODO Add test that production has not started
913 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=confirm_setdraft&confirm=yes&token='.newToken().'">'.$langs->trans("SetToDraft").'</a>';
914 }
915 }
916
917 // Modify
918 if ($object->status == $object::STATUS_DRAFT) {
919 if ($permissiontoadd) {
920 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&token='.newToken().'">'.$langs->trans("Modify").'</a>'."\n";
921 } else {
922 print '<a class="butActionRefused classfortooltip" href="#" title="'.dolPrintHTMLForAttribute($langs->trans("NotEnoughPermissions")).'">'.$langs->trans('Modify').'</a>'."\n";
923 }
924 }
925
926 // Reload BOM
927 if ($object->status == $object::STATUS_DRAFT && $object->fk_bom > 0) {
928 if ($permissiontoadd) {
929 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=reload&token='.newToken().'" title="'.dolPrintHTMLForAttribute($langs->trans("ReInitializeHelp")).'">'.$langs->trans("ReInitialize").'</a>';
930 } else {
931 print '<a class="butActionRefused classfortooltip" href="#" title="'.dolPrintHTMLForAttribute($langs->trans("ReInitializeHelp").'<br>'.$langs->trans("NotEnoughPermissions")).'">'.$langs->trans('ReInitialize').'</a>'."\n";
932 }
933 }
934
935 // Validate
936 if ($object->status == $object::STATUS_DRAFT) {
937 if ($permissiontoadd) {
938 if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) {
939 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=validate&token='.newToken().'">'.$langs->trans("Validate").'</a>';
940 } else {
941 $langs->load("errors");
942 print '<a class="butActionRefused" href="" title="'.$langs->trans("ErrorAddAtLeastOneLineFirst").'">'.$langs->trans("Validate").'</a>';
943 }
944 }
945 }
946
947 // Clone
948 if ($permissiontoadd) {
949 print dolGetButtonAction($langs->trans("ToClone"), $langs->trans("ToClone"), 'clone', $_SERVER['PHP_SELF'].'?id='.$object->id.(!empty($object->socid) ? '&socid='.$object->socid : "").'&action=clone&token='.newToken().'&object=mo', 'clone', $permissiontoadd, array('attr' => array('class' => 'reposition')))."\n";
950 }
951
952 // Cancel - Reopen
953 if ($permissiontoadd) {
954 if ($object->status == $object::STATUS_VALIDATED || $object->status == $object::STATUS_INPROGRESS) {
955 $arrayproduced = $object->fetchLinesLinked('produced', 0);
956 $nbProduced = 0;
957 foreach ($arrayproduced as $lineproduced) {
958 $nbProduced += $lineproduced['qty'];
959 }
960 if ($nbProduced > 0) { // If production has started, we can close it
961 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=confirm_produced&confirm=yes&token='.newToken().'">'.$langs->trans("Close").'</a>'."\n";
962 } else {
963 print '<a class="butActionRefused" href="#" title="'.$langs->trans("GoOnTabProductionToProduceFirst", $langs->transnoentitiesnoconv("Production")).'">'.$langs->trans("Close").'</a>'."\n";
964 }
965
966 print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=cancel&token='.newToken().'">'.$langs->trans("Cancel").'</a>'."\n";
967 }
968
969 if ($object->status == $object::STATUS_PRODUCED || $object->status == $object::STATUS_CANCELED) {
970 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=confirm_reopen&confirm=yes&token='.newToken().'">'.$langs->trans("ReOpen").'</a>'."\n";
971 }
972 }
973
974 // Delete
975 print dolGetButtonAction($langs->trans("Delete"), $langs->trans("Delete"), 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), 'delete', $permissiontodelete, array('attr' => array('class' => 'reposition')))."\n";
976 }
977 print '</div>'."\n";
978 }
979
980
981 // Select mail models is same action as presend
982 if (GETPOST('modelselected')) {
983 $action = 'presend';
984 }
985
986 if ($action != 'presend') {
987 print '<div class="fichecenter"><div class="fichehalfleft">';
988 print '<a name="builddoc"></a>'; // ancre
989
990 // Documents
991 $objref = dol_sanitizeFileName($object->ref);
992 $relativepath = $objref.'/'.$objref.'.pdf';
993 $filedir = $conf->mrp->dir_output.'/'.$objref;
994 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
995 $genallowed = $user->hasRight('mrp', 'read'); // If you can read, you can build the PDF to read content
996 $delallowed = $user->hasRight("mrp", "creer"); // If you can create/edit, you can remove a file on card
997 print $formfile->showdocuments('mrp:mo', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $mysoc->default_lang, '', $object);
998
999 // Show links to link elements
1000 $tmparray = $form->showLinkToObjectBlock($object, array(), array('mo'), 1);
1001 $linktoelem = $tmparray['linktoelem'];
1002 $htmltoenteralink = $tmparray['htmltoenteralink'];
1003 print $htmltoenteralink;
1004
1005 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem, array());
1006
1007
1008 print '</div><div class="fichehalfright">';
1009
1010 $MAXEVENT = 10;
1011
1012 $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/mrp/mo_agenda.php?id='.$object->id);
1013
1014 // List of actions on element
1015 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
1016 $formactions = new FormActions($db);
1017 $somethingshown = $formactions->showactions($object, $object->element, $socid, 1, '', $MAXEVENT, '', $morehtmlcenter);
1018
1019 print '</div></div>';
1020 }
1021
1022 //Select mail models is same action as presend
1023 if (GETPOST('modelselected')) {
1024 $action = 'presend';
1025 }
1026
1027 // Presend form
1028 $modelmail = 'mo';
1029 $defaulttopic = 'InformationMessage';
1030 $diroutput = $conf->mrp->dir_output;
1031 $trackid = 'mo'.$object->id;
1032
1033 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
1034}
1035
1036// End of page
1037llxFooter();
1038$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
mrpCollapseBomManagement()
Manage collapse bom display.
Definition bom.lib.php:164
Class for BOM.
Definition bom.class.php:42
Class for BOMLine.
Class to manage building of HTML components.
Class to offer components to list and upload files.
Class to manage generation of HTML components Only common components must be here.
Class with static methods for building HTML components related to products Only components common to ...
Class to manage building of HTML components.
Class for Mo.
Definition mo.class.php:35
Class MoLine.
Class to manage products or services.
Class to manage projects.
Class to manage translations.
global $mysoc
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $conf
The main.inc.php has been included so the following variable are now defined:
dolBuildUrl($url, $params=[], $addtoken=false, $anchor='')
Return path of url.
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0, $allowdash=0)
Clean a string to use it as a file name.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
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.
GETPOSTFLOAT($paramname, $rounding='', $option=2)
Return the value of a $_GET or $_POST supervariable, converted into float.
GETPOSTINT($paramname, $method=0, $nodefault=0)
Return the value of a $_GET or $_POST supervariable, converted into integer.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
dol_clone($srcobject, $native=2)
Create a clone of instance of object (new instance with same value for each properties) With native =...
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
isModEnabled($module)
Is Dolibarr module enabled.
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
dolGetButtonTitle($label, $helpText='', $iconClass='fa fa-file', $url='', $id='', $status=1, $params=array())
Function dolGetButtonTitle : this kind of buttons are used in title in list.
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.
moPrepareHead($object)
Prepare array of tabs for Mo.
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.