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