dolibarr 24.0.0-beta
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-2025 MDW <mdeweerd@users.noreply.github.com>
5 * Copyright (C) 2024-2026 Frédéric France <frederic.france@free.fr>
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 include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
160
161 $mo_parent = $object;
162
163 $moline = new MoLine($db);
164 $objectbomchildline = new BOMLine($db);
165
166 foreach ($TBomLineId as $id_bom_line) {
167 $object = new Mo($db); // modified by the actions_addupdatedelete.inc.php
168
169 $objectbomchildline->fetch($id_bom_line);
170
171 $TMoLines = $moline->fetchAll('DESC', 'rowid', 1, 0, array('origin_id' => $id_bom_line));
172
173 foreach ($TMoLines as $tmpmoline) {
174 $_POST['fk_bom'] = $objectbomchildline->fk_bom_child;
175 $_POST['fk_parent_line'] = $tmpmoline->id;
176 $_POST['qty'] = $tmpmoline->qty;
177 $_POST['fk_product'] = $tmpmoline->fk_product;
178 }
179
180 include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
181
182 $res = $object->add_object_linked('mo', $mo_parent->id);
183 }
184
185 header("Location: ".dol_buildpath('/mrp/mo_card.php?id='.((int) $mo_parent->id), 1));
186 exit;
187 } elseif ($action == 'confirm_cancel' && $confirm == 'yes' && !empty($permissiontoadd)) {
188 $also_cancel_consumed_and_produced_lines = (GETPOST('alsoCancelConsumedAndProducedLines', 'alpha') ? 1 : 0);
189 $result = $object->cancel($user, 0, (bool) $also_cancel_consumed_and_produced_lines);
190 if ($result > 0) {
191 header("Location: " . dol_buildpath('/mrp/mo_card.php?id=' . $object->id, 1));
192 exit;
193 } else {
194 $action = '';
195 setEventMessages($object->error, $object->errors, 'errors');
196 }
197 } elseif ($action == 'confirm_delete' && $confirm == 'yes' && !empty($permissiontodelete)) {
198 $also_cancel_consumed_and_produced_lines = (GETPOST('alsoCancelConsumedAndProducedLines', 'alpha') ? 1 : 0);
199 $result = $object->delete($user, 0, (bool) $also_cancel_consumed_and_produced_lines);
200 if ($result > 0) {
201 header("Location: " . $backurlforlist);
202 exit;
203 } else {
204 $action = '';
205 setEventMessages($object->error, $object->errors, 'errors');
206 }
207 } elseif ($action == 'settags' && isModEnabled('category') && $permissiontoadd) {
208 $result = $object->setCategories(GETPOST('categories', 'array'));
209 if ($result < 0) {
210 setEventMessages($object->error, $object->errors, 'errors');
211 }
212 }
213
214 if ($action == 'confirm_delete' && !empty($permissiontodelete)) {
215 if (!($object->id > 0)) {
216 dol_print_error(null, 'Error, object must be fetched before being deleted');
217 exit;
218 }
219
220 $error = 0;
221 $deleteChilds = GETPOST('deletechilds', 'aZ');
222
223 // Start the database transaction
224 $db->begin();
225
226 if ($deleteChilds === 'on') {
227 $TMoChildren = $object->getAllMoChilds();
228
229 foreach ($TMoChildren as $id => $childObject) {
230 if ($childObject->delete($user) == -1) {
231 $error++;
232 if (!empty($childObject->errors)) {
233 setEventMessages(null, $childObject->errors, 'errors');
234 } else {
235 setEventMessages($childObject->error, null, 'errors');
236 }
237 }
238 }
239 }
240
241 if (!$error) {
242 $result = $object->delete($user);
243
244 if ($result > 0) {
245 setEventMessages("RecordDeleted", null, 'mesgs');
246
247 if ($deleteChilds === 'on') {
248 setEventMessages("MoChildsDeleted", null, 'mesgs');
249 }
250
251 if (empty($noback)) {
252 header("Location: " . $backurlforlist);
253 exit;
254 }
255 } else {
256 $error++;
257 if (!empty($object->errors)) {
258 setEventMessages(null, $object->errors, 'errors');
259 } else {
260 setEventMessages($object->error, null, 'errors');
261 }
262 }
263 }
264
265 // Commit or rollback the database transaction based on whether there was an error
266 if ($error) {
267 $db->rollback();
268 } else {
269 $db->commit();
270 }
271 }
272
273
274 // Allow editing qty while MO is still in draft status.
275 // IMPORTANT: this handler MUST run BEFORE actions_addupdatedelete.inc.php,
276 // which has a generic 'set<key>' matcher that would intercept 'setqty' and
277 // call $object->fetch() + update() without setting $object->oldQty, so
278 // Mo::updateProduction() would skip the line scaling (its condition is
279 // !empty($this->oldQty)).
280 if ($action == 'setqty' && $permissiontoadd && $object->status == Mo::STATUS_DRAFT) {
281 $newqty = GETPOSTFLOAT('qty');
282 if ($newqty > 0) {
283 $object->oldQty = (float) $object->qty;
284 $object->qty = $newqty;
285 $res = $object->update($user);
286 if ($res > 0) {
287 // Enforce invariant: the 'toproduce' line for the MO's main product
288 // must equal the MO qty. Mo::updateProduction() scales by ratio
289 // (newQty/oldQty) which can drift if the line state was already
290 // inconsistent (e.g. legacy data from before this patch). Realign
291 // the main product line, leaving sub-products and frozen lines
292 // untouched.
293 $object->fetchLines();
294 foreach ($object->lines as $line) {
295 if ($line->role === 'toproduce'
296 && (int) $line->fk_product === (int) $object->fk_product
297 && empty($line->qty_frozen)
298 && (float) $line->qty != (float) $object->qty) {
299 $line->qty = (float) $object->qty;
300 $line->update($user);
301 }
302 }
303 setEventMessages($langs->trans("RecordSaved"), null, 'mesgs');
304 } else {
305 setEventMessages($object->error, $object->errors, 'errors');
306 }
307 } else {
308 setEventMessages($langs->trans("ErrorFieldRequired", $langs->trans("Qty")), null, 'errors');
309 }
310 header("Location: ".$_SERVER["PHP_SELF"]."?id=".$object->id);
311 exit;
312 }
313
314 // Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen
315 include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
316
317 // Actions when linking object each other
318 include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php';
319
320 // Actions when printing a doc from card
321 include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
322
323 // Action to build doc
324 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
325
326 if ($action == 'set_thirdparty' && $permissiontoadd) {
327 $object->setValueFrom('fk_soc', GETPOSTINT('fk_soc'), '', null, 'date', '', $user, $triggermodname);
328 }
329 if ($action == 'classin' && $permissiontoadd) {
330 $object->setProject(GETPOSTINT('projectid'));
331 }
332
333 // Actions to send emails
334 $triggersendname = 'MO_SENTBYMAIL';
335 $autocopy = 'MAIN_MAIL_AUTOCOPY_MO_TO';
336 $trackid = 'mo'.$object->id;
337 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
338
339 // Action to move up and down lines of object
340 //include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; // Must be 'include', not 'include_once'
341
342 // Action close produced
343 if ($action == 'confirm_produced' && $confirm == 'yes' && $permissiontoadd) {
344 $result = $object->setStatut($object::STATUS_PRODUCED, 0, '', 'MRP_MO_PRODUCED');
345 if ($result >= 0) {
346 // Define output language
347 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
348 $outputlangs = $langs;
349 $newlang = '';
350 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
351 $newlang = GETPOST('lang_id', 'aZ09');
352 }
353 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
354 $newlang = $object->thirdparty->default_lang;
355 }
356 if (!empty($newlang)) {
357 $outputlangs = new Translate("", $conf);
358 $outputlangs->setDefaultLang($newlang);
359 }
360 $model = $object->model_pdf;
361 $ret = $object->fetch($id); // Reload to get new records
362
363 $object->generateDocument($model, $outputlangs, 0, 0, 0);
364 }
365 } else {
366 setEventMessages($object->error, $object->errors, 'errors');
367 }
368 }
369}
370
371
372
373
374/*
375 * View
376 */
377
378$form = new Form($db);
379$formfile = new FormFile($db);
380$formproject = new FormProjets($db);
381
382$title = $langs->trans('ManufacturingOrder')." - ".$langs->trans("Card");
383$help_url = 'EN:Module_Manufacturing_Orders|FR:Module_Ordres_de_Fabrication|DE:Modul_Fertigungsauftrag';
384
385llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-mrp page-card');
386
387
388// Part to create
389if ($action == 'create') {
390 $titlelist = null;
391 if (GETPOSTINT('fk_bom') > 0) {
392 $titlelist = $langs->trans("ToConsume");
393 if ($objectbom->bomtype == 1) {
394 $titlelist = $langs->trans("ToObtain");
395 }
396 }
397
398 print load_fiche_titre($langs->trans("NewObject", $langs->transnoentitiesnoconv("Mo")), '', 'mrp');
399
400 print '<form method="POST" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
401 print '<input type="hidden" name="token" value="'.newToken().'">';
402 print '<input type="hidden" name="action" value="add">';
403 if ($backtopage) {
404 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
405 }
406 if ($backtopageforcancel) {
407 print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
408 }
409
410 print dol_get_fiche_head(array(), '');
411
412 print '<table class="border centpercent tableforfieldcreate">'."\n";
413
414 // Common attributes
415 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php';
416
417 // Other attributes
418 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
419
420 if (isModEnabled('category')) {
421 // Categories
422 print '<tr><td>'.$langs->trans("Categories").'</td><td>';
423 print $form->selectCategories(Categorie::TYPE_MO, 'categories', $object);
424 print '</td></tr>';
425 }
426
427 print '</table>'."\n";
428
429 print dol_get_fiche_end();
430
432 <script>
433 $(document).ready(function () {
434 jQuery('#fk_bom').change(function() {
435 console.log('We change value of BOM with BOM of id '+jQuery('#fk_bom').val());
436 if (jQuery('#fk_bom').val() > 0)
437 {
438 // Redirect to page with fk_bom set
439 window.location.href = '<?php echo $_SERVER["PHP_SELF"] ?>?action=create&token=<?php echo newToken(); ?>&fk_bom='+jQuery('#fk_bom').val();
440 /*
441 $.getJSON('<?php echo DOL_URL_ROOT ?>/mrp/ajax/ajax_bom.php?action=getBoms&idbom='+jQuery('#fk_bom').val(), function(data) {
442 console.log(data);
443 if (typeof data.rowid != "undefined") {
444 console.log("New BOM loaded, we set values in form");
445 console.log(data);
446 $('#qty').val(data.qty);
447 $("#mrptype").val(data.bomtype); // We set bomtype into mrptype
448 $('#mrptype').trigger('change'); // Notify any JS components that the value changed
449 $("#fk_product").val(data.fk_product);
450 $('#fk_product').trigger('change'); // Notify any JS components that the value changed
451 $('#note_private').val(data.description);
452 $('#note_private').trigger('change'); // Notify any JS components that the value changed
453 $('#fk_warehouse').val(data.fk_warehouse);
454 $('#fk_warehouse').trigger('change'); // Notify any JS components that the value changed
455 if (typeof CKEDITOR != "undefined") {
456 if (typeof CKEDITOR.instances != "undefined") {
457 if (typeof CKEDITOR.instances.note_private != "undefined") {
458 console.log(CKEDITOR.instances.note_private);
459 CKEDITOR.instances.note_private.setData(data.description);
460 }
461 }
462 }
463 } else {
464 console.log("Failed to get BOM");
465 }
466 });*/
467 }
468 else if (jQuery('#fk_bom').val() < 0) {
469 // Redirect to page with all fields defined except fk_bom set
470 console.log(jQuery('#fk_product').val());
471 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();
472 /*
473 $('#qty').val('');
474 $("#fk_product").val('');
475 $('#fk_product').trigger('change'); // Notify any JS components that the value changed
476 $('#note_private').val('');
477 $('#note_private').trigger('change'); // Notify any JS components that the value changed
478 $('#fk_warehouse').val('');
479 $('#fk_warehouse').trigger('change'); // Notify any JS components that the value changed
480 */
481 }
482 });
483
484 //jQuery('#fk_bom').trigger('change');
485 })
486 </script>
487 <?php
488
489 print $form->buttonsSaveCancel("Create");
490
491 if ($objectbom->id > 0) {
492 print load_fiche_titre((string) $titlelist);
493
494 print '<!-- list of product/services to consume -->'."\n";
495 print '<div class="div-table-responsive-no-min">';
496 print '<table class="noborder centpercent">';
497
498 $arrayOfMoLines = array();
499 foreach ($objectbom->lines as $key => $val) {
500 $moLine = new MoLine($db);
501 $moLine->id = $objectbom->lines[$key]->id;
502 $moLine->position = $objectbom->lines[$key]->position;
503 $moLine->fk_product = $objectbom->lines[$key]->fk_product;
504 $moLine->fk_unit = $objectbom->lines[$key]->fk_unit;
505 $moLine->qty = $objectbom->lines[$key]->qty;
506 $moLine->qty_frozen = $objectbom->lines[$key]->qty_frozen;
507 $moLine->disable_stock_change = $objectbom->lines[$key]->disable_stock_change;
508 $moLine->fk_bom_child = $objectbom->lines[$key]->fk_bom_child;
509
510 $arrayOfMoLines[] = $moLine;
511 }
512 $object->lines = $arrayOfMoLines;
513 $object->mrptype = $objectbom->bomtype;
514 $object->bom = $objectbom;
515
516 $object->printOriginLinesList('', array());
517
518 print '</table>';
519 print '</div>';
520 }
521
522 print '</form>';
523}
524
525// Part to edit record
526if (($id || $ref) && $action == 'edit') {
527 print load_fiche_titre($langs->trans("ManufacturingOrder"), '', 'mrp');
528
529 print '<form method="POST" action="'.dolBuildUrl($_SERVER["PHP_SELF"]).'">';
530 print '<input type="hidden" name="token" value="'.newToken().'">';
531 print '<input type="hidden" name="action" value="update">';
532 print '<input type="hidden" name="id" value="'.$object->id.'">';
533 if ($backtopage) {
534 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
535 }
536 if ($backtopageforcancel) {
537 print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
538 }
539
540 print dol_get_fiche_head();
541
542 $object->fields['fk_bom']['disabled'] = 1;
543
544 print '<table class="border centpercent tableforfieldedit">'."\n";
545
546 // Common attributes
547 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_edit.tpl.php';
548
549 // Other attributes
550 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php';
551
552 if (isModEnabled('category')) {
553 // Categories
554 print '<tr><td>'.$langs->trans("Categories").'</td><td>';
555 print $form->selectCategories(Categorie::TYPE_MO, 'categories', $object);
556 print '</td></tr>';
557 }
558
559 print '</table>';
560
561 print dol_get_fiche_end();
562
563 print $form->buttonsSaveCancel();
564
565 print '</form>';
566}
567
568// Part to show record
569if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
570 $res = $object->fetch_thirdparty();
571
572 $head = moPrepareHead($object);
573
574 print dol_get_fiche_head($head, 'card', $langs->trans("ManufacturingOrder"), -1, $object->picto);
575
576 $formconfirm = '';
577
578 // Confirmation to delete
579 if ($action == 'delete') {
580 $numberofmochilds = count($object->getAllMoChilds());
581
582 if ($numberofmochilds > 0) {
583 $label = $langs->trans("DeleteMoChild", '('.strval($numberofmochilds).')');
584 } else {
585 $label = $langs->trans("DeleteMoChild");
586 }
587
588 $formquestion = array(
589 array('type' => 'checkbox', 'name' => 'deletechilds', 'label' => $label, 'value' => 0),
590 array(
591 'label' => $langs->trans('MoCancelConsumedAndProducedLines'),
592 'name' => 'alsoCancelConsumedAndProducedLines',
593 'type' => 'checkbox',
594 'value' => !getDolGlobalString('MO_ALSO_CANCEL_CONSUMED_AND_PRODUCED_LINES_BY_DEFAULT') ? 0 : 1
595 )
596 );
597 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteMo'), $langs->trans('ConfirmDeleteMo'), 'confirm_delete', $formquestion, 0, 1);
598 }
599 // Confirmation to delete line
600 if ($action == 'deleteline') {
601 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1);
602 }
603
604 // Reload BOM to consume and produce
605 if ($action == 'reload') {
606 $object->createProduction($user, 0);
607 }
608
609 // Confirmation of validation
610 if ($action == 'validate') {
611 // We check that object has a temporary ref
612 $ref = substr($object->ref, 1, 4);
613 if ($ref == 'PROV') {
614 $object->fetch_product();
615 $numref = $object->getNextNumRef($object->product);
616 } else {
617 $numref = (string) $object->ref;
618 }
619
620 $text = $langs->trans('ConfirmValidateMo', $numref);
621 /*if (isModEnabled('notification'))
622 {
623 require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php';
624 $notify = new Notify($db);
625 $text .= '<br>';
626 $text .= $notify->confirmMessage('BOM_VALIDATE', $object->socid, $object);
627 }*/
628
629 $formquestion = array();
630 if (isModEnabled('mrp')) {
631 $langs->load("mrp");
632 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
633 $formproduct = new FormProduct($db);
634 $forcecombo = 0;
635 if ($conf->browser->name == 'ie') {
636 $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
637 }
638 $formquestion = array(
639 // 'text' => $langs->trans("ConfirmClone"),
640 // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
641 // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
642 );
643 }
644
645 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Validate'), $text, 'confirm_validate', $formquestion, 0, 1, 220);
646 }
647
648 // Confirmation to cancel
649 if ($action == 'cancel') {
650 $formquestion = array(
651 array(
652 'label' => $langs->trans('MoCancelConsumedAndProducedLines'),
653 'name' => 'alsoCancelConsumedAndProducedLines',
654 'type' => 'checkbox',
655 'value' => 0
656 ),
657 );
658 $formconfirm = $form->formconfirm(dolBuildUrl($_SERVER["PHP_SELF"], ['id' => $object->id]), $langs->trans('CancelMo'), $langs->trans('ConfirmCancelMo'), 'confirm_cancel', $formquestion, 0, 1);
659 }
660
661 // Clone confirmation
662 if ($action == 'clone') {
663 // Create an array for form
664 $formquestion = array();
665 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneMo', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
666 }
667
668 // Call Hook formConfirm
669 $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
670 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
671 if (empty($reshook)) {
672 $formconfirm .= $hookmanager->resPrint;
673 } elseif ($reshook > 0) {
674 $formconfirm = $hookmanager->resPrint;
675 }
676
677 // Print form confirm
678 print $formconfirm;
679
680
681 // Object card
682 // ------------------------------------------------------------
683 $linkback = '<a href="'.dol_buildpath('/mrp/mo_list.php', 1).'?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
684
685 $morehtmlref = '<div class="refidno">';
686 /*
687 // Ref bis
688 $morehtmlref.=$form->editfieldkey("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->mrp->creer, 'string', '', 0, 1);
689 $morehtmlref.=$form->editfieldval("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->mrp->creer, 'string', '', null, null, '', 1);*/
690 // Thirdparty
691 if (is_object($object->thirdparty)) {
692 $morehtmlref .= $object->thirdparty->getNomUrl(1, 'customer');
693 if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
694 $morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'&search_societe='.urlencode($object->thirdparty->name).'">'.$langs->trans("OtherOrders").'</a>)';
695 }
696 }
697 // Project
698 if (isModEnabled('project')) {
699 $langs->load("projects");
700 if (is_object($object->thirdparty)) {
701 $morehtmlref .= '<br>';
702 }
703 if ($permissiontoadd) {
704 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
705 if ($action != 'classify') {
706 $morehtmlref .= '<a class="editfielda" href="'.dolBuildUrl($_SERVER['PHP_SELF'], ['action' => 'classify', 'id' => $object->id], true).'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
707 }
708 $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');
709 } else {
710 if (!empty($object->fk_project)) {
711 $proj = new Project($db);
712 $proj->fetch($object->fk_project);
713 $morehtmlref .= $proj->getNomUrl(1);
714 if ($proj->title) {
715 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
716 }
717 }
718 }
719 }
720 $morehtmlref .= '</div>';
721
722
723 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
724
725
726 print '<div class="fichecenter">';
727 print '<div class="fichehalfleft">';
728 print '<div class="underbanner clearboth"></div>';
729 print '<table class="border centpercent tableforfield">'."\n";
730
731 //Mo Parent
732 $mo_parent = $object->getMoParent();
733 if (is_object($mo_parent)) {
734 print '<tr class="field_fk_mo_parent">';
735 print '<td class="titlefield fieldname_fk_mo_parent">' . $langs->trans('ParentMo') . '</td>';
736 print '<td class="valuefield fieldname_fk_mo_parent">' .$mo_parent->getNomUrl(1).'</td>';
737 print '</tr>';
738 }
739
740 // Common attributes
741 $keyforbreak = 'fk_warehouse';
742 unset($object->fields['fk_project']);
743 unset($object->fields['fk_soc']);
744 // Allow inline edit of qty while MO is in draft status.
745 // Note: editfieldval() does not handle type 'real' (no <input> rendered, only
746 // Save/Cancel buttons appear). So we override the type to 'numeric' only when
747 // the user has actually clicked the edit pencil (action=editqty). This keeps
748 // the read-mode rendering (price() format) untouched.
749 if ($object->status == Mo::STATUS_DRAFT && $permissiontoadd && isset($object->fields['qty'])) {
750 $object->fields['qty']['alwayseditable'] = 1;
751 if ($action == 'editqty') {
752 $object->fields['qty']['type'] = 'numeric';
753 }
754 }
755
756 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php';
757
758 // Tags-Categories
759 if (isModEnabled('category')) {
760 print '<tr><td>';
761 print '<table class="nobordernopadding centpercent"><tr><td>';
762 print $langs->trans("Categories");
763 print '<td><td class="right">';
764 if ($permissiontoadd) {
765 print '<a class="editfielda" href="' . DOL_URL_ROOT . '/mrp/mo_card.php?id=' . $object->id . '&action=edittags&token=' . newToken() . '">' . img_edit() . '</a>';
766 } else {
767 print '&nbsp;';
768 }
769 print '</td></tr></table>';
770 print '</td>';
771 print '<td>';
772 if ($action == 'edittags') {
773 print '<form method="POST" action="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '">';
774 print '<input type="hidden" name="action" value="settags">';
775 print '<input type="hidden" name="token" value="' . newToken() . '">';
776 print $form->selectCategories(Categorie::TYPE_MO, 'categories', $object);
777 print '<input type="submit" class="button valignmiddle smallpaddingimp" value="' . $langs->trans("Modify") . '">';
778 print '</form>';
779 } else {
780 print $form->showCategories($object->id, Categorie::TYPE_MO, 1);
781 }
782 print "</td></tr>";
783 }
784
785 // Other attributes
786 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
787
788 print '</table>';
789 print '</div>';
790 print '</div>';
791
792 print '<div class="clearboth"></div>';
793
794 print dol_get_fiche_end();
795
796
797 /*
798 * Lines
799 */
800
801 if (!empty($object->table_element_line)) {
802 // Show object lines
803 //$result = $object->getLinesArray();
804 $object->fetchLines();
805
806 print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '' : '#line_'.GETPOSTINT('lineid')).'" method="POST">
807 <input type="hidden" name="token" value="' . newToken().'">
808 <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
809 <input type="hidden" name="mode" value="">
810 <input type="hidden" name="page_y" value="">
811 <input type="hidden" name="id" value="' . $object->id.'">
812 ';
813
814 /*if (!empty($conf->use_javascript_ajax) && $object->status == 0) {
815 include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
816 }*/
817
818 if (!empty($object->lines)) {
819 print '<div class="div-table-responsive-no-min">';
820 print '<table id="tablelines" class="noborder noshadow" width="100%">';
821
822 print '<tr class="liste_titre">';
823 print '<td class="liste_titre">'.$langs->trans("Summary").'</td>';
824 print '<td></td>';
825 print '</tr>';
826
827 print '<tr class="oddeven">';
828 print '<td>'.$langs->trans("ProductsToConsume").'</td>';
829 print '<td>';
830 if (!empty($object->lines)) {
831 $i = 0;
832 foreach ($object->lines as $line) {
833 if ($line->role == 'toconsume') {
834 if ($i) {
835 print ', ';
836 }
837 $tmpproduct = new Product($db);
838 $tmpproduct->fetch($line->fk_product);
839 print $tmpproduct->getNomUrl(1);
840 $i++;
841 }
842 }
843 }
844 print '</td>';
845 print '</tr>';
846
847 print '<tr class="oddeven">';
848 print '<td>'.$langs->trans("ProductsToProduce").'</td>';
849 print '<td>';
850 if (!empty($object->lines)) {
851 $i = 0;
852 foreach ($object->lines as $line) {
853 if ($line->role == 'toproduce') {
854 if ($i) {
855 print ', ';
856 }
857 $tmpproduct = new Product($db);
858 $tmpproduct->fetch($line->fk_product);
859 print $tmpproduct->getNomUrl(1);
860 $i++;
861 }
862 }
863 }
864 print '</td>';
865 print '</tr>';
866
867 print '</table>';
868 print '</div>';
869 }
870
871 print "</form>\n";
872 }
873
874
875 // Buttons for actions
876
877 if ($action != 'presend' && $action != 'editline') {
878 print '<div class="tabsAction">'."\n";
879 $parameters = array();
880 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
881 if ($reshook < 0) {
882 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
883 }
884
885 if (empty($reshook)) {
886 // Send
887 //if (empty($user->socid)) {
888 // print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=presend&mode=init#formmailbeforetitle">' . $langs->trans('SendMail') . '</a>'."\n";
889 //}
890
891 // Back to draft
892 if ($object->status == $object::STATUS_VALIDATED) {
893 if ($permissiontoadd) {
894 // TODO Add test that production has not started
895 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=confirm_setdraft&confirm=yes&token='.newToken().'">'.$langs->trans("SetToDraft").'</a>';
896 }
897 }
898
899 // Modify
900 if ($object->status == $object::STATUS_DRAFT) {
901 if ($permissiontoadd) {
902 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&token='.newToken().'">'.$langs->trans("Modify").'</a>'."\n";
903 } else {
904 print '<a class="butActionRefused classfortooltip" href="#" title="'.dolPrintHTMLForAttribute($langs->trans("NotEnoughPermissions")).'">'.$langs->trans('Modify').'</a>'."\n";
905 }
906 }
907
908 // Reload BOM
909 if ($object->status == $object::STATUS_DRAFT && $object->fk_bom > 0) {
910 if ($permissiontoadd) {
911 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=reload&token='.newToken().'" title="'.dolPrintHTMLForAttribute($langs->trans("ReInitializeHelp")).'">'.$langs->trans("ReInitialize").'</a>';
912 } else {
913 print '<a class="butActionRefused classfortooltip" href="#" title="'.dolPrintHTMLForAttribute($langs->trans("ReInitializeHelp").'<br>'.$langs->trans("NotEnoughPermissions")).'">'.$langs->trans('ReInitialize').'</a>'."\n";
914 }
915 }
916
917 // Validate
918 if ($object->status == $object::STATUS_DRAFT) {
919 if ($permissiontoadd) {
920 if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) {
921 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=validate&token='.newToken().'">'.$langs->trans("Validate").'</a>';
922 } else {
923 $langs->load("errors");
924 print '<a class="butActionRefused" href="" title="'.$langs->trans("ErrorAddAtLeastOneLineFirst").'">'.$langs->trans("Validate").'</a>';
925 }
926 }
927 }
928
929 // Clone
930 if ($permissiontoadd) {
931 print dolGetButtonAction($langs->trans("ToClone"), '', 'clone', $_SERVER['PHP_SELF'].'?id='.$object->id.(!empty($object->socid) ? '&socid='.$object->socid : "").'&action=clone&token='.newToken().'&object=mo', 'clone', $permissiontoadd);
932 }
933
934 // Cancel - Reopen
935 if ($permissiontoadd) {
936 if ($object->status == $object::STATUS_VALIDATED || $object->status == $object::STATUS_INPROGRESS) {
937 $arrayproduced = $object->fetchLinesLinked('produced', 0);
938 $nbProduced = 0;
939 foreach ($arrayproduced as $lineproduced) {
940 $nbProduced += $lineproduced['qty'];
941 }
942 if ($nbProduced > 0) { // If production has started, we can close it
943 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=confirm_produced&confirm=yes&token='.newToken().'">'.$langs->trans("Close").'</a>'."\n";
944 } else {
945 print '<a class="butActionRefused" href="#" title="'.$langs->trans("GoOnTabProductionToProduceFirst", $langs->transnoentitiesnoconv("Production")).'">'.$langs->trans("Close").'</a>'."\n";
946 }
947
948 print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=cancel&token='.newToken().'">'.$langs->trans("Cancel").'</a>'."\n";
949 }
950
951 if ($object->status == $object::STATUS_PRODUCED || $object->status == $object::STATUS_CANCELED) {
952 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=confirm_reopen&confirm=yes&token='.newToken().'">'.$langs->trans("ReOpen").'</a>'."\n";
953 }
954 }
955
956 // Delete
957 print dolGetButtonAction($langs->trans("Delete"), '', 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), 'delete', $permissiontodelete);
958 }
959 print '</div>'."\n";
960 }
961
962
963 // Select mail models is same action as presend
964 if (GETPOST('modelselected')) {
965 $action = 'presend';
966 }
967
968 if ($action != 'presend') {
969 print '<div class="fichecenter"><div class="fichehalfleft">';
970 print '<a name="builddoc"></a>'; // ancre
971
972 // Documents
973 $objref = dol_sanitizeFileName($object->ref);
974 $relativepath = $objref.'/'.$objref.'.pdf';
975 $filedir = $conf->mrp->dir_output.'/'.$objref;
976 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
977 $genallowed = $user->hasRight('mrp', 'read'); // If you can read, you can build the PDF to read content
978 $delallowed = $user->hasRight("mrp", "creer"); // If you can create/edit, you can remove a file on card
979 print $formfile->showdocuments('mrp:mo', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $mysoc->default_lang, '', $object);
980
981 // Show links to link elements
982 $tmparray = $form->showLinkToObjectBlock($object, array(), array('mo'), 1);
983 $linktoelem = $tmparray['linktoelem'];
984 $htmltoenteralink = $tmparray['htmltoenteralink'];
985 print $htmltoenteralink;
986
987 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem, array());
988
989
990 print '</div><div class="fichehalfright">';
991
992 $MAXEVENT = 10;
993
994 $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/mrp/mo_agenda.php?id='.$object->id);
995
996 // List of actions on element
997 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
998 $formactions = new FormActions($db);
999 $somethingshown = $formactions->showactions($object, $object->element, $socid, 1, '', $MAXEVENT, '', $morehtmlcenter);
1000
1001 print '</div></div>';
1002 }
1003
1004 //Select mail models is same action as presend
1005 if (GETPOST('modelselected')) {
1006 $action = 'presend';
1007 }
1008
1009 // Presend form
1010 $modelmail = 'mo';
1011 $defaulttopic = 'InformationMessage';
1012 $diroutput = $conf->mrp->dir_output;
1013 $trackid = 'mo'.$object->id;
1014
1015 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
1016}
1017
1018// End of page
1019llxFooter();
1020$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:
if(!isModEnabled('ai')||!getDolGlobalString('AI_ASSISTANT_ENABLED')) global $db
API class for accounts.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0, $attop=0)
Set event messages in dol_events session object.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=0, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2, $allowothertags=array())
Show picto whatever it's its name (generic function)
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.
dolBuildUrl($url, $params=[], $addtoken=false, $anchor='')
Return path of url.
dol_get_fiche_end($notab=0)
Return tab footer of a card.
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.
GETPOSTFLOAT($paramname, $rounding='', $option=2)
Return the value of a $_GET or $_POST supervariable, converted into float.
dolPrintHTMLForAttribute($s, $escapeonlyhtmltags=0, $allowothertags=array())
Return a string ready to be output into an HTML attribute (alt, title, data-html, ....
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
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.
print $langs trans("Show") . '< td style="' . $timeColor . '" align="center"> s</td > badge status0 badge status4 badge status3 Error badge status8< td align="center">< span class="badge ' . $badge . '"></span ></td >< td align="center">< a href="#" class="button button-small" onclick="openLogModal(this)" data-req="' . dol_escape_htmltag($reqSafe) . '" data-res="' . dol_escape_htmltag($resSafe) . '" data-err="' . dol_escape_htmltag($errSafe) . '">< span class="fa fa-search-plus"></span ></a ></td ></tr >< tr >< td colspan="' . $colspan . '" class="opacitymedium"></td ></tr ></table ></div ></form > logModal none logModal none s a JSON string
buildzip.php
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, $mode=0)
Check permissions of a user to show a page and an object.