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