30require
'../main.inc.php';
31require_once DOL_DOCUMENT_ROOT.
'/bom/class/bom.class.php';
32require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formcompany.class.php';
33require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formfile.class.php';
34require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formprojet.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.
'/projet/class/project.class.php';
38require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
39require_once DOL_DOCUMENT_ROOT.
'/product/class/html.formproduct.class.php';
40require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/entrepot.class.php';
41require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/productlot.class.php';
42require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
43require_once DOL_DOCUMENT_ROOT.
'/workstation/class/workstation.class.php';
47$langs->loadLangs(array(
"mrp",
"stocks",
"other",
"product",
"productbatch"));
52$action =
GETPOST(
'action',
'aZ09');
53$confirm =
GETPOST(
'confirm',
'alpha');
54$cancel =
GETPOST(
'cancel',
'aZ09');
55$contextpage =
GETPOST(
'contextpage',
'aZ') ?
GETPOST(
'contextpage',
'aZ') :
'mocard';
56$backtopage =
GETPOST(
'backtopage',
'alpha');
59$fk_default_warehouse =
GETPOSTINT(
'fk_default_warehouse');
61$collapse =
GETPOST(
'collapse',
'aZ09comma');
66$diroutputmassaction = $conf->mrp->dir_output.
'/temp/massgeneration/'.$user->id;
67$objectline =
new MoLine($db);
69$hookmanager->initHooks(array(
'moproduction',
'globalcard'));
72$extrafields->fetch_name_optionals_label(
$object->table_element);
74$search_array_options = $extrafields->getOptionalsFromPost(
$object->table_element,
'',
'search_');
77$search_all =
GETPOST(
"search_all",
'alpha');
79foreach (
$object->fields as $key => $val) {
80 if (
GETPOST(
'search_'.$key,
'alpha')) {
81 $search[$key] =
GETPOST(
'search_'.$key,
'alpha');
85if (empty($action) && empty($id) && empty($ref)) {
90include DOL_DOCUMENT_ROOT.
'/core/actions_fetchobject.inc.php';
95$isdraft = ((
$object->status == $object::STATUS_DRAFT) ? 1 : 0);
99$permissionnote = $user->hasRight(
'mrp',
'write');
100$permissiondellink = $user->hasRight(
'mrp',
'write');
101$permissiontoadd = $user->hasRight(
'mrp',
'write');
102$permissiontodelete = $user->hasRight(
'mrp',
'delete') || ($permissiontoadd && isset(
$object->status) &&
$object->status == $object::STATUS_DRAFT);
104$permissiontoproduce = $permissiontoadd;
105$permissiontoupdatecost = $user->hasRight(
'bom',
'read');
107$upload_dir = $conf->mrp->multidir_output[isset(
$object->entity) ?
$object->entity : 1];
114$parameters = array();
115$reshook = $hookmanager->executeHooks(
'doActions', $parameters, $object, $action);
120if (empty($reshook)) {
123 $backurlforlist = DOL_URL_ROOT.
'/mrp/mo_list.php';
125 if (empty($backtopage) || ($cancel && empty($id))) {
127 if (empty($id) && (($action !=
'add' && $action !=
'create') || $cancel)) {
128 $backtopage = $backurlforlist;
130 $backtopage = DOL_URL_ROOT.
'/mrp/mo_production.php?id='.($id > 0 ? $id :
'__ID__');
133 $triggermodname =
'MO_MODIFY';
135 if ($action ==
'confirm_cancel' && $confirm ==
'yes' && !empty($permissiontoadd)) {
136 $also_cancel_consumed_and_produced_lines = (
GETPOST(
'alsoCancelConsumedAndProducedLines',
'alpha') ? 1 : 0);
137 $result =
$object->cancel($user, 0, $also_cancel_consumed_and_produced_lines);
139 header(
"Location: " . DOL_URL_ROOT.
'/mrp/mo_card.php?id=' .
$object->id);
145 } elseif ($action ==
'confirm_delete' && $confirm ==
'yes' && !empty($permissiontodelete)) {
146 $also_cancel_consumed_and_produced_lines = (
GETPOST(
'alsoCancelConsumedAndProducedLines',
'alpha') ? 1 : 0);
147 $result =
$object->delete($user, 0, $also_cancel_consumed_and_produced_lines);
149 header(
"Location: " . $backurlforlist);
158 include DOL_DOCUMENT_ROOT.
'/core/actions_addupdatedelete.inc.php';
161 include DOL_DOCUMENT_ROOT.
'/core/actions_dellink.inc.php';
164 include DOL_DOCUMENT_ROOT.
'/core/actions_printing.inc.php';
167 $triggersendname =
'MO_SENTBYMAIL';
168 $autocopy =
'MAIN_MAIL_AUTOCOPY_MO_TO';
169 $trackid =
'mo'.$object->id;
170 include DOL_DOCUMENT_ROOT.
'/core/actions_sendmails.inc.php';
175 if ($action ==
'set_thirdparty' && $permissiontoadd) {
176 $object->setValueFrom(
'fk_soc',
GETPOSTINT(
'fk_soc'),
'',
'',
'date',
'', $user, $triggermodname);
178 if ($action ==
'classin' && $permissiontoadd) {
182 if ($action ==
'confirm_reopen' && $permissiontoadd) {
183 $result =
$object->setStatut($object::STATUS_INPROGRESS, 0,
'',
'MRP_REOPEN');
186 if (($action ==
'confirm_addconsumeline' &&
GETPOST(
'addconsumelinebutton') && $permissiontoadd)
187 || ($action ==
'confirm_addproduceline' &&
GETPOST(
'addproducelinebutton') && $permissiontoadd)) {
188 $moline =
new MoLine($db);
193 $moline->fk_product =
GETPOSTINT(
'productidtoadd');
194 if (
GETPOST(
'addconsumelinebutton')) {
195 $moline->role =
'toconsume';
197 $moline->role =
'toproduce';
199 $moline->origin_type =
'free';
200 $moline->position = 0;
203 if (!empty($moline->fk_product)) {
204 $tmpproduct =
new Product($db);
205 $tmpproduct->fetch($moline->fk_product);
207 $moline->fk_default_workstation = $tmpproduct->fk_default_workstation;
211 $moline->fk_unit = $tmpproduct->fk_unit;
215 $extralabelsline = $extrafields->fetch_name_optionals_label(
$object->table_element_line);
216 $array_options = $extrafields->getOptionalsFromPost(
$object->table_element_line);
218 if (is_array($extralabelsline)) {
220 foreach ($extralabelsline as $key => $value) {
221 unset($_POST[
"options_".$key]);
224 if (is_array($array_options) && count($array_options) > 0) {
225 $moline->array_options = $array_options;
228 $resultline = $moline->create($user,
false);
229 if ($resultline <= 0) {
236 header(
"Location: ".$_SERVER[
"PHP_SELF"].
'?id='.
$object->id);
240 if (in_array($action, array(
'confirm_consumeorproduce',
'confirm_consumeandproduceall')) && $permissiontoproduce) {
243 $labelmovement =
GETPOST(
'inventorylabel',
'alphanohtml');
244 $codemovement =
GETPOST(
'inventorycode',
'alphanohtml');
249 foreach (
$object->lines as $line) {
250 if ($line->role ==
'toconsume') {
251 $tmpproduct =
new Product($db);
252 $tmpproduct->fetch($line->fk_product);
255 while (GETPOSTISSET(
'qty-'.$line->id.
'-'.$i)) {
258 if ($qtytoprocess != 0) {
260 if (GETPOSTISSET(
'idwarehouse-'.$line->id.
'-'.$i)) {
261 if (!(
GETPOST(
'idwarehouse-'.$line->id.
'-'.$i) > 0)) {
262 $langs->load(
"errors");
263 setEventMessages($langs->trans(
"ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv(
"Warehouse"), $tmpproduct->ref),
null,
'errors');
266 if ($tmpproduct->status_batch && (!
GETPOST(
'batch-'.$line->id.
'-'.$i))) {
267 $langs->load(
"errors");
268 setEventMessages($langs->trans(
"ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv(
"Batch"), $tmpproduct->ref),
null,
'errors');
274 if (!$error &&
GETPOST(
'idwarehouse-'.$line->id.
'-'.$i) > 0) {
276 $id_product_batch = 0;
278 $stockmove->context[
'mrp_role'] =
'toconsume';
280 if ($qtytoprocess >= 0) {
281 $idstockmove = $stockmove->livraison($user, $line->fk_product,
GETPOST(
'idwarehouse-'.$line->id.
'-'.$i), $qtytoprocess, 0, $labelmovement,
dol_now(),
'',
'',
GETPOST(
'batch-'.$line->id.
'-'.$i), $id_product_batch, $codemovement);
283 $idstockmove = $stockmove->reception($user, $line->fk_product,
GETPOST(
'idwarehouse-'.$line->id.
'-'.$i), $qtytoprocess * -1, 0, $labelmovement,
dol_now(),
'',
'',
GETPOST(
'batch-'.$line->id.
'-'.$i), $id_product_batch, $codemovement);
285 if ($idstockmove < 0) {
293 $moline =
new MoLine($db);
295 $moline->position = $pos;
296 $moline->fk_product = $line->fk_product;
297 $moline->fk_warehouse =
GETPOST(
'idwarehouse-'.$line->id.
'-'.$i);
298 $moline->qty = $qtytoprocess;
299 $moline->batch =
GETPOST(
'batch-'.$line->id.
'-'.$i);
300 $moline->role =
'consumed';
301 $moline->fk_mrp_production = $line->id;
302 $moline->fk_stock_movement = $idstockmove == 0 ? null : $idstockmove;
303 $moline->fk_user_creat = $user->id;
305 $resultmoline = $moline->create($user);
306 if ($resultmoline <= 0) {
323 foreach (
$object->lines as $line) {
324 if ($line->role ==
'toproduce') {
325 $tmpproduct =
new Product($db);
326 $tmpproduct->fetch($line->fk_product);
329 while (GETPOSTISSET(
'qtytoproduce-'.$line->id.
'-'.$i)) {
330 $qtytoprocess = (float)
price2num(
GETPOST(
'qtytoproduce-'.$line->id.
'-'.$i));
331 $pricetoprocess =
GETPOST(
'pricetoproduce-'.$line->id.
'-'.$i) ?
price2num(
GETPOST(
'pricetoproduce-'.$line->id.
'-'.$i)) : 0;
333 if ($qtytoprocess != 0) {
335 if (GETPOSTISSET(
'idwarehousetoproduce-'.$line->id.
'-'.$i)) {
336 if (!(
GETPOST(
'idwarehousetoproduce-'.$line->id.
'-'.$i) > 0)) {
337 $langs->load(
"errors");
338 setEventMessages($langs->trans(
"ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv(
"Warehouse"), $tmpproduct->ref),
null,
'errors');
341 if (isModEnabled(
'productbatch') && $tmpproduct->status_batch && (!
GETPOST(
'batchtoproduce-'.$line->id.
'-'.$i))) {
342 $langs->load(
"errors");
343 setEventMessages($langs->trans(
"ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv(
"Batch"), $tmpproduct->ref),
null,
'errors');
349 if (!$error &&
GETPOST(
'idwarehousetoproduce-'.$line->id.
'-'.$i) > 0) {
351 $id_product_batch = 0;
352 $stockmove->origin_type =
$object->element;
353 $stockmove->origin_id =
$object->id;
354 $stockmove->context[
'mrp_role'] =
'toproduce';
356 $idstockmove = $stockmove->reception($user, $line->fk_product,
GETPOST(
'idwarehousetoproduce-'.$line->id.
'-'.$i), $qtytoprocess, $pricetoprocess, $labelmovement,
'',
'',
GETPOST(
'batchtoproduce-'.$line->id.
'-'.$i),
dol_now(), $id_product_batch, $codemovement);
357 if ($idstockmove < 0) {
365 $moline =
new MoLine($db);
367 $moline->position = $pos;
368 $moline->fk_product = $line->fk_product;
369 $moline->fk_warehouse =
GETPOST(
'idwarehousetoproduce-'.$line->id.
'-'.$i);
370 $moline->qty = $qtytoprocess;
371 $moline->batch =
GETPOST(
'batchtoproduce-'.$line->id.
'-'.$i);
372 $moline->role =
'produced';
373 $moline->fk_mrp_production = $line->id;
374 $moline->fk_stock_movement = $idstockmove;
375 $moline->fk_user_creat = $user->id;
377 $resultmoline = $moline->create($user);
378 if ($resultmoline <= 0) {
393 $consumptioncomplete =
true;
394 $productioncomplete =
true;
397 foreach (
$object->lines as $line) {
398 if ($line->role ==
'toconsume') {
399 $arrayoflines =
$object->fetchLinesLinked(
'consumed', $line->id);
400 $alreadyconsumed = 0;
401 foreach ($arrayoflines as $line2) {
402 $alreadyconsumed += $line2[
'qty'];
405 if ($alreadyconsumed < $line->qty) {
406 $consumptioncomplete =
false;
409 if ($line->role ==
'toproduce') {
410 $arrayoflines =
$object->fetchLinesLinked(
'produced', $line->id);
411 $alreadyproduced = 0;
412 foreach ($arrayoflines as $line2) {
413 $alreadyproduced += $line2[
'qty'];
416 if ($alreadyproduced < $line->qty) {
417 $productioncomplete =
false;
422 $consumptioncomplete =
false;
423 $productioncomplete =
false;
427 dol_syslog(
"consumptioncomplete = ".json_encode($consumptioncomplete).
" productioncomplete = ".json_encode($productioncomplete));
428 if ($consumptioncomplete && $productioncomplete) {
429 $result =
$object->setStatut($object::STATUS_PRODUCED, 0,
'',
'MRP_MO_PRODUCED');
431 $result =
$object->setStatut($object::STATUS_INPROGRESS, 0,
'',
'MRP_MO_PRODUCED');
440 $action = str_replace(
'confirm_',
'', $action);
446 header(
"Location: ".$_SERVER[
"PHP_SELF"].
'?id='.
$object->id);
452 if ($action ==
'confirm_produced' && $confirm ==
'yes' && $permissiontoadd) {
453 $result =
$object->setStatut($object::STATUS_PRODUCED, 0,
'',
'MRP_MO_PRODUCED');
457 $outputlangs = $langs;
460 $newlang =
GETPOST(
'lang_id',
'aZ09');
463 $newlang =
$object->thirdparty->default_lang;
465 if (!empty($newlang)) {
467 $outputlangs->setDefaultLang($newlang);
472 $object->generateDocument($model, $outputlangs, 0, 0, 0);
479 if ($action ==
'confirm_editline' && $permissiontoadd) {
480 $moline =
new MoLine($db);
483 $extrafields->fetch_name_optionals_label($moline->element);
484 foreach ($extrafields->attributes[$moline->table_element][
'label'] as $key => $label) {
485 $value =
GETPOST(
'options_'.$key,
'alphanohtml');
486 $moline->array_options[
"options_".$key] = $value;
489 $res = $moline->update($user);
492 header(
"Location: ".$_SERVER[
"PHP_SELF"].
'?id='.
$object->id);
495 header(
"Location: ".$_SERVER[
"PHP_SELF"].
'?id='.
$object->id);
507$form =
new Form($db);
514$help_url =
'EN:Module_Manufacturing_Orders|FR:Module_Ordres_de_Fabrication|DE:Modul_Fertigungsauftrag';
515$morejs = array(
'/mrp/js/lib_dispatch.js.php');
516llxHeader(
'', $langs->trans(
'Mo'), $help_url,
'', 0, 0, $morejs);
521if (
$object->id > 0 && (empty($action) || ($action !=
'edit' && $action !=
'create'))) {
522 $res =
$object->fetch_thirdparty();
523 $res =
$object->fetch_optionals();
526 $tmpwarehouse->fetch(
$object->fk_warehouse);
527 $fk_default_warehouse =
$object->fk_warehouse;
537 if ($action ==
'delete') {
538 $formquestion = array(
540 'label' => $langs->trans(
'MoCancelConsumedAndProducedLines'),
541 'name' =>
'alsoCancelConsumedAndProducedLines',
542 'type' =>
'checkbox',
546 $formconfirm = $form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.
$object->id, $langs->trans(
'DeleteMo'), $langs->trans(
'ConfirmDeleteMo'),
'confirm_delete', $formquestion, 0, 1);
549 if ($action ==
'deleteline') {
550 $formconfirm = $form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&lineid='.$lineid.
'&fk_movement='.$fk_movement, $langs->trans(
'DeleteLine'), $langs->trans(
'ConfirmDeleteLine'),
'confirm_deleteline',
'', 0, 1);
553 if ($action ==
'clone') {
555 $formquestion = array();
556 $formconfirm = $form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.
$object->id, $langs->trans(
'ToClone'), $langs->trans(
'ConfirmCloneMo',
$object->ref),
'confirm_clone', $formquestion,
'yes', 1);
560 if ($action ==
'validate') {
562 $ref = substr(
$object->ref, 1, 4);
563 if ($ref ==
'PROV') {
570 $text = $langs->trans(
'ConfirmValidateMo', $numref);
579 $formquestion = array();
580 if (isModEnabled(
'mrp')) {
582 require_once DOL_DOCUMENT_ROOT.
'/product/class/html.formproduct.class.php';
585 if ($conf->browser->name ==
'ie') {
588 $formquestion = array(
595 $formconfirm = $form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.
$object->id, $langs->trans(
'Validate'), $text,
'confirm_validate', $formquestion, 0, 1, 220);
599 if ($action ==
'cancel') {
600 $formquestion = array(
602 'label' => $langs->trans(
'MoCancelConsumedAndProducedLines'),
603 'name' =>
'alsoCancelConsumedAndProducedLines',
604 'type' =>
'checkbox',
605 'value' => !
getDolGlobalString(
'MO_ALSO_CANCEL_CONSUMED_AND_PRODUCED_LINES_BY_DEFAULT') ? 0 : 1
608 $formconfirm = $form->formconfirm($_SERVER[
"PHP_SELF"] .
'?id=' .
$object->id, $langs->trans(
'CancelMo'), $langs->trans(
'ConfirmCancelMo'),
'confirm_cancel', $formquestion, 0, 1);
612 $parameters = array(
'formConfirm' => $formconfirm,
'lineid' => $lineid);
613 $reshook = $hookmanager->executeHooks(
'formConfirm', $parameters, $object, $action);
614 if (empty($reshook)) {
615 $formconfirm .= $hookmanager->resPrint;
616 } elseif ($reshook > 0) {
617 $formconfirm = $hookmanager->resPrint;
626 $linkback =
'<a href="'.DOL_URL_ROOT.
'/mrp/mo_list.php?restore_lastsearch_values=1'.(!empty($socid) ?
'&socid='.$socid :
'').
'">'.$langs->trans(
"BackToList").
'</a>';
628 $morehtmlref =
'<div class="refidno">';
637 if (is_object(
$object->thirdparty)) {
638 $morehtmlref .=
$object->thirdparty->getNomUrl(1,
'customer');
640 $morehtmlref .=
' (<a href="'.DOL_URL_ROOT.
'/commande/list.php?socid='.
$object->thirdparty->id.
'&search_societe='.urlencode(
$object->thirdparty->name).
'">'.$langs->trans(
"OtherOrders").
'</a>)';
645 if (isModEnabled(
'project')) {
646 $langs->load(
"projects");
647 if (is_object(
$object->thirdparty)) {
648 $morehtmlref .=
'<br>';
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> ';
655 $morehtmlref .= $form->form_project($_SERVER[
'PHP_SELF'].
'?id='.
$object->id,
$object->socid,
$object->fk_project, ($action ==
'classify' ?
'projectid' :
'none'), 0, 0, 0, 1,
'',
'maxwidth300');
657 if (!empty(
$object->fk_project)) {
659 $proj->fetch(
$object->fk_project);
660 $morehtmlref .= $proj->getNomUrl(1);
662 $morehtmlref .=
'<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).
'</span>';
667 $morehtmlref .=
'</div>';
670 dol_banner_tab($object,
'ref', $linkback, 1,
'ref',
'ref', $morehtmlref);
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";
679 $keyforbreak =
'fk_warehouse';
680 unset(
$object->fields[
'fk_project']);
681 unset(
$object->fields[
'fk_soc']);
682 include DOL_DOCUMENT_ROOT.
'/core/tpl/commonfields_view.tpl.php';
685 include DOL_DOCUMENT_ROOT.
'/core/tpl/extrafields_view.tpl.php';
691 print
'<div class="clearboth"></div>';
696 if (!in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
697 print
'<div class="tabsAction">';
699 $parameters = array();
701 $reshook = $hookmanager->executeHooks(
'addMoreActionsButtons', $parameters, $object, $action);
702 if (empty($reshook)) {
704 if (
$object->status == $object::STATUS_DRAFT) {
705 if ($permissiontoadd) {
707 print
'<a class="butAction" href="'.$_SERVER[
'PHP_SELF'].
'?id='.
$object->id.
'&action=validate&token='.$newToken.
'">'.$langs->trans(
"Validate").
'</a>';
709 $langs->load(
"errors");
710 print
'<a class="butActionRefused" href="" title="'.$langs->trans(
"ErrorAddAtLeastOneLineFirst").
'">'.$langs->trans(
"Validate").
'</a>';
716 if (
$object->status == Mo::STATUS_VALIDATED ||
$object->status == Mo::STATUS_INPROGRESS) {
717 if ($permissiontoproduce) {
718 print
'<a class="butAction" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=consumeorproduce&token='.$newToken.
'">'.$langs->trans(
'ConsumeOrProduce').
'</a>';
720 print
'<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans(
"NotEnoughPermissions").
'">'.$langs->trans(
'ConsumeOrProduce').
'</a>';
722 } elseif (
$object->status == Mo::STATUS_DRAFT) {
723 print
'<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans(
"ValidateBefore").
'">'.$langs->trans(
'ConsumeOrProduce').
'</a>';
727 if (
$object->status == Mo::STATUS_VALIDATED ||
$object->status == Mo::STATUS_INPROGRESS) {
728 if ($permissiontoproduce) {
729 print
'<a class="butAction" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=consumeandproduceall&token='.$newToken.
'">'.$langs->trans(
'ConsumeAndProduceAll').
'</a>';
731 print
'<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans(
"NotEnoughPermissions").
'">'.$langs->trans(
'ConsumeAndProduceAll').
'</a>';
733 } elseif (
$object->status == Mo::STATUS_DRAFT) {
734 print
'<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans(
"ValidateBefore").
'">'.$langs->trans(
'ConsumeAndProduceAll').
'</a>';
738 if ($permissiontoadd) {
739 if (
$object->status == $object::STATUS_VALIDATED ||
$object->status == $object::STATUS_INPROGRESS) {
740 $arrayproduced =
$object->fetchLinesLinked(
'produced', 0);
742 foreach ($arrayproduced as $lineproduced) {
743 $nbProduced += $lineproduced[
'qty'];
745 if ($nbProduced > 0) {
746 print
'<a class="butAction" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=confirm_produced&confirm=yes&token='.$newToken.
'">'.$langs->trans(
"Close").
'</a>'.
"\n";
748 print
'<a class="butActionRefused" href="#" title="'.$langs->trans(
"GoOnTabProductionToProduceFirst", $langs->transnoentitiesnoconv(
"Production")).
'">'.$langs->trans(
"Close").
'</a>'.
"\n";
751 print
'<a class="butActionDelete" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=cancel&token='.$newToken.
'">'.$langs->trans(
"Cancel").
'</a>'.
"\n";
754 if (
$object->status == $object::STATUS_CANCELED) {
755 print
'<a class="butAction" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=confirm_reopen&confirm=yes&token='.$newToken.
'">'.$langs->trans(
"ReOpen").
'</a>'.
"\n";
758 if (
$object->status == $object::STATUS_PRODUCED) {
759 if ($permissiontoproduce) {
760 print
'<a class="butAction" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=confirm_reopen&token='.$newToken.
'">'.$langs->trans(
'ReOpen').
'</a>';
762 print
'<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans(
"NotEnoughPermissions").
'">'.$langs->trans(
'ReOpen').
'</a>';
771 if (in_array($action, array(
'consumeorproduce',
'consumeandproduceall',
'addconsumeline',
'addproduceline',
'editline'))) {
772 print
'<form method="POST" action="'.$_SERVER[
"PHP_SELF"].
'">';
773 print
'<input type="hidden" name="token" value="'.newToken().
'">';
774 print
'<input type="hidden" name="action" value="confirm_'.$action.
'">';
775 print
'<input type="hidden" name="backtopage" value="'.$backtopage.
'">';
776 print
'<input type="hidden" name="id" value="'.$id.
'">';
779 if (in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
780 $defaultstockmovementlabel =
GETPOST(
'inventorylabel',
'alphanohtml') ?
GETPOST(
'inventorylabel',
'alphanohtml') : $langs->trans(
"ProductionForRef",
$object->
ref);
783 print
'<div class="center'.(in_array($action, array(
'consumeorproduce',
'consumeandproduceall')) ?
' formconsumeproduce' :
'').
'">';
784 print
'<div class="opacitymedium hideonsmartphone paddingbottom">'.$langs->trans(
"ConfirmProductionDesc", $langs->transnoentitiesnoconv(
"Confirm")).
'<br></div>';
785 print
'<span class="fieldrequired">'.$langs->trans(
"InventoryCode").
':</span> <input type="text" class="minwidth150 maxwidth200" name="inventorycode" value="'.$defaultstockmovementcode.
'"> ';
786 print
'<span class="clearbothonsmartphone"></span>';
787 print $langs->trans(
"MovementLabel").
': <input type="text" class="minwidth300" name="inventorylabel" value="'.$defaultstockmovementlabel.
'"><br><br>';
788 print
'<input type="checkbox" id="autoclose" name="autoclose" value="1"'.(GETPOSTISSET(
'inventorylabel') ? (
GETPOST(
'autoclose') ?
' checked="checked"' :
'') :
' checked="checked"').
'> <label for="autoclose">'.$langs->trans(
"AutoCloseMO").
'</label><br>';
789 print
'<input type="submit" class="button" value="'.$langs->trans(
"Confirm").
'" name="confirm">';
791 print
'<input class="button button-cancel" type="submit" value="'.$langs->trans(
"Cancel").
'" name="cancel">';
805 if (!empty(
$object->table_element_line)) {
812 $res = $bom->fetch(
$object->fk_bom);
814 $bom->calculateCosts();
815 $bomcost = $bom->unit_cost;
821 print
'<div class="fichecenter">';
822 print
'<div class="fichehalfleft">';
823 print
'<div class="clearboth"></div>';
825 $url = $_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=addconsumeline&token='.
newToken();
826 $permissiontoaddaconsumeline =
$object->status != $object::STATUS_PRODUCED &&
$object->status != $object::STATUS_CANCELED;
827 $parameters = array(
'morecss' =>
'reposition');
830 if ($action !=
'consumeorproduce' && $action !=
'consumeandproduceall') {
831 $newcardbutton =
dolGetButtonTitle($langs->trans(
'AddNewConsumeLines'),
'',
'fa fa-plus-circle size15x', $url,
'', $permissiontoaddaconsumeline, $parameters);
834 print
load_fiche_titre($langs->trans(
'Consumption'), $newcardbutton,
'', 0,
'',
'',
'');
836 print
'<div class="div-table-responsive-no-min">';
837 print
'<table class="noborder noshadow centpercent nobottom">';
839 print
'<!-- Line of title for products to consume -->'.
"\n";
840 print
'<tr class="liste_titre">';
842 print
'<td>'.$langs->trans(
"Product").
'</td>';
844 print
'<td class="right">'.$langs->trans(
"Qty").
'</td>';
849 print
'<td class="right">'.$langs->trans(
"UnitCost").
'</td>';
852 print
'<td class="right">'.$form->textwithpicto($langs->trans(
"QtyAlreadyConsumedShort"), $langs->trans(
"QtyAlreadyConsumed")).
'</td>';
855 if ($collapse || in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
856 print $langs->trans(
"Warehouse");
857 if (isModEnabled(
'workstation')) {
858 print
' '.$langs->trans(
"or").
' '.$langs->trans(
"Workstation");
861 if (in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
862 $listwarehouses = $tmpwarehouse->list_array(1);
863 if (count($listwarehouses) > 1) {
864 print
'<br>'.$form->selectarray(
'fk_default_warehouse', $listwarehouses, $fk_default_warehouse, $langs->trans(
"ForceTo"), 0, 0,
'', 0, 0, 0,
'',
'minwidth100 maxwidth200', 1);
865 } elseif (count($listwarehouses) == 1) {
866 print
'<br>'.$form->selectarray(
'fk_default_warehouse', $listwarehouses, $fk_default_warehouse, 0, 0, 0,
'', 0, 0, 0,
'',
'minwidth100 maxwidth200', 1);
872 if (isModEnabled(
'stock')) {
874 print
'<td align="right">';
875 if ($collapse || in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
876 print $langs->trans(
"Stock");
881 if (isModEnabled(
'productbatch')) {
883 if ($collapse || in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
884 print $langs->trans(
"Batch");
896 if (
$object->status == Mo::STATUS_DRAFT) {
901 if ($permissiontodelete) {
907 if ($action ==
'addconsumeline') {
908 print
'<!-- Add line to consume -->'.
"\n";
909 print
'<tr class="liste_titre">';
912 print $form->select_produits(
'',
'productidtoadd',
'', 0, 0, -1, 2,
'', 1, array(), 0,
'1', 0,
'maxwidth300');
915 print
'<td class="right"><input type="text" name="qtytoadd" value="1" class="width50 right"></td>';
923 print
'<td colspan="2">';
924 print
'<input type="submit" class="button buttongen button-add" name="addconsumelinebutton" value="'.$langs->trans(
"Add").
'">';
925 print
'<input type="submit" class="button buttongen button-cancel" name="canceladdconsumelinebutton" value="'.$langs->trans(
"Cancel").
'">';
927 if (isModEnabled(
'stock')) {
931 if (isModEnabled(
'productbatch')) {
939 if (
$object->status == Mo::STATUS_DRAFT) {
943 if ($permissiontodelete) {
949 if (is_object($objectline)) {
950 $extrafields->fetch_name_optionals_label(
$object->table_element_line);
951 $temps = $objectline->showOptionals($extrafields,
'edit', array(),
'',
'', 1,
'line');
952 if (!empty($temps)) {
953 print
'<tr class="liste_titre"><td style="padding-top: 20px" colspan="9" id="extrafield_lines_area_edit" name="extrafield_lines_area_edit">';
965 $nblinetoconsume = 0;
966 foreach (
$object->lines as $line) {
967 if ($line->role ==
'toconsume') {
972 $nblinetoconsumecursor = 0;
973 foreach (
$object->lines as $line) {
974 if ($line->role ==
'toconsume') {
975 $nblinetoconsumecursor++;
977 $tmpproduct =
new Product($db);
978 $tmpproduct->fetch($line->fk_product);
979 $linecost =
price2num($tmpproduct->pmp,
'MT');
983 $costprice =
price2num((!empty($tmpproduct->cost_price)) ? $tmpproduct->cost_price : $tmpproduct->pmp);
984 if (empty($costprice)) {
985 require_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.product.class.php';
987 if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product, $line->qty) > 0) {
988 $costprice = $productFournisseur->fourn_unitprice;
996 if ($useunit && $line->fk_unit > 0) {
999 if (preg_match(
'/^(\d+)([a-z]+)$/', $tmpproduct->duration, $reg)) {
1002 $qtyhourforline = 0;
1003 if ($line->fk_unit) {
1008 if ($qtyhourservice && $qtyhourforline) {
1009 $linecost =
price2num(($qtyhourforline / $qtyhourservice * $costprice) /
$object->qty,
'MT');
1010 $bomcostupdated +=
price2num(($qtyhourforline / $qtyhourservice * $costprice) /
$object->qty,
'MU');
1013 $bomcostupdated +=
price2num(($line->qty * $costprice) /
$object->qty,
'MU');
1017 $bomcostupdated +=
price2num(($line->qty * $costprice) /
$object->qty,
'MU');
1021 $bomcostupdated =
price2num($bomcostupdated,
'MU');
1022 $arrayoflines =
$object->fetchLinesLinked(
'consumed', $line->id);
1023 $alreadyconsumed = 0;
1024 foreach ($arrayoflines as $line2) {
1025 $alreadyconsumed += $line2[
'qty'];
1028 if ($action ==
'editline' && $lineid == $line->id) {
1029 $linecost =
price2num($tmpproduct->pmp,
'MT');
1031 $arrayoflines =
$object->fetchLinesLinked(
'consumed', $line->id);
1032 $alreadyconsumed = 0;
1033 if (is_array($arrayoflines) && !empty($arrayoflines)) {
1034 foreach ($arrayoflines as $line2) {
1035 $alreadyconsumed += $line2[
'qty'];
1038 $suffix =
'_' . $line->id;
1039 print
'<!-- Line to dispatch ' . $suffix .
' (line edited) -->' .
"\n";
1041 print
'<input id="qty_ordered' . $suffix .
'" type="hidden" value="' . $line->qty .
'">';
1043 print
'<input id="qty_dispatched' . $suffix .
'" type="hidden" value="' . $alreadyconsumed .
'">';
1045 print
'<input name="lineid" type="hidden" value="' . $line->id .
'">';
1048 print
'<td>' . $tmpproduct->getNomUrl(1);
1049 print
'<br><div class="opacitymedium small tdoverflowmax150" title="' .
dol_escape_htmltag($tmpproduct->label) .
'">' . $tmpproduct->label .
'</span>';
1053 print
'<td class="right nowraponall">';
1054 print
'<input class="width40 right" name="qty_lineProduce" value="'. $line->qty.
'">';
1058 print
'<td class="right nowraponall">';
1066 if ($permissiontoupdatecost &&
getDolGlobalString(
'MRP_SHOW_COST_FOR_CONSUMPTION')) {
1071 print
'<td class="right">';
1072 print
' ' .
price2num($alreadyconsumed,
'MS');
1080 if (isModEnabled(
'stock')) {
1081 print
'<td class="nowraponall right">';
1082 if ($tmpproduct->isStockManaged()) {
1083 if ($tmpproduct->stock_reel < ($line->qty - $alreadyconsumed)) {
1084 print
img_warning($langs->trans(
'StockTooLow')).
' ';
1086 print
'<span class="left">'. $tmpproduct->stock_reel .
' </span>';
1092 if (isModEnabled(
'productbatch')) {
1096 print
'<td colspan="'.(3 + (
$object->status == Mo::STATUS_DRAFT ? 1 : 0) + ($permissiontodelete ? 1 : 0)).
'">';
1097 print
'<input type="submit" class="button buttongen button-add small nominwidth" name="save" value="' . $langs->trans(
"Save") .
'">';
1098 print
'<input type="submit" class="button buttongen button-cancel small nominwidth" name="cancel" value="' . $langs->trans(
"Cancel") .
'">';
1104 if (!empty($extrafields)) {
1105 $line->fetch_optionals();
1106 $temps = $line->showOptionals($extrafields,
'edit', array(),
'',
'', 1,
'line');
1107 if (!empty($temps)) {
1109 print
'<tr><td colspan="'.$colspan.
'"><div style="padding-top: 20px" id="extrafield_lines_area_edit" name="extrafield_lines_area_edit">';
1111 print
'</div></td></tr>';
1115 $suffix =
'_' . $line->id;
1116 print
'<!-- Line to dispatch ' . $suffix .
' -->' .
"\n";
1118 print
'<input id="qty_ordered' . $suffix .
'" type="hidden" value="' . $line->qty .
'">';
1119 print
'<input id="qty_dispatched' . $suffix .
'" type="hidden" value="' . $alreadyconsumed .
'">';
1121 print
'<tr data-line-id="' . $line->id .
'">';
1124 print
'<td>' . $tmpproduct->getNomUrl(1);
1125 print
'<br><div class="opacitymedium small tdoverflowmax150" title="' .
dol_escape_htmltag($tmpproduct->label) .
'">' . $tmpproduct->label .
'</div>';
1129 print
'<td class="right nowraponall">';
1131 if ($line->qty_frozen) {
1132 $help = ($help ?
'<br>' :
'') .
'<strong>' . $langs->trans(
"QuantityFrozen") .
'</strong>: ' .
yn(1) .
' (' . $langs->trans(
"QuantityConsumedInvariable") .
')';
1133 print $form->textwithpicto(
'', $help, -1,
'lock') .
' ';
1135 if ($line->disable_stock_change) {
1136 $help = ($help ?
'<br>' :
'') .
'<strong>' . $langs->trans(
"DisableStockChange") .
'</strong>: ' .
yn(1) .
' (' . (($tmpproduct->type ==
Product::TYPE_SERVICE && !
getDolGlobalString(
'STOCK_SUPPORTS_SERVICES')) ? $langs->trans(
"NoStockChangeOnServices") : $langs->trans(
"DisableStockChangeHelp")) .
')';
1137 print $form->textwithpicto(
'', $help, -1,
'help') .
' ';
1143 print
'<td class="right nowraponall">';
1151 if ($permissiontoupdatecost &&
getDolGlobalString(
'MRP_SHOW_COST_FOR_CONSUMPTION')) {
1152 print
'<td class="right nowraponall">';
1153 print
price($linecost);
1158 print
'<td class="right">';
1159 if ($alreadyconsumed) {
1161 print
'jQuery(document).ready(function() {
1162 jQuery("#expandtoproduce' . $line->id .
'").click(function() {
1163 console.log("Expand mrp_production line ' . $line->id .
'");
1164 jQuery(".expanddetail' . $line->id .
'").toggle();';
1165 if ($nblinetoconsume == $nblinetoconsumecursor) {
1166 print
'if (jQuery("#tablelines").hasClass("nobottom")) { jQuery("#tablelines").removeClass("nobottom"); } else { jQuery("#tablelines").addClass("nobottom"); }';
1172 if (empty($conf->use_javascript_ajax)) {
1173 print
'<a href="' . $_SERVER[
"PHP_SELF"] .
'?collapse=' . $collapse .
',' . $line->id .
'">';
1175 print
img_picto($langs->trans(
"ShowDetails"),
"chevron-down",
'id="expandtoproduce' . $line->id .
'"');
1176 if (empty($conf->use_javascript_ajax)) {
1180 if ($nblinetoconsume == $nblinetoconsumecursor) {
1181 print
'<script>jQuery("#tablelines").removeClass("nobottom");</script>';
1184 print
' ' .
price2num($alreadyconsumed,
'MS');
1189 if (
getDolGlobalString(
'STOCK_CONSUMPTION_FROM_MANUFACTURING_WAREHOUSE') && $tmpwarehouse->id > 0) {
1190 print
img_picto(
'', $tmpwarehouse->picto) .
" " . $tmpwarehouse->label;
1192 if (isModEnabled(
'workstation') && $line->fk_default_workstation > 0) {
1194 $tmpworkstation->fetch($line->fk_default_workstation);
1195 print $tmpworkstation->getNomUrl(1);
1200 if (isModEnabled(
'stock')) {
1201 print
'<td class="nowraponall right">';
1203 if (!$line->disable_stock_change && $tmpproduct->stock_reel < ($line->qty - $alreadyconsumed)) {
1204 print
img_warning($langs->trans(
'StockTooLow')) .
' ';
1206 if (!
getDolGlobalString(
'STOCK_CONSUMPTION_FROM_MANUFACTURING_WAREHOUSE') || empty($tmpwarehouse->id)) {
1207 print
price2num($tmpproduct->stock_reel,
'MS');
1210 $tmpproduct->load_stock();
1211 $wh_stock = $tmpproduct->stock_warehouse[$tmpwarehouse->id];
1212 if (!empty($wh_stock)) {
1223 if (isModEnabled(
'productbatch')) {
1234 if (
$object->status == Mo::STATUS_DRAFT) {
1235 $href = $_SERVER[
"PHP_SELF"] .
'?id=' . ((int)
$object->id) .
'&action=editline&token=' .
newToken() .
'&lineid=' . ((int) $line->id);
1236 print
'<td class="center">';
1237 print
'<a class="reposition editfielda" href="' . $href .
'">';
1238 print
img_picto($langs->trans(
'TooltipEditAndRevertStockMovement'),
'edit');
1244 if ($permissiontodelete && empty($arrayoflines)) {
1245 $href = $_SERVER[
"PHP_SELF"] .
'?id=' . ((int)
$object->id) .
'&action=deleteline&token=' .
newToken() .
'&lineid=' . ((int) $line->id);
1246 print
'<td class="center">';
1247 print
'<a class="reposition" href="' . $href .
'">';
1248 print
img_picto($langs->trans(
'TooltipDeleteAndRevertStockMovement'),
'delete');
1256 if (!empty($extrafields)) {
1257 $line->fetch_optionals();
1258 $temps = $line->showOptionals($extrafields,
'view', array(),
'',
'', 1,
'line');
1259 if (!empty($temps)) {
1261 print
'<tr><td colspan="'.$colspan.
'"><div id="extrafield_lines_area_'.$line->id.
'" name="extrafield_lines_area_'.$line->id.
'">';
1263 print
'</div></td></tr>';
1269 foreach ($arrayoflines as $line2) {
1270 print
'<tr class="expanddetail'.$line->id.
' hideobject opacitylow">';
1274 $tmpstockmovement->id = $line2[
'fk_stock_movement'];
1275 print
'<a href="'.DOL_URL_ROOT.
'/product/stock/movement_list.php?search_ref='.$tmpstockmovement->id.
'">'.
img_picto($langs->trans(
"StockMovement"),
'movement',
'class="paddingright"').
'</a>';
1286 if ($permissiontoupdatecost &&
getDolGlobalString(
'MRP_SHOW_COST_FOR_CONSUMPTION')) {
1291 print
'<td class="right">'.$line2[
'qty'].
'</td>';
1294 print
'<td class="tdoverflowmax150">';
1295 if ($line2[
'fk_warehouse'] > 0) {
1296 $result = $tmpwarehouse->fetch($line2[
'fk_warehouse']);
1298 print $tmpwarehouse->getNomUrl(1);
1304 if (isModEnabled(
'stock')) {
1309 if (isModEnabled(
'productbatch')) {
1311 if ($line2[
'batch'] !=
'') {
1312 $tmpbatch->fetch(0, $line2[
'fk_product'], $line2[
'batch']);
1313 print $tmpbatch->getNomUrl(1);
1325 if (
$object->status == Mo::STATUS_DRAFT) {
1326 $href = $_SERVER[
"PHP_SELF"] .
'?id=' . ((int)
$object->id) .
'&action=editline&token=' .
newToken() .
'&lineid=' . ((int) $line2[
'rowid']);
1327 print
'<td class="center">';
1328 print
'<a class="reposition" href="' . $href .
'">';
1329 print
img_picto($langs->trans(
'TooltipEditAndRevertStockMovement'),
'edit');
1335 if ($permissiontodelete) {
1336 $href = $_SERVER[
"PHP_SELF"].
'?id='.((int)
$object->id).
'&action=deleteline&token='.
newToken().
'&lineid='.((int) $line2[
'rowid']).
'&fk_movement='.((int) $line2[
'fk_stock_movement']);
1337 print
'<td class="center">';
1338 print
'<a class="reposition" href="'.$href.
'">';
1339 print
img_picto($langs->trans(
'TooltipDeleteAndRevertStockMovement'),
'delete');
1347 if (in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
1349 print
'<!-- Enter line to consume -->'.
"\n";
1351 print
'<tr data-max-qty="'.$maxQty.
'" name="batch_'.$line->id.
'_'.$i.
'">';
1353 print
'<td><span class="opacitymedium">'.$langs->trans(
"ToConsume").
'</span></td>';
1354 $preselected = (GETPOSTISSET(
'qty-'.$line->id.
'-'.$i) ?
GETPOST(
'qty-'.$line->id.
'-'.$i) : max(0, $line->qty - $alreadyconsumed));
1355 if ($action ==
'consumeorproduce' && !GETPOSTISSET(
'qty-'.$line->id.
'-'.$i)) {
1360 if (
getDolGlobalString(
'MRP_NEVER_CONSUME_MORE_THAN_EXPECTED') && ($line->qty - $alreadyconsumed) <= 0) {
1361 $disable =
'disabled';
1365 print
'<input type="hidden" name="product-'.$line->id.
'-'.$i.
'" value="'.$line->fk_product.
'">';
1368 print
'<td class="right"><input type="text" class="width50 right" id="qtytoconsume-' . $line->id .
'-' . $i .
'" name="qty-' . $line->id .
'-' . $i .
'" value="' . $preselected .
'" ' . $disable .
'></td>';
1374 if ($permissiontoupdatecost &&
getDolGlobalString(
'MRP_SHOW_COST_FOR_CONSUMPTION')) {
1384 if (empty($line->disable_stock_change)) {
1385 $preselected = (GETPOSTISSET(
'idwarehouse-'.$line->id.
'-'.$i) ?
GETPOST(
'idwarehouse-'.$line->id.
'-'.$i) : ($tmpproduct->fk_default_warehouse > 0 ? $tmpproduct->fk_default_warehouse :
'ifone'));
1386 print $formproduct->selectWarehouses($preselected,
'idwarehouse-'.$line->id.
'-'.$i,
'', 1, 0, $line->fk_product,
'', 1, 0,
null,
'maxwidth200 csswarehouse_'.$line->id.
'_'.$i);
1388 print
'<span class="opacitymedium">'.$langs->trans(
"DisableStockChange").
'</span>';
1391 print
'<span class="opacitymedium">'.$langs->trans(
"NoStockChangeOnServices").
'</span>';
1396 if (isModEnabled(
'stock')) {
1401 if (isModEnabled(
'productbatch')) {
1402 print
'<td class="nowraponall">';
1403 if ($tmpproduct->status_batch) {
1404 $preselected = (GETPOSTISSET(
'batch-'.$line->id.
'-'.$i) ?
GETPOST(
'batch-'.$line->id.
'-'.$i) :
'');
1405 print
'<input type="text" class="width75" name="batch-'.$line->id.
'-'.$i.
'" value="'.$preselected.
'" list="batch-'.$line->id.
'-'.$i.
'">';
1406 print $formproduct->selectLotDataList(
'batch-'.$line->id.
'-'.$i, 0, $line->fk_product,
'',
'');
1413 print
'<td align="right" class="split">';
1414 print
' '.img_picto($langs->trans(
'AddStockLocationLine'),
'split.png',
'class="splitbutton" onClick="addDispatchLine('.((int) $line->id).
', \''.
dol_escape_js($type).
'\', \
'qtymissingconsume\')"');
1418 print
'<td align="right" class="splitall">';
1419 if (($action ==
'consumeorproduce' || $action ==
'consumeandproduceall') && $tmpproduct->status_batch == 2) {
1420 print
img_picto($langs->trans(
'SplitAllQuantity'),
'split.png',
'class="splitbutton splitallbutton field-error-icon" data-max-qty="1" onClick="addDispatchLine('.$line->id.
', \'batch\', \'allmissingconsume\')"');
1425 if (
$object->status == Mo::STATUS_DRAFT) {
1430 if ($permissiontodelete) {
1444 print
'<script type="text/javascript">
1445 $(document).ready(function () {
1446 $("select[name=fk_default_warehouse]").change(function() {
1447 var fk_default_warehouse = $("option:selected", this).val();
1448 $("select[name^=idwarehouse-]").val(fk_default_warehouse).change();
1453 if (in_array($action, array(
'consumeorproduce',
'consumeandproduceall')) &&
1455 print
'<script>$(document).ready(function () {
1456 $("#fk_default_warehouse").change();
1464 print
'<div class="fichehalfright">';
1465 print
'<div class="clearboth"></div>';
1467 $nblinetoproduce = 0;
1468 foreach (
$object->lines as $line) {
1469 if ($line->role ==
'toproduce') {
1474 $newcardbutton =
'';
1475 $url = $_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=addproduceline&token='.
newToken();
1476 $permissiontoaddaproductline =
$object->status != $object::STATUS_PRODUCED &&
$object->status != $object::STATUS_CANCELED;
1477 $parameters = array(
'morecss' =>
'reposition');
1478 if ($action !=
'consumeorproduce' && $action !=
'consumeandproduceall') {
1479 if ($nblinetoproduce == 0 ||
$object->mrptype == 1) {
1480 $newcardbutton =
dolGetButtonTitle($langs->trans(
'AddNewProduceLines'),
'',
'fa fa-plus-circle size15x', $url,
'', $permissiontoaddaproductline, $parameters);
1484 print
load_fiche_titre($langs->trans(
'Production'), $newcardbutton,
'', 0,
'',
'');
1486 print
'<div class="div-table-responsive-no-min">';
1487 print
'<table id="tablelinestoproduce" class="noborder noshadow nobottom centpercent">';
1489 print
'<tr class="liste_titre">';
1491 print
'<td>'.$langs->trans(
"Product").
'</td>';
1493 print
'<td class="right">'.$langs->trans(
"Qty").
'</td>';
1496 print
'<td class="right">'.$langs->trans(
"Unit").
'</td>';
1499 if ($permissiontoupdatecost) {
1500 if (empty($bomcostupdated)) {
1501 print
'<td class="right">'.$form->textwithpicto($langs->trans(
"UnitCost"), $langs->trans(
"AmountUsedToUpdateWAP")).
'</td>';
1503 print
'<td class="right">'.$form->textwithpicto($langs->trans(
"ManufacturingPrice"), $langs->trans(
"AmountUsedToUpdateWAP")).
'</td>';
1507 print
'<td class="right">'.$form->textwithpicto($langs->trans(
"QtyAlreadyProducedShort"), $langs->trans(
"QtyAlreadyProduced")).
'</td>';
1510 if ($collapse || in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
1511 print $langs->trans(
"Warehouse");
1516 if (isModEnabled(
'productbatch')) {
1518 if ($collapse || in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
1519 print $langs->trans(
"Batch");
1531 if ($permissiontodelete) {
1537 if ($action ==
'addproduceline') {
1538 print
'<!-- Add line to produce -->'.
"\n";
1539 print
'<tr class="liste_titre">';
1543 print $form->select_produits(
'',
'productidtoadd',
'', 0, 0, -1, 2,
'', 1, array(), 0,
'1', 0,
'maxwidth300');
1546 print
'<td class="right"><input type="text" name="qtytoadd" value="1" class="width50 right"></td>';
1552 if ($permissiontoupdatecost) {
1556 print
'<td colspan="2">';
1557 print
'<input type="submit" class="button buttongen button-add" name="addproducelinebutton" value="'.$langs->trans(
"Add").
'">';
1558 print
'<input type="submit" class="button buttongen button-cancel" name="canceladdproducelinebutton" value="'.$langs->trans(
"Cancel").
'">';
1561 if (isModEnabled(
'productbatch')) {
1571 if ($permissiontodelete) {
1578 $nblinetoproduce = 0;
1579 foreach (
$object->lines as $line) {
1580 if ($line->role ==
'toproduce') {
1585 $nblinetoproducecursor = 0;
1586 foreach (
$object->lines as $line) {
1587 if ($line->role ==
'toproduce') {
1590 $nblinetoproducecursor++;
1592 $tmpproduct =
new Product($db);
1593 $tmpproduct->fetch($line->fk_product);
1595 $arrayoflines =
$object->fetchLinesLinked(
'produced', $line->id);
1596 $alreadyproduced = 0;
1597 foreach ($arrayoflines as $line2) {
1598 $alreadyproduced += $line2[
'qty'];
1601 $suffix =
'_'.$line->id;
1602 print
'<!-- Line to dispatch '.$suffix.
' (toproduce) -->'.
"\n";
1604 print
'<input id="qty_ordered'.$suffix.
'" type="hidden" value="'.$line->qty.
'">';
1605 print
'<input id="qty_dispatched'.$suffix.
'" type="hidden" value="'.$alreadyproduced.
'">';
1609 print
'<td>'.$tmpproduct->getNomUrl(1);
1610 print
'<br><span class="opacitymedium small">'.$tmpproduct->label.
'</span>';
1613 print
'<td class="right">'.$line->qty.
'</td>';
1616 print
'<td class="right">'.measuringUnitString($line->fk_unit,
'',
'', 1).
'</td>';
1619 if ($permissiontoupdatecost) {
1621 $manufacturingcost = 0;
1622 $manufacturingcostsrc =
'';
1624 $manufacturingcost = $bomcostupdated;
1625 $manufacturingcostsrc = $langs->trans(
"CalculatedFromProductsToConsume");
1626 if (empty($manufacturingcost)) {
1627 $manufacturingcost = $bomcost;
1628 $manufacturingcostsrc = $langs->trans(
"ValueFromBom");
1630 if (empty($manufacturingcost)) {
1631 $manufacturingcost =
price2num($tmpproduct->cost_price,
'MU');
1632 $manufacturingcostsrc = $langs->trans(
"CostPrice");
1634 if (empty($manufacturingcost)) {
1635 $manufacturingcost =
price2num($tmpproduct->pmp,
'MU');
1636 $manufacturingcostsrc = $langs->trans(
"PMPValue");
1640 print
'<td class="right nowraponall" title="'.dol_escape_htmltag($manufacturingcostsrc).
'">';
1641 if ($manufacturingcost) {
1642 print
price($manufacturingcost);
1647 print
'<td class="right nowraponall">';
1648 if ($alreadyproduced) {
1650 print
'jQuery(document).ready(function() {
1651 jQuery("#expandtoproduce'.$line->id.
'").click(function() {
1652 console.log("Expand mrp_production line '.$line->id.
'");
1653 jQuery(".expanddetailtoproduce'.$line->id.
'").toggle();';
1654 if ($nblinetoproduce == $nblinetoproducecursor) {
1655 print
'if (jQuery("#tablelinestoproduce").hasClass("nobottom")) { jQuery("#tablelinestoproduce").removeClass("nobottom"); } else { jQuery("#tablelinestoproduce").addClass("nobottom"); }';
1661 if (empty($conf->use_javascript_ajax)) {
1662 print
'<a href="'.$_SERVER[
"PHP_SELF"].
'?collapse='.$collapse.
','.$line->id.
'">';
1664 print
img_picto($langs->trans(
"ShowDetails"),
"chevron-down",
'id="expandtoproduce'.$line->id.
'"');
1665 if (empty($conf->use_javascript_ajax)) {
1669 print
' '.$alreadyproduced;
1675 if (isModEnabled(
'productbatch')) {
1685 if ($permissiontodelete) {
1686 if ($line->origin_type ==
'free') {
1687 $href = $_SERVER[
"PHP_SELF"];
1688 $href .=
'?id='.$object->id;
1689 $href .=
'&action=deleteline';
1690 $href .=
'&token='.newToken();
1691 $href .=
'&lineid='.$line->id;
1692 print
'<td class="center">';
1693 print
'<a class="reposition" href="'.$href.
'">';
1694 print
img_picto($langs->trans(
'TooltipDeleteAndRevertStockMovement'),
"delete");
1704 foreach ($arrayoflines as $line2) {
1705 print
'<tr class="expanddetailtoproduce'.$line->id.
' hideobject opacitylow">';
1708 $tmpstockmovement->id = $line2[
'fk_stock_movement'];
1709 print
'<a href="'.DOL_URL_ROOT.
'/product/stock/movement_list.php?search_ref='.$tmpstockmovement->id.
'">'.
img_picto($langs->trans(
"StockMovement"),
'movement',
'class="paddingright"').
'</a>';
1719 if ($permissiontoupdatecost) {
1723 print
'<td class="right">'.$line2[
'qty'].
'</td>';
1725 print
'<td class="tdoverflowmax150">';
1726 if ($line2[
'fk_warehouse'] > 0) {
1727 $result = $tmpwarehouse->fetch($line2[
'fk_warehouse']);
1729 print $tmpwarehouse->getNomUrl(1);
1734 if (isModEnabled(
'productbatch')) {
1736 if ($line2[
'batch'] !=
'') {
1737 $tmpbatch->fetch(0, $line2[
'fk_product'], $line2[
'batch']);
1738 print $tmpbatch->getNomUrl(1);
1749 if ($permissiontodelete) {
1755 if (in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
1756 print
'<!-- Enter line to produce -->'.
"\n";
1758 print
'<tr data-max-qty="'.$maxQty.
'" name="batch_'.$line->id.
'_'.$i.
'">';
1760 print
'<td><span class="opacitymedium">'.$langs->trans(
"ToProduce").
'</span></td>';
1761 $preselected = (GETPOSTISSET(
'qtytoproduce-'.$line->id.
'-'.$i) ?
GETPOST(
'qtytoproduce-'.$line->id.
'-'.$i) : max(0, $line->qty - $alreadyproduced));
1762 if ($action ==
'consumeorproduce' && !GETPOSTISSET(
'qtytoproduce-'.$line->id.
'-'.$i)) {
1766 print
'<td class="right"><input type="text" class="width50 right" id="qtytoproduce-'.$line->id.
'-'.$i.
'" name="qtytoproduce-'.$line->id.
'-'.$i.
'" value="'.$preselected.
'"></td>';
1769 print
'<td class="right"></td>';
1772 if ($permissiontoupdatecost) {
1774 $manufacturingcost = 0;
1775 $manufacturingcostsrc =
'';
1777 $manufacturingcost = $bomcostupdated;
1778 $manufacturingcostsrc = $langs->trans(
"CalculatedFromProductsToConsume");
1779 if (empty($manufacturingcost)) {
1780 $manufacturingcost = $bomcost;
1781 $manufacturingcostsrc = $langs->trans(
"ValueFromBom");
1783 if (empty($manufacturingcost)) {
1784 $manufacturingcost =
price2num($tmpproduct->cost_price,
'MU');
1785 $manufacturingcostsrc = $langs->trans(
"CostPrice");
1787 if (empty($manufacturingcost)) {
1788 $manufacturingcost =
price2num($tmpproduct->pmp,
'MU');
1789 $manufacturingcostsrc = $langs->trans(
"PMPValue");
1794 $preselected = (GETPOSTISSET(
'pricetoproduce-'.$line->id.
'-'.$i) ?
GETPOST(
'pricetoproduce-'.$line->id.
'-'.$i) : ($manufacturingcost ?
price($manufacturingcost) :
''));
1795 print
'<td class="right"><input type="text" class="width75 right" name="pricetoproduce-'.$line->id.
'-'.$i.
'" value="'.$preselected.
'"></td>';
1797 print
'<td><input type="hidden" class="width50 right" name="pricetoproduce-'.$line->id.
'-'.$i.
'" value="'.($manufacturingcost ? $manufacturingcost :
'').
'"></td>';
1805 $preselected = (GETPOSTISSET(
'idwarehousetoproduce-'.$line->id.
'-'.$i) ?
GETPOST(
'idwarehousetoproduce-'.$line->id.
'-'.$i) : (
$object->fk_warehouse > 0 ?
$object->fk_warehouse :
'ifone'));
1806 print $formproduct->selectWarehouses($preselected,
'idwarehousetoproduce-'.$line->id.
'-'.$i,
'', 1, 0, $line->fk_product,
'', 1, 0,
null,
'maxwidth200 csswarehouse_'.$line->id.
'_'.$i);
1808 print
'<span class="opacitymedium">'.$langs->trans(
"NoStockChangeOnServices").
'</span>';
1812 if (isModEnabled(
'productbatch')) {
1814 if ($tmpproduct->status_batch) {
1815 $preselected = (GETPOSTISSET(
'batchtoproduce-'.$line->id.
'-'.$i) ?
GETPOST(
'batchtoproduce-'.$line->id.
'-'.$i) :
'');
1816 print
'<input type="text" class="width75" name="batchtoproduce-'.$line->id.
'-'.$i.
'" value="'.$preselected.
'">';
1820 if ($tmpproduct->status_batch) {
1822 print
'<td align="right" class="split">';
1823 print
img_picto($langs->trans(
'AddStockLocationLine'),
'split.png',
'class="splitbutton" onClick="addDispatchLine('.$line->id.
', \''.$type.
'\', \
'qtymissing\')"');
1826 print
'<td align="right" class="splitall">';
1827 if (($action ==
'consumeorproduce' || $action ==
'consumeandproduceall') && $tmpproduct->status_batch == 2) {
1828 print
img_picto($langs->trans(
'SplitAllQuantity'),
'split.png',
'class="splitbutton splitallbutton field-error-icon" onClick="addDispatchLine('.$line->id.
', \'batch\', \'alltoproduce\')"');
1854 if (in_array($action, array(
'consumeorproduce',
'consumeandproduceall',
'addconsumeline'))) {
1858 <script
type=
"text/javascript" language=
"javascript">
1860 $(document).ready(
function() {
1862 updateselectbatchbywarehouse();
1864 updateselectwarehousebybatch();
1867 function updateselectbatchbywarehouse() {
1868 $(document).on(
'change',
"select[name*='idwarehouse']",
function () {
1869 console.log(
"We change warehouse so we update the list of possible batch number");
1871 var selectwarehouse = $(
this);
1873 var selectbatch_name = selectwarehouse.attr(
'name').replace(
'idwarehouse',
'batch');
1874 var selectbatch = $(
"datalist[id*='" + selectbatch_name +
"']");
1875 var selectedbatch = selectbatch.val();
1877 var product_element_name = selectwarehouse.attr(
'name').replace(
'idwarehouse',
'product');
1881 url:
"<?php echo DOL_URL_ROOT . '/mrp/ajax/interface.php'; ?>",
1883 action:
"updateselectbatchbywarehouse",
1884 permissiontoproduce: <?php echo $permissiontoproduce ?>,
1885 warehouse_id: $(
this).val(),
1886 token:
'<?php echo currentToken(); ?>',
1887 product_id: $(
"input[name='" + product_element_name +
"']").val()
1889 }).done(
function (data) {
1891 selectbatch.empty();
1893 if (typeof data ==
"object") {
1894 console.log(
"data is already type object, no need to parse it");
1896 console.log(
"data is type "+(typeof data));
1897 data = JSON.parse(data);
1900 selectbatch.append($(
'<option>', {
1904 $.each(data,
function (key, value) {
1906 if(selectwarehouse.val() == -1) {
1907 var label = key +
" (<?php echo $langs->trans('Stock total') ?> : " + value +
")";
1909 var label = key +
" (<?php echo $langs->trans('Stock') ?> : " + value +
")";
1912 if(key === selectedbatch) {
1913 var option =
'<option value="'+key+
'" selected>'+ label +
'</option>';
1915 var option =
'<option value="'+key+
'">'+ label +
'</option>';
1918 selectbatch.append(option);
1924 function updateselectwarehousebybatch() {
1925 $(document).on(
'change',
'input[name*=batch]',
function(){
1926 console.log(
"We change batch so we update the list of possible warehouses");
1928 var selectbatch = $(
this);
1930 var selectwarehouse_name = selectbatch.attr(
'name').replace(
'batch',
'idwarehouse');
1931 var selectwarehouse = $(
"select[name*='" + selectwarehouse_name +
"']");
1932 var selectedwarehouse = selectwarehouse.val();
1934 if(selectedwarehouse != -1){
1938 var product_element_name = selectbatch.attr(
'name').replace(
'batch',
'product');
1942 url:
"<?php echo DOL_URL_ROOT . '/mrp/ajax/interface.php'; ?>",
1944 action:
"updateselectwarehousebybatch",
1945 permissiontoproduce: <?php echo $permissiontoproduce ?>,
1946 batch: $(
this).val(),
1947 token:
'<?php echo currentToken(); ?>',
1948 product_id: $(
"input[name='" + product_element_name +
"']").val()
1950 }).done(
function (data) {
1952 if (typeof data ==
"object") {
1953 console.log(
"data is already type object, no need to parse it");
1955 console.log(
"data is type "+(typeof data));
1956 data = JSON.parse(data);
1960 selectwarehouse.val(data).change();
if( $user->socid > 0) if(! $user->hasRight('accounting', 'chartofaccount')) $object
if(!defined('NOREQUIRESOC')) if(!defined( 'NOREQUIRETRAN')) if(!defined('NOTOKENRENEWAL')) if(!defined( 'NOREQUIREMENU')) if(!defined('NOREQUIREHTML')) if(!defined( 'NOREQUIREAJAX')) llxHeader()
Empty header.
Class to manage warehouses.
Class to manage stock movements.
Class to manage predefined suppliers products.
Class to manage products or services.
const TYPE_PRODUCT
Regular product.
const TYPE_SERVICE
Service.
Class with list of lots and properties.
Class to manage projects.
Class to manage translations.
convertDurationtoHour($duration_value, $duration_unit)
Convert duration to hour.
load_fiche_titre($title, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
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.
yn($yesno, $case=1, $color=0)
Return yes or no in current language.
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.
price2num($amount, $rounding='', $option=0)
Function that return a number with universal decimal format (decimal separator is '.
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.
price($amount, $form=0, $outlangs='', $trunc=1, $rounding=-1, $forcerounding=-1, $currency_code='')
Function to format a value into an amount for visual output Function used into PDF and HTML pages.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return a Dolibarr global constant int value.
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into javascript code.
dol_print_date($time, $format='', $tzoutput='auto', $outputlangs=null, $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
newToken()
Return the value of token currently saved into session with name 'newtoken'.
GETPOST($paramname, $check='alphanohtml', $method=0, $filter=null, $options=null, $noreplace=0)
Return value of a param into GET or POST supervariable.
GETPOSTFLOAT($paramname, $rounding='')
Return the value of a $_GET or $_POST supervariable, converted into float.
setEventMessages($mesg, $mesgs, $style='mesgs', $messagekey='', $noduplicate=0)
Set event messages in dol_events session object.
getDolGlobalString($key, $default='')
Return dolibarr global constant string value.
img_edit($titlealt='default', $float=0, $other='')
Show logo edit/modify fiche.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
dol_escape_htmltag($stringtoescape, $keepb=0, $keepn=0, $noescapetags='', $escapeonlyhtmltags=0, $cleanalsojavascript=0)
Returns text escaped for inclusion in HTML alt or title or value tags, or into values of HTML input f...
moPrepareHead($object)
Prepare array of tabs for Mo.
measuringUnitString($unit, $measuring_style='', $scale='', $use_short_label=0, $outputlangs=null)
Return translation label of a unit key.
if(preg_match('/crypted:/i', $dolibarr_main_db_pass)||!empty($dolibarr_main_db_encrypted_pass)) $conf db type
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.