dolibarr 22.0.5
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 MDW <mdeweerd@users.noreply.github.com>
5 * Copyright (C) 2024-2025 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';
30
31require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php';
32require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php';
33require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php';
34require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php';
35require_once DOL_DOCUMENT_ROOT.'/mrp/class/mo.class.php';
36require_once DOL_DOCUMENT_ROOT.'/mrp/lib/mrp_mo.lib.php';
37require_once DOL_DOCUMENT_ROOT.'/bom/class/bom.class.php';
38require_once DOL_DOCUMENT_ROOT.'/bom/lib/bom.lib.php';
39
40if (isModEnabled('workstation')) {
41 require_once DOL_DOCUMENT_ROOT.'/workstation/class/workstation.class.php';
42}
43
44
54// Load translation files required by the page
55$langs->loadLangs(array('mrp', 'other'));
56
57
58// Get parameters
59$id = GETPOSTINT('id');
60$ref = GETPOST('ref', 'alpha');
61$action = GETPOST('action', 'aZ09');
62$confirm = GETPOST('confirm', 'alpha');
63$cancel = GETPOST('cancel');
64$contextpage = GETPOST('contextpage', 'aZ') ? GETPOST('contextpage', 'aZ') : 'mocard'; // To manage different context of search
65$backtopage = GETPOST('backtopage', 'alpha');
66$backtopageforcancel = GETPOST('backtopageforcancel', 'alpha');
67$TBomLineId = GETPOST('bomlineid', 'array:int');
68$lineid = GETPOSTINT('lineid');
69$socid = GETPOSTINT("socid");
70
71// Initialize a technical objects
72$object = new Mo($db);
73$objectbom = new BOM($db);
74
75$extrafields = new ExtraFields($db);
76$diroutputmassaction = $conf->mrp->dir_output.'/temp/massgeneration/'.$user->id;
77$hookmanager->initHooks(array('mocard', 'globalcard')); // Note that conf->hooks_modules contains array
78
79// Fetch optionals attributes and labels
80$extrafields->fetch_name_optionals_label($object->table_element);
81
82$search_array_options = $extrafields->getOptionalsFromPost($object->table_element, '', 'search_');
83
84// Initialize array of search criteria
85$search_all = GETPOST("search_all", 'alpha');
86$search = array();
87foreach ($object->fields as $key => $val) {
88 if (GETPOST('search_'.$key, 'alpha')) {
89 $search[$key] = GETPOST('search_'.$key, 'alpha');
90 }
91}
92
93if (empty($action) && empty($id) && empty($ref)) {
94 $action = 'view';
95}
96
97// Load object
98include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be 'include', not 'include_once'.
99
100if (GETPOSTINT('fk_bom') > 0) {
101 $objectbom->fetch(GETPOSTINT('fk_bom'));
102
103 if ($action != 'add') {
104 // We force calling parameters if we are not in the submit of creation of MO
105 $_POST['fk_product'] = $objectbom->fk_product;
106 $_POST['qty'] = $objectbom->qty;
107 $_POST['mrptype'] = $objectbom->bomtype;
108 $_POST['fk_warehouse'] = $objectbom->fk_warehouse;
109 $_POST['note_private'] = $objectbom->note_private;
110 }
111}
112
113// Security check - Protection if external user
114//if ($user->socid > 0) accessforbidden();
115//if ($user->socid > 0) $socid = $user->socid;
116$isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
117$result = restrictedArea($user, 'mrp', $object->id, 'mrp_mo', '', 'fk_soc', 'rowid', $isdraft);
118
119// Permissions
120$permissionnote = $user->hasRight('mrp', 'write'); // Used by the include of actions_setnotes.inc.php
121$permissiondellink = $user->hasRight('mrp', 'write'); // Used by the include of actions_dellink.inc.php
122$permissiontoadd = $user->hasRight('mrp', 'write'); // Used by the include of actions_addupdatedelete.inc.php and actions_lineupdown.inc.php
123$permissiontodelete = $user->hasRight('mrp', 'delete') || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
124$upload_dir = $conf->mrp->multidir_output[isset($object->entity) ? $object->entity : 1];
125
126
127/*
128 * Actions
129 */
130
131$parameters = array();
132$reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks
133if ($reshook < 0) {
134 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
135}
136
137if (empty($reshook)) {
138 $error = 0;
139
140 $backurlforlist = dol_buildpath('/mrp/mo_list.php', 1);
141
142 $object->oldQty = $object->qty;
143
144 if (empty($backtopage) || ($cancel && empty($id))) {
145 if (empty($backtopage) || ($cancel && strpos($backtopage, '__ID__'))) {
146 if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) {
147 $backtopage = $backurlforlist;
148 } else {
149 $backtopage = DOL_URL_ROOT.'/mrp/mo_card.php?id='.($id > 0 ? $id : '__ID__');
150 }
151 }
152 }
153 if ($cancel && !empty($backtopageforcancel)) {
154 $backtopage = $backtopageforcancel;
155 }
156 $triggermodname = 'MO_MODIFY'; // Name of trigger action code to execute when we modify record
157
158 // Create MO with Children
159 if ($action == 'add' && empty($id) && !empty($TBomLineId) && $permissiontoadd) {
160 $noback = 1;
161 include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
162
163 $mo_parent = $object;
164
165 $moline = new MoLine($db);
166 $objectbomchildline = new BOMLine($db);
167
168 foreach ($TBomLineId as $id_bom_line) {
169 $object = new Mo($db); // modified by the actions_addupdatedelete.inc.php
170
171 $objectbomchildline->fetch((int) $id_bom_line);
172
173 // Find the consume line of the parent MO generated from this BOM line.
174 // The lookup must be scoped to the parent MO and use an exact match on origin_id/origin_type,
175 // otherwise the default 'origin_id LIKE %..%' filter can return an unrelated line (or none),
176 // which would let the child MO be created from the leftover parent POST data (duplicate MO).
177 $filter = '(fk_mo:=:'.((int) $mo_parent->id).') AND (origin_id:=:'.((int) $id_bom_line).") AND (origin_type:=:'bomline')";
178 $TMoLines = $moline->fetchAll('DESC', 'rowid', 1, 0, $filter);
179
180 if (empty($TMoLines)) {
181 continue;
182 }
183
184 foreach ($TMoLines as $tmpmoline) {
185 $_POST['fk_bom'] = $objectbomchildline->fk_bom_child;
186 $_POST['fk_parent_line'] = $tmpmoline->id;
187 $_POST['qty'] = $tmpmoline->qty;
188 $_POST['fk_product'] = $tmpmoline->fk_product;
189 }
190
191 include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
192
193 $res = $object->add_object_linked('mo', $mo_parent->id);
194 }
195
196 header("Location: ".dol_buildpath('/mrp/mo_card.php?id='.((int) $mo_parent->id), 1));
197 exit;
198 } elseif ($action == 'confirm_cancel' && $confirm == 'yes' && !empty($permissiontoadd)) {
199 $also_cancel_consumed_and_produced_lines = (GETPOST('alsoCancelConsumedAndProducedLines', 'alpha') ? 1 : 0);
200 $result = $object->cancel($user, 0, (bool) $also_cancel_consumed_and_produced_lines);
201 if ($result > 0) {
202 header("Location: " . dol_buildpath('/mrp/mo_card.php?id=' . $object->id, 1));
203 exit;
204 } else {
205 $action = '';
206 setEventMessages($object->error, $object->errors, 'errors');
207 }
208 } elseif ($action == 'confirm_delete' && $confirm == 'yes' && !empty($permissiontodelete)) {
209 $also_cancel_consumed_and_produced_lines = (GETPOST('alsoCancelConsumedAndProducedLines', 'alpha') ? 1 : 0);
210 $result = $object->delete($user, 0, (bool) $also_cancel_consumed_and_produced_lines);
211 if ($result > 0) {
212 header("Location: " . $backurlforlist);
213 exit;
214 } else {
215 $action = '';
216 setEventMessages($object->error, $object->errors, 'errors');
217 }
218 }
219
220 if ($action == 'confirm_delete' && !empty($permissiontodelete)) {
221 if (!($object->id > 0)) {
222 dol_print_error(null, 'Error, object must be fetched before being deleted');
223 exit;
224 }
225
226 $error = 0;
227 $deleteChilds = GETPOST('deletechilds', 'aZ');
228
229 // Start the database transaction
230 $db->begin();
231
232 if ($deleteChilds === 'on') {
233 $TMoChildren = $object->getAllMoChilds();
234
235 foreach ($TMoChildren as $id => $childObject) {
236 if ($childObject->delete($user) == -1) {
237 $error++;
238 if (!empty($childObject->errors)) {
239 setEventMessages(null, $childObject->errors, 'errors');
240 } else {
241 setEventMessages($childObject->error, null, 'errors');
242 }
243 }
244 }
245 }
246
247 if (!$error) {
248 $result = $object->delete($user);
249
250 if ($result > 0) {
251 setEventMessages("RecordDeleted", null, 'mesgs');
252
253 if ($deleteChilds === 'on') {
254 setEventMessages("MoChildsDeleted", null, 'mesgs');
255 }
256
257 if (empty($noback)) {
258 header("Location: " . $backurlforlist);
259 exit;
260 }
261 } else {
262 $error++;
263 if (!empty($object->errors)) {
264 setEventMessages(null, $object->errors, 'errors');
265 } else {
266 setEventMessages($object->error, null, 'errors');
267 }
268 }
269 }
270
271 // Commit or rollback the database transaction based on whether there was an error
272 if ($error) {
273 $db->rollback();
274 } else {
275 $db->commit();
276 }
277 }
278
279
280 // Actions cancel, add, update, update_extras, confirm_validate, confirm_delete, confirm_deleteline, confirm_clone, confirm_close, confirm_setdraft, confirm_reopen
281 include DOL_DOCUMENT_ROOT.'/core/actions_addupdatedelete.inc.php';
282
283 // Actions when linking object each other
284 include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php';
285
286 // Actions when printing a doc from card
287 include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
288
289 // Action to build doc
290 include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
291
292 if ($action == 'set_thirdparty' && $permissiontoadd) {
293 $object->setValueFrom('fk_soc', GETPOSTINT('fk_soc'), '', null, 'date', '', $user, $triggermodname);
294 }
295 if ($action == 'classin' && $permissiontoadd) {
296 $object->setProject(GETPOSTINT('projectid'));
297 }
298
299 // Actions to send emails
300 $triggersendname = 'MO_SENTBYMAIL';
301 $autocopy = 'MAIN_MAIL_AUTOCOPY_MO_TO';
302 $trackid = 'mo'.$object->id;
303 include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
304
305 // Action to move up and down lines of object
306 //include DOL_DOCUMENT_ROOT.'/core/actions_lineupdown.inc.php'; // Must be 'include', not 'include_once'
307
308 // Action close produced
309 if ($action == 'confirm_produced' && $confirm == 'yes' && $permissiontoadd) {
310 $result = $object->setStatut($object::STATUS_PRODUCED, 0, '', 'MRP_MO_PRODUCED');
311 if ($result >= 0) {
312 // Define output language
313 if (!getDolGlobalString('MAIN_DISABLE_PDF_AUTOUPDATE')) {
314 $outputlangs = $langs;
315 $newlang = '';
316 if (getDolGlobalInt('MAIN_MULTILANGS') /* && empty($newlang) */ && GETPOST('lang_id', 'aZ09')) {
317 $newlang = GETPOST('lang_id', 'aZ09');
318 }
319 if (getDolGlobalInt('MAIN_MULTILANGS') && empty($newlang)) {
320 $newlang = $object->thirdparty->default_lang;
321 }
322 if (!empty($newlang)) {
323 $outputlangs = new Translate("", $conf);
324 $outputlangs->setDefaultLang($newlang);
325 }
326 $model = $object->model_pdf;
327 $ret = $object->fetch($id); // Reload to get new records
328
329 $object->generateDocument($model, $outputlangs, 0, 0, 0);
330 }
331 } else {
332 setEventMessages($object->error, $object->errors, 'errors');
333 }
334 }
335}
336
337
338
339
340/*
341 * View
342 */
343
344$form = new Form($db);
345$formfile = new FormFile($db);
346$formproject = new FormProjets($db);
347
348$title = $langs->trans('ManufacturingOrder')." - ".$langs->trans("Card");
349$help_url = 'EN:Module_Manufacturing_Orders|FR:Module_Ordres_de_Fabrication|DE:Modul_Fertigungsauftrag';
350
351llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-mrp page-card');
352
353
354// Part to create
355if ($action == 'create') {
356 $titlelist = null;
357 if (GETPOSTINT('fk_bom') > 0) {
358 $titlelist = $langs->trans("ToConsume");
359 if ($objectbom->bomtype == 1) {
360 $titlelist = $langs->trans("ToObtain");
361 }
362 }
363
364 print load_fiche_titre($langs->trans("NewObject", $langs->transnoentitiesnoconv("Mo")), '', 'mrp');
365
366 print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
367 print '<input type="hidden" name="token" value="'.newToken().'">';
368 print '<input type="hidden" name="action" value="add">';
369 if ($backtopage) {
370 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
371 }
372 if ($backtopageforcancel) {
373 print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
374 }
375
376 print dol_get_fiche_head(array(), '');
377
378 print '<table class="border centpercent tableforfieldcreate">'."\n";
379
380 // Common attributes
381 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_add.tpl.php';
382
383 // Other attributes
384 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_add.tpl.php';
385
386 print '</table>'."\n";
387
388 print dol_get_fiche_end();
389
391 <script>
392 $(document).ready(function () {
393 jQuery('#fk_bom').change(function() {
394 console.log('We change value of BOM with BOM of id '+jQuery('#fk_bom').val());
395 if (jQuery('#fk_bom').val() > 0)
396 {
397 // Redirect to page with fk_bom set
398 window.location.href = '<?php echo $_SERVER["PHP_SELF"] ?>?action=create&token=<?php echo newToken(); ?>&fk_bom='+jQuery('#fk_bom').val();
399 /*
400 $.getJSON('<?php echo DOL_URL_ROOT ?>/mrp/ajax/ajax_bom.php?action=getBoms&idbom='+jQuery('#fk_bom').val(), function(data) {
401 console.log(data);
402 if (typeof data.rowid != "undefined") {
403 console.log("New BOM loaded, we set values in form");
404 console.log(data);
405 $('#qty').val(data.qty);
406 $("#mrptype").val(data.bomtype); // We set bomtype into mrptype
407 $('#mrptype').trigger('change'); // Notify any JS components that the value changed
408 $("#fk_product").val(data.fk_product);
409 $('#fk_product').trigger('change'); // Notify any JS components that the value changed
410 $('#note_private').val(data.description);
411 $('#note_private').trigger('change'); // Notify any JS components that the value changed
412 $('#fk_warehouse').val(data.fk_warehouse);
413 $('#fk_warehouse').trigger('change'); // Notify any JS components that the value changed
414 if (typeof CKEDITOR != "undefined") {
415 if (typeof CKEDITOR.instances != "undefined") {
416 if (typeof CKEDITOR.instances.note_private != "undefined") {
417 console.log(CKEDITOR.instances.note_private);
418 CKEDITOR.instances.note_private.setData(data.description);
419 }
420 }
421 }
422 } else {
423 console.log("Failed to get BOM");
424 }
425 });*/
426 }
427 else if (jQuery('#fk_bom').val() < 0) {
428 // Redirect to page with all fields defined except fk_bom set
429 console.log(jQuery('#fk_product').val());
430 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();
431 /*
432 $('#qty').val('');
433 $("#fk_product").val('');
434 $('#fk_product').trigger('change'); // Notify any JS components that the value changed
435 $('#note_private').val('');
436 $('#note_private').trigger('change'); // Notify any JS components that the value changed
437 $('#fk_warehouse').val('');
438 $('#fk_warehouse').trigger('change'); // Notify any JS components that the value changed
439 */
440 }
441 });
442
443 //jQuery('#fk_bom').trigger('change');
444 })
445 </script>
446 <?php
447
448 print $form->buttonsSaveCancel("Create");
449
450 if ($objectbom->id > 0) {
451 print load_fiche_titre((string) $titlelist);
452
453 print '<!-- list of product/services to consume -->'."\n";
454 print '<div class="div-table-responsive-no-min">';
455 print '<table class="noborder centpercent">';
456
457 $arrayOfMoLines = array();
458 foreach ($objectbom->lines as $key => $val) {
459 $moLine = new MoLine($db);
460 $moLine->id = $objectbom->lines[$key]->id;
461 $moLine->position = $objectbom->lines[$key]->position;
462 $moLine->fk_product = $objectbom->lines[$key]->fk_product;
463 $moLine->fk_unit = $objectbom->lines[$key]->fk_unit;
464 $moLine->qty = $objectbom->lines[$key]->qty;
465 $moLine->qty_frozen = $objectbom->lines[$key]->qty_frozen;
466 $moLine->disable_stock_change = $objectbom->lines[$key]->disable_stock_change;
467 $moLine->fk_bom_child = $objectbom->lines[$key]->fk_bom_child;
468
469 $arrayOfMoLines[] = $moLine;
470 }
471 $object->lines = $arrayOfMoLines;
472 $object->mrptype = $objectbom->bomtype;
473 $object->bom = $objectbom;
474
475 $object->printOriginLinesList('', array());
476
477 print '</table>';
478 print '</div>';
479 }
480
481 print '</form>';
482}
483
484// Part to edit record
485if (($id || $ref) && $action == 'edit') {
486 print load_fiche_titre($langs->trans("ManufacturingOrder"), '', 'mrp');
487
488 print '<form method="POST" action="'.$_SERVER["PHP_SELF"].'">';
489 print '<input type="hidden" name="token" value="'.newToken().'">';
490 print '<input type="hidden" name="action" value="update">';
491 print '<input type="hidden" name="id" value="'.$object->id.'">';
492 if ($backtopage) {
493 print '<input type="hidden" name="backtopage" value="'.$backtopage.'">';
494 }
495 if ($backtopageforcancel) {
496 print '<input type="hidden" name="backtopageforcancel" value="'.$backtopageforcancel.'">';
497 }
498
499 print dol_get_fiche_head();
500
501 $object->fields['fk_bom']['disabled'] = 1;
502
503 print '<table class="border centpercent tableforfieldedit">'."\n";
504
505 // Common attributes
506 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_edit.tpl.php';
507
508 // Other attributes
509 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_edit.tpl.php';
510
511 print '</table>';
512
513 print dol_get_fiche_end();
514
515 print $form->buttonsSaveCancel();
516
517 print '</form>';
518}
519
520// Part to show record
521if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'create'))) {
522 $res = $object->fetch_thirdparty();
523
524 $head = moPrepareHead($object);
525
526 print dol_get_fiche_head($head, 'card', $langs->trans("ManufacturingOrder"), -1, $object->picto);
527
528 $formconfirm = '';
529
530 // Confirmation to delete
531 if ($action == 'delete') {
532 $numberofmochilds = count($object->getAllMoChilds());
533
534 if ($numberofmochilds > 0) {
535 $label = $langs->trans("DeleteMoChild", '('.strval($numberofmochilds).')');
536 } else {
537 $label = $langs->trans("DeleteMoChild");
538 }
539
540 $formquestion = array(
541 array('type' => 'checkbox', 'name' => 'deletechilds', 'label' => $label, 'value' => 0),
542 array(
543 'label' => $langs->trans('MoCancelConsumedAndProducedLines'),
544 'name' => 'alsoCancelConsumedAndProducedLines',
545 'type' => 'checkbox',
546 'value' => !getDolGlobalString('MO_ALSO_CANCEL_CONSUMED_AND_PRODUCED_LINES_BY_DEFAULT') ? 0 : 1
547 )
548 );
549 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('DeleteMo'), $langs->trans('ConfirmDeleteMo'), 'confirm_delete', $formquestion, 0, 1);
550 }
551 // Confirmation to delete line
552 if ($action == 'deleteline') {
553 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id.'&lineid='.$lineid, $langs->trans('DeleteLine'), $langs->trans('ConfirmDeleteLine'), 'confirm_deleteline', '', 0, 1);
554 }
555
556 // Confirmation of validation
557 if ($action == 'validate') {
558 // We check that object has a temporary ref
559 $ref = substr($object->ref, 1, 4);
560 if ($ref == 'PROV') {
561 $object->fetch_product();
562 $numref = $object->getNextNumRef($object->product);
563 } else {
564 $numref = $object->ref;
565 }
566
567 $text = $langs->trans('ConfirmValidateMo', $numref);
568 /*if (isModEnabled('notification'))
569 {
570 require_once DOL_DOCUMENT_ROOT . '/core/class/notify.class.php';
571 $notify = new Notify($db);
572 $text .= '<br>';
573 $text .= $notify->confirmMessage('BOM_VALIDATE', $object->socid, $object);
574 }*/
575
576 $formquestion = array();
577 if (isModEnabled('mrp')) {
578 $langs->load("mrp");
579 require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php';
580 $formproduct = new FormProduct($db);
581 $forcecombo = 0;
582 if ($conf->browser->name == 'ie') {
583 $forcecombo = 1; // There is a bug in IE10 that make combo inside popup crazy
584 }
585 $formquestion = array(
586 // 'text' => $langs->trans("ConfirmClone"),
587 // array('type' => 'checkbox', 'name' => 'clone_content', 'label' => $langs->trans("CloneMainAttributes"), 'value' => 1),
588 // array('type' => 'checkbox', 'name' => 'update_prices', 'label' => $langs->trans("PuttingPricesUpToDate"), 'value' => 1),
589 );
590 }
591
592 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('Validate'), $text, 'confirm_validate', $formquestion, 0, 1, 220);
593 }
594
595 // Confirmation to cancel
596 if ($action == 'cancel') {
597 $formquestion = array(
598 array(
599 'label' => $langs->trans('MoCancelConsumedAndProducedLines'),
600 'name' => 'alsoCancelConsumedAndProducedLines',
601 'type' => 'checkbox',
602 'value' => 0
603 ),
604 );
605 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?id=' . $object->id, $langs->trans('CancelMo'), $langs->trans('ConfirmCancelMo'), 'confirm_cancel', $formquestion, 0, 1);
606 }
607
608 // Clone confirmation
609 if ($action == 'clone') {
610 // Create an array for form
611 $formquestion = array();
612 $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"].'?id='.$object->id, $langs->trans('ToClone'), $langs->trans('ConfirmCloneMo', $object->ref), 'confirm_clone', $formquestion, 'yes', 1);
613 }
614
615 // Call Hook formConfirm
616 $parameters = array('formConfirm' => $formconfirm, 'lineid' => $lineid);
617 $reshook = $hookmanager->executeHooks('formConfirm', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
618 if (empty($reshook)) {
619 $formconfirm .= $hookmanager->resPrint;
620 } elseif ($reshook > 0) {
621 $formconfirm = $hookmanager->resPrint;
622 }
623
624 // Print form confirm
625 print $formconfirm;
626
627
628 // Object card
629 // ------------------------------------------------------------
630 $linkback = '<a href="'.dol_buildpath('/mrp/mo_list.php', 1).'?restore_lastsearch_values=1'.(!empty($socid) ? '&socid='.$socid : '').'">'.$langs->trans("BackToList").'</a>';
631
632 $morehtmlref = '<div class="refidno">';
633 /*
634 // Ref bis
635 $morehtmlref.=$form->editfieldkey("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->mrp->creer, 'string', '', 0, 1);
636 $morehtmlref.=$form->editfieldval("RefBis", 'ref_client', $object->ref_client, $object, $user->rights->mrp->creer, 'string', '', null, null, '', 1);*/
637 // Thirdparty
638 if (is_object($object->thirdparty)) {
639 $morehtmlref .= $object->thirdparty->getNomUrl(1, 'customer');
640 if (!getDolGlobalString('MAIN_DISABLE_OTHER_LINK') && $object->thirdparty->id > 0) {
641 $morehtmlref .= ' (<a href="'.DOL_URL_ROOT.'/commande/list.php?socid='.$object->thirdparty->id.'">'.$langs->trans("OtherOrders").'</a>)';
642 }
643 }
644 // Project
645 if (isModEnabled('project')) {
646 $langs->load("projects");
647 if (is_object($object->thirdparty)) {
648 $morehtmlref .= '<br>';
649 }
650 if ($permissiontoadd) {
651 $morehtmlref .= img_picto($langs->trans("Project"), 'project', 'class="pictofixedwidth"');
652 if ($action != 'classify') {
653 $morehtmlref .= '<a class="editfielda" href="'.$_SERVER['PHP_SELF'].'?action=classify&token='.newToken().'&id='.$object->id.'">'.img_edit($langs->transnoentitiesnoconv('SetProject')).'</a> ';
654 }
655 $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');
656 } else {
657 if (!empty($object->fk_project)) {
658 $proj = new Project($db);
659 $proj->fetch($object->fk_project);
660 $morehtmlref .= $proj->getNomUrl(1);
661 if ($proj->title) {
662 $morehtmlref .= '<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).'</span>';
663 }
664 }
665 }
666 }
667 $morehtmlref .= '</div>';
668
669
670 dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref);
671
672
673 print '<div class="fichecenter">';
674 print '<div class="fichehalfleft">';
675 print '<div class="underbanner clearboth"></div>';
676 print '<table class="border centpercent tableforfield">'."\n";
677
678 //Mo Parent
679 $mo_parent = $object->getMoParent();
680 if (is_object($mo_parent)) {
681 print '<tr class="field_fk_mo_parent">';
682 print '<td class="titlefield fieldname_fk_mo_parent">' . $langs->trans('ParentMo') . '</td>';
683 print '<td class="valuefield fieldname_fk_mo_parent">' .$mo_parent->getNomUrl(1).'</td>';
684 print '</tr>';
685 }
686
687 // Common attributes
688 $keyforbreak = 'fk_warehouse';
689 unset($object->fields['fk_project']);
690 unset($object->fields['fk_soc']);
691 include DOL_DOCUMENT_ROOT.'/core/tpl/commonfields_view.tpl.php';
692
693 // Other attributes
694 include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_view.tpl.php';
695
696 print '</table>';
697 print '</div>';
698 print '</div>';
699
700 print '<div class="clearboth"></div>';
701
702 print dol_get_fiche_end();
703
704
705 /*
706 * Lines
707 */
708
709 if (!empty($object->table_element_line)) {
710 // Show object lines
711 //$result = $object->getLinesArray();
712 $object->fetchLines();
713
714 print ' <form name="addproduct" id="addproduct" action="'.$_SERVER["PHP_SELF"].'?id='.$object->id.(($action != 'editline') ? '' : '#line_'.GETPOSTINT('lineid')).'" method="POST">
715 <input type="hidden" name="token" value="' . newToken().'">
716 <input type="hidden" name="action" value="' . (($action != 'editline') ? 'addline' : 'updateline').'">
717 <input type="hidden" name="mode" value="">
718 <input type="hidden" name="page_y" value="">
719 <input type="hidden" name="id" value="' . $object->id.'">
720 ';
721
722 /*if (!empty($conf->use_javascript_ajax) && $object->status == 0) {
723 include DOL_DOCUMENT_ROOT.'/core/tpl/ajaxrow.tpl.php';
724 }*/
725
726 if (!empty($object->lines)) {
727 print '<div class="div-table-responsive-no-min">';
728 print '<table id="tablelines" class="noborder noshadow" width="100%">';
729
730 print '<tr class="liste_titre">';
731 print '<td class="liste_titre">'.$langs->trans("Summary").'</td>';
732 print '<td></td>';
733 print '</tr>';
734
735 print '<tr class="oddeven">';
736 print '<td>'.$langs->trans("ProductsToConsume").'</td>';
737 print '<td>';
738 if (!empty($object->lines)) {
739 $i = 0;
740 foreach ($object->lines as $line) {
741 if ($line->role == 'toconsume') {
742 if ($i) {
743 print ', ';
744 }
745 $tmpproduct = new Product($db);
746 $tmpproduct->fetch($line->fk_product);
747 print $tmpproduct->getNomUrl(1);
748 $i++;
749 }
750 }
751 }
752 print '</td>';
753 print '</tr>';
754
755 print '<tr class="oddeven">';
756 print '<td>'.$langs->trans("ProductsToProduce").'</td>';
757 print '<td>';
758 if (!empty($object->lines)) {
759 $i = 0;
760 foreach ($object->lines as $line) {
761 if ($line->role == 'toproduce') {
762 if ($i) {
763 print ', ';
764 }
765 $tmpproduct = new Product($db);
766 $tmpproduct->fetch($line->fk_product);
767 print $tmpproduct->getNomUrl(1);
768 $i++;
769 }
770 }
771 }
772 print '</td>';
773 print '</tr>';
774
775 print '</table>';
776 print '</div>';
777 }
778
779 print "</form>\n";
780 }
781
782
783 // Buttons for actions
784
785 if ($action != 'presend' && $action != 'editline') {
786 print '<div class="tabsAction">'."\n";
787 $parameters = array();
788 $reshook = $hookmanager->executeHooks('addMoreActionsButtons', $parameters, $object, $action); // Note that $action and $object may have been modified by hook
789 if ($reshook < 0) {
790 setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
791 }
792
793 if (empty($reshook)) {
794 // Send
795 //if (empty($user->socid)) {
796 // print '<a class="butAction" href="' . $_SERVER["PHP_SELF"] . '?id=' . $object->id . '&action=presend&mode=init#formmailbeforetitle">' . $langs->trans('SendMail') . '</a>'."\n";
797 //}
798
799 // Back to draft
800 if ($object->status == $object::STATUS_VALIDATED) {
801 if ($permissiontoadd) {
802 // TODO Add test that production has not started
803 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=confirm_setdraft&confirm=yes&token='.newToken().'">'.$langs->trans("SetToDraft").'</a>';
804 }
805 }
806
807 // Modify
808 if ($object->status == $object::STATUS_DRAFT) {
809 if ($permissiontoadd) {
810 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=edit&token='.newToken().'">'.$langs->trans("Modify").'</a>'."\n";
811 } else {
812 print '<a class="butActionRefused classfortooltip" href="#" title="'.dol_escape_htmltag($langs->trans("NotEnoughPermissions")).'">'.$langs->trans('Modify').'</a>'."\n";
813 }
814 }
815
816 // Validate
817 if ($object->status == $object::STATUS_DRAFT) {
818 if ($permissiontoadd) {
819 if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) {
820 print '<a class="butAction" href="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'&action=validate&token='.newToken().'">'.$langs->trans("Validate").'</a>';
821 } else {
822 $langs->load("errors");
823 print '<a class="butActionRefused" href="" title="'.$langs->trans("ErrorAddAtLeastOneLineFirst").'">'.$langs->trans("Validate").'</a>';
824 }
825 }
826 }
827
828 // Clone
829 if ($permissiontoadd) {
830 print dolGetButtonAction($langs->trans("ToClone"), '', 'default', $_SERVER['PHP_SELF'].'?id='.$object->id.(!empty($object->socid) ? '&socid='.$object->socid : "").'&action=clone&token='.newToken().'&object=mo', 'clone', $permissiontoadd);
831 }
832
833 // Cancel - Reopen
834 if ($permissiontoadd) {
835 if ($object->status == $object::STATUS_VALIDATED || $object->status == $object::STATUS_INPROGRESS) {
836 $arrayproduced = $object->fetchLinesLinked('produced', 0);
837 $nbProduced = 0;
838 foreach ($arrayproduced as $lineproduced) {
839 $nbProduced += $lineproduced['qty'];
840 }
841 if ($nbProduced > 0) { // If production has started, we can close it
842 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=confirm_produced&confirm=yes&token='.newToken().'">'.$langs->trans("Close").'</a>'."\n";
843 } else {
844 print '<a class="butActionRefused" href="#" title="'.$langs->trans("GoOnTabProductionToProduceFirst", $langs->transnoentitiesnoconv("Production")).'">'.$langs->trans("Close").'</a>'."\n";
845 }
846
847 print '<a class="butActionDelete" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=cancel&token='.newToken().'">'.$langs->trans("Cancel").'</a>'."\n";
848 }
849
850 if ($object->status == $object::STATUS_PRODUCED || $object->status == $object::STATUS_CANCELED) {
851 print '<a class="butAction" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=confirm_reopen&confirm=yes&token='.newToken().'">'.$langs->trans("ReOpen").'</a>'."\n";
852 }
853 }
854
855 // Delete
856 print dolGetButtonAction($langs->trans("Delete"), '', 'delete', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=delete&token='.newToken(), 'delete', $permissiontodelete);
857 }
858 print '</div>'."\n";
859 }
860
861
862 // Select mail models is same action as presend
863 if (GETPOST('modelselected')) {
864 $action = 'presend';
865 }
866
867 if ($action != 'presend') {
868 print '<div class="fichecenter"><div class="fichehalfleft">';
869 print '<a name="builddoc"></a>'; // ancre
870
871 // Documents
872 $objref = dol_sanitizeFileName($object->ref);
873 $relativepath = $objref.'/'.$objref.'.pdf';
874 $filedir = $conf->mrp->dir_output.'/'.$objref;
875 $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id;
876 $genallowed = $user->hasRight('mrp', 'read'); // If you can read, you can build the PDF to read content
877 $delallowed = $user->hasRight("mrp", "creer"); // If you can create/edit, you can remove a file on card
878 print $formfile->showdocuments('mrp:mo', $objref, $filedir, $urlsource, $genallowed, $delallowed, $object->model_pdf, 1, 0, 0, 28, 0, '', '', '', $mysoc->default_lang, '', $object);
879
880 // Show links to link elements
881 $tmparray = $form->showLinkToObjectBlock($object, array(), array('mo'), 1);
882 $linktoelem = $tmparray['linktoelem'];
883 $htmltoenteralink = $tmparray['htmltoenteralink'];
884 print $htmltoenteralink;
885
886 $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem, array());
887
888
889 print '</div><div class="fichehalfright">';
890
891 $MAXEVENT = 10;
892
893 $morehtmlcenter = dolGetButtonTitle($langs->trans('SeeAll'), '', 'fa fa-bars imgforviewmode', DOL_URL_ROOT.'/mrp/mo_agenda.php?id='.$object->id);
894
895 // List of actions on element
896 include_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
897 $formactions = new FormActions($db);
898 $somethingshown = $formactions->showactions($object, $object->element, $socid, 1, '', $MAXEVENT, '', $morehtmlcenter);
899
900 print '</div></div>';
901 }
902
903 //Select mail models is same action as presend
904 if (GETPOST('modelselected')) {
905 $action = 'presend';
906 }
907
908 // Presend form
909 $modelmail = 'mo';
910 $defaulttopic = 'InformationMessage';
911 $diroutput = $conf->mrp->dir_output;
912 $trackid = 'mo'.$object->id;
913
914 include DOL_DOCUMENT_ROOT.'/core/tpl/card_presend.tpl.php';
915}
916
917// End of page
918llxFooter();
919$db->close();
$id
Support class for third parties, contacts, members, users or resources.
Definition account.php:48
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
Definition card.php:67
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:166
Class for BOM.
Definition bom.class.php:42
Class for BOMLine.
Class to manage standard extra fields.
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.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
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.
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.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
newToken()
Return the value of token currently saved into session with name 'newtoken'.
dolGetButtonAction($label, $text='', $actionType='default', $url='', $id='', $userRight=1, $params=array())
Function dolGetButtonAction.
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...
dol_sanitizeFileName($str, $newstr='_', $unaccent=1, $includequotes=0)
Clean a string to use it as a file name.
getDolGlobalString($key, $default='')
Return a Dolibarr global constant string value.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
global $conf
The following vars must be defined: $type2label $form $conf, $lang, The following vars may also be de...
Definition member.php:79
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.