29require
'../main.inc.php';
30require_once DOL_DOCUMENT_ROOT.
'/bom/class/bom.class.php';
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.
'/mrp/class/mo.class.php';
35require_once DOL_DOCUMENT_ROOT.
'/mrp/lib/mrp_mo.lib.php';
36require_once DOL_DOCUMENT_ROOT.
'/projet/class/project.class.php';
37require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
38require_once DOL_DOCUMENT_ROOT.
'/product/class/html.formproduct.class.php';
39require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/entrepot.class.php';
40require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/productlot.class.php';
41require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
42require_once DOL_DOCUMENT_ROOT.
'/workstation/class/workstation.class.php';
46$langs->loadLangs(array(
"mrp",
"stocks",
"other",
"product",
"productbatch"));
51$action =
GETPOST(
'action',
'aZ09');
52$confirm =
GETPOST(
'confirm',
'alpha');
53$cancel =
GETPOST(
'cancel',
'aZ09');
54$contextpage =
GETPOST(
'contextpage',
'aZ') ?
GETPOST(
'contextpage',
'aZ') :
'mocard';
55$backtopage =
GETPOST(
'backtopage',
'alpha');
58$fk_default_warehouse =
GETPOSTINT(
'fk_default_warehouse');
60$collapse =
GETPOST(
'collapse',
'aZ09comma');
65$diroutputmassaction = $conf->mrp->dir_output.
'/temp/massgeneration/'.$user->id;
66$objectline =
new MoLine($db);
68$hookmanager->initHooks(array(
'moproduction',
'globalcard'));
71$extrafields->fetch_name_optionals_label(
$object->table_element);
73$search_array_options = $extrafields->getOptionalsFromPost(
$object->table_element,
'',
'search_');
76$search_all =
GETPOST(
"search_all",
'alpha');
78foreach (
$object->fields as $key => $val) {
79 if (
GETPOST(
'search_'.$key,
'alpha')) {
80 $search[$key] =
GETPOST(
'search_'.$key,
'alpha');
84if (empty($action) && empty($id) && empty($ref)) {
89include DOL_DOCUMENT_ROOT.
'/core/actions_fetchobject.inc.php';
94$isdraft = ((
$object->status == $object::STATUS_DRAFT) ? 1 : 0);
98$permissionnote = $user->hasRight(
'mrp',
'write');
99$permissiondellink = $user->hasRight(
'mrp',
'write');
100$permissiontoadd = $user->hasRight(
'mrp',
'write');
101$permissiontodelete = $user->hasRight(
'mrp',
'delete') || ($permissiontoadd && isset(
$object->status) &&
$object->status == $object::STATUS_DRAFT);
103$permissiontoproduce = $permissiontoadd;
104$permissiontoupdatecost = $user->hasRight(
'bom',
'read');
106$upload_dir = $conf->mrp->multidir_output[isset(
$object->entity) ?
$object->entity : 1];
113$parameters = array();
114$reshook = $hookmanager->executeHooks(
'doActions', $parameters, $object, $action);
119if (empty($reshook)) {
122 $backurlforlist = DOL_URL_ROOT.
'/mrp/mo_list.php';
124 if (empty($backtopage) || ($cancel && empty($id))) {
126 if (empty($id) && (($action !=
'add' && $action !=
'create') || $cancel)) {
127 $backtopage = $backurlforlist;
129 $backtopage = DOL_URL_ROOT.
'/mrp/mo_production.php?id='.($id > 0 ? $id :
'__ID__');
132 $triggermodname =
'MO_MODIFY';
134 if ($action ==
'confirm_cancel' && $confirm ==
'yes' && !empty($permissiontoadd)) {
135 $also_cancel_consumed_and_produced_lines = (
GETPOST(
'alsoCancelConsumedAndProducedLines',
'alpha') ? 1 : 0);
136 $result =
$object->cancel($user, 0, $also_cancel_consumed_and_produced_lines);
138 header(
"Location: " . DOL_URL_ROOT.
'/mrp/mo_card.php?id=' .
$object->id);
144 } elseif ($action ==
'confirm_delete' && $confirm ==
'yes' && !empty($permissiontodelete)) {
145 $also_cancel_consumed_and_produced_lines = (
GETPOST(
'alsoCancelConsumedAndProducedLines',
'alpha') ? 1 : 0);
146 $result =
$object->delete($user, 0, $also_cancel_consumed_and_produced_lines);
148 header(
"Location: " . $backurlforlist);
157 include DOL_DOCUMENT_ROOT.
'/core/actions_addupdatedelete.inc.php';
160 include DOL_DOCUMENT_ROOT.
'/core/actions_dellink.inc.php';
163 include DOL_DOCUMENT_ROOT.
'/core/actions_printing.inc.php';
166 $triggersendname =
'MO_SENTBYMAIL';
167 $autocopy =
'MAIN_MAIL_AUTOCOPY_MO_TO';
168 $trackid =
'mo'.$object->id;
169 include DOL_DOCUMENT_ROOT.
'/core/actions_sendmails.inc.php';
174 if ($action ==
'set_thirdparty' && $permissiontoadd) {
175 $object->setValueFrom(
'fk_soc',
GETPOSTINT(
'fk_soc'),
'',
'',
'date',
'', $user, $triggermodname);
177 if ($action ==
'classin' && $permissiontoadd) {
181 if ($action ==
'confirm_reopen' && $permissiontoadd) {
182 $result =
$object->setStatut($object::STATUS_INPROGRESS, 0,
'',
'MRP_REOPEN');
185 if (($action ==
'confirm_addconsumeline' &&
GETPOST(
'addconsumelinebutton') && $permissiontoadd)
186 || ($action ==
'confirm_addproduceline' &&
GETPOST(
'addproducelinebutton') && $permissiontoadd)) {
187 $moline =
new MoLine($db);
192 $moline->fk_product =
GETPOSTINT(
'productidtoadd');
193 if (
GETPOST(
'addconsumelinebutton')) {
194 $moline->role =
'toconsume';
196 $moline->role =
'toproduce';
198 $moline->origin_type =
'free';
199 $moline->position = 0;
202 if (!empty($moline->fk_product)) {
203 $tmpproduct =
new Product($db);
204 $tmpproduct->fetch($moline->fk_product);
206 $moline->fk_default_workstation = $tmpproduct->fk_default_workstation;
210 $moline->fk_unit = $tmpproduct->fk_unit;
214 $extralabelsline = $extrafields->fetch_name_optionals_label(
$object->table_element_line);
215 $array_options = $extrafields->getOptionalsFromPost(
$object->table_element_line);
217 if (is_array($extralabelsline)) {
219 foreach ($extralabelsline as $key => $value) {
220 unset($_POST[
"options_".$key]);
223 if (is_array($array_options) && count($array_options) > 0) {
224 $moline->array_options = $array_options;
227 $resultline = $moline->create($user,
false);
228 if ($resultline <= 0) {
235 header(
"Location: ".$_SERVER[
"PHP_SELF"].
'?id='.
$object->id);
239 if (in_array($action, array(
'confirm_consumeorproduce',
'confirm_consumeandproduceall')) && $permissiontoproduce) {
242 $labelmovement =
GETPOST(
'inventorylabel',
'alphanohtml');
243 $codemovement =
GETPOST(
'inventorycode',
'alphanohtml');
248 foreach (
$object->lines as $line) {
249 if ($line->role ==
'toconsume') {
250 $tmpproduct =
new Product($db);
251 $tmpproduct->fetch($line->fk_product);
254 while (GETPOSTISSET(
'qty-'.$line->id.
'-'.$i)) {
257 if ($qtytoprocess != 0) {
259 if (GETPOSTISSET(
'idwarehouse-'.$line->id.
'-'.$i)) {
260 if (!(
GETPOST(
'idwarehouse-'.$line->id.
'-'.$i) > 0)) {
261 $langs->load(
"errors");
262 setEventMessages($langs->trans(
"ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv(
"Warehouse"), $tmpproduct->ref),
null,
'errors');
265 if ($tmpproduct->status_batch && (!
GETPOST(
'batch-'.$line->id.
'-'.$i))) {
266 $langs->load(
"errors");
267 setEventMessages($langs->trans(
"ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv(
"Batch"), $tmpproduct->ref),
null,
'errors');
273 if (!$error &&
GETPOST(
'idwarehouse-'.$line->id.
'-'.$i) > 0) {
275 $id_product_batch = 0;
277 $stockmove->context[
'mrp_role'] =
'toconsume';
279 if ($qtytoprocess >= 0) {
280 $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);
282 $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);
284 if ($idstockmove < 0) {
292 $moline =
new MoLine($db);
294 $moline->position = $pos;
295 $moline->fk_product = $line->fk_product;
296 $moline->fk_warehouse =
GETPOST(
'idwarehouse-'.$line->id.
'-'.$i);
297 $moline->qty = $qtytoprocess;
298 $moline->batch =
GETPOST(
'batch-'.$line->id.
'-'.$i);
299 $moline->role =
'consumed';
300 $moline->fk_mrp_production = $line->id;
301 $moline->fk_stock_movement = $idstockmove == 0 ? null : $idstockmove;
302 $moline->fk_user_creat = $user->id;
304 $resultmoline = $moline->create($user);
305 if ($resultmoline <= 0) {
322 foreach (
$object->lines as $line) {
323 if ($line->role ==
'toproduce') {
324 $tmpproduct =
new Product($db);
325 $tmpproduct->fetch($line->fk_product);
328 while (GETPOSTISSET(
'qtytoproduce-'.$line->id.
'-'.$i)) {
329 $qtytoprocess = (float)
price2num(
GETPOST(
'qtytoproduce-'.$line->id.
'-'.$i));
330 $pricetoprocess =
GETPOST(
'pricetoproduce-'.$line->id.
'-'.$i) ?
price2num(
GETPOST(
'pricetoproduce-'.$line->id.
'-'.$i)) : 0;
332 if ($qtytoprocess != 0) {
334 if (GETPOSTISSET(
'idwarehousetoproduce-'.$line->id.
'-'.$i)) {
335 if (!(
GETPOST(
'idwarehousetoproduce-'.$line->id.
'-'.$i) > 0)) {
336 $langs->load(
"errors");
337 setEventMessages($langs->trans(
"ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv(
"Warehouse"), $tmpproduct->ref),
null,
'errors');
340 if (isModEnabled(
'productbatch') && $tmpproduct->status_batch && (!
GETPOST(
'batchtoproduce-'.$line->id.
'-'.$i))) {
341 $langs->load(
"errors");
342 setEventMessages($langs->trans(
"ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv(
"Batch"), $tmpproduct->ref),
null,
'errors');
348 if (!$error &&
GETPOST(
'idwarehousetoproduce-'.$line->id.
'-'.$i) > 0) {
350 $id_product_batch = 0;
351 $stockmove->origin_type =
$object->element;
352 $stockmove->origin_id =
$object->id;
353 $stockmove->context[
'mrp_role'] =
'toproduce';
355 $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);
356 if ($idstockmove < 0) {
364 $moline =
new MoLine($db);
366 $moline->position = $pos;
367 $moline->fk_product = $line->fk_product;
368 $moline->fk_warehouse =
GETPOST(
'idwarehousetoproduce-'.$line->id.
'-'.$i);
369 $moline->qty = $qtytoprocess;
370 $moline->batch =
GETPOST(
'batchtoproduce-'.$line->id.
'-'.$i);
371 $moline->role =
'produced';
372 $moline->fk_mrp_production = $line->id;
373 $moline->fk_stock_movement = $idstockmove;
374 $moline->fk_user_creat = $user->id;
376 $resultmoline = $moline->create($user);
377 if ($resultmoline <= 0) {
392 $consumptioncomplete =
true;
393 $productioncomplete =
true;
396 foreach (
$object->lines as $line) {
397 if ($line->role ==
'toconsume') {
398 $arrayoflines =
$object->fetchLinesLinked(
'consumed', $line->id);
399 $alreadyconsumed = 0;
400 foreach ($arrayoflines as $line2) {
401 $alreadyconsumed += $line2[
'qty'];
404 if ($alreadyconsumed < $line->qty) {
405 $consumptioncomplete =
false;
408 if ($line->role ==
'toproduce') {
409 $arrayoflines =
$object->fetchLinesLinked(
'produced', $line->id);
410 $alreadyproduced = 0;
411 foreach ($arrayoflines as $line2) {
412 $alreadyproduced += $line2[
'qty'];
415 if ($alreadyproduced < $line->qty) {
416 $productioncomplete =
false;
421 $consumptioncomplete =
false;
422 $productioncomplete =
false;
426 dol_syslog(
"consumptioncomplete = ".json_encode($consumptioncomplete).
" productioncomplete = ".json_encode($productioncomplete));
427 if ($consumptioncomplete && $productioncomplete) {
428 $result =
$object->setStatut($object::STATUS_PRODUCED, 0,
'',
'MRP_MO_PRODUCED');
430 $result =
$object->setStatut($object::STATUS_INPROGRESS, 0,
'',
'MRP_MO_PRODUCED');
439 $action = str_replace(
'confirm_',
'', $action);
445 header(
"Location: ".$_SERVER[
"PHP_SELF"].
'?id='.
$object->id);
451 if ($action ==
'confirm_produced' && $confirm ==
'yes' && $permissiontoadd) {
452 $result =
$object->setStatut($object::STATUS_PRODUCED, 0,
'',
'MRP_MO_PRODUCED');
456 $outputlangs = $langs;
459 $newlang =
GETPOST(
'lang_id',
'aZ09');
462 $newlang =
$object->thirdparty->default_lang;
464 if (!empty($newlang)) {
466 $outputlangs->setDefaultLang($newlang);
471 $object->generateDocument($model, $outputlangs, 0, 0, 0);
478 if ($action ==
'confirm_editline' && $permissiontoadd) {
479 $moline =
new MoLine($db);
482 $extrafields->fetch_name_optionals_label($moline->element);
483 foreach ($extrafields->attributes[$moline->table_element][
'label'] as $key => $label) {
484 $value =
GETPOST(
'options_'.$key,
'alphanohtml');
485 $moline->array_options[
"options_".$key] = $value;
488 $res = $moline->update($user);
491 header(
"Location: ".$_SERVER[
"PHP_SELF"].
'?id='.
$object->id);
494 header(
"Location: ".$_SERVER[
"PHP_SELF"].
'?id='.
$object->id);
506$form =
new Form($db);
513$help_url =
'EN:Module_Manufacturing_Orders|FR:Module_Ordres_de_Fabrication|DE:Modul_Fertigungsauftrag';
514$morejs = array(
'/mrp/js/lib_dispatch.js.php');
515llxHeader(
'', $langs->trans(
'Mo'), $help_url,
'', 0, 0, $morejs);
520if (
$object->id > 0 && (empty($action) || ($action !=
'edit' && $action !=
'create'))) {
521 $res =
$object->fetch_thirdparty();
522 $res =
$object->fetch_optionals();
525 $tmpwarehouse->fetch(
$object->fk_warehouse);
526 $fk_default_warehouse =
$object->fk_warehouse;
536 if ($action ==
'delete') {
537 $formquestion = array(
539 'label' => $langs->trans(
'MoCancelConsumedAndProducedLines'),
540 'name' =>
'alsoCancelConsumedAndProducedLines',
541 'type' =>
'checkbox',
545 $formconfirm = $form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.
$object->id, $langs->trans(
'DeleteMo'), $langs->trans(
'ConfirmDeleteMo'),
'confirm_delete', $formquestion, 0, 1);
548 if ($action ==
'deleteline') {
549 $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);
552 if ($action ==
'clone') {
554 $formquestion = array();
555 $formconfirm = $form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.
$object->id, $langs->trans(
'ToClone'), $langs->trans(
'ConfirmCloneMo',
$object->ref),
'confirm_clone', $formquestion,
'yes', 1);
559 if ($action ==
'validate') {
561 $ref = substr(
$object->ref, 1, 4);
562 if ($ref ==
'PROV') {
569 $text = $langs->trans(
'ConfirmValidateMo', $numref);
578 $formquestion = array();
579 if (isModEnabled(
'mrp')) {
581 require_once DOL_DOCUMENT_ROOT.
'/product/class/html.formproduct.class.php';
584 if ($conf->browser->name ==
'ie') {
587 $formquestion = array(
594 $formconfirm = $form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.
$object->id, $langs->trans(
'Validate'), $text,
'confirm_validate', $formquestion, 0, 1, 220);
598 if ($action ==
'cancel') {
599 $formquestion = array(
601 'label' => $langs->trans(
'MoCancelConsumedAndProducedLines'),
602 'name' =>
'alsoCancelConsumedAndProducedLines',
603 'type' =>
'checkbox',
604 'value' => !
getDolGlobalString(
'MO_ALSO_CANCEL_CONSUMED_AND_PRODUCED_LINES_BY_DEFAULT') ? 0 : 1
607 $formconfirm = $form->formconfirm($_SERVER[
"PHP_SELF"] .
'?id=' .
$object->id, $langs->trans(
'CancelMo'), $langs->trans(
'ConfirmCancelMo'),
'confirm_cancel', $formquestion, 0, 1);
611 $parameters = array(
'formConfirm' => $formconfirm,
'lineid' => $lineid);
612 $reshook = $hookmanager->executeHooks(
'formConfirm', $parameters, $object, $action);
613 if (empty($reshook)) {
614 $formconfirm .= $hookmanager->resPrint;
615 } elseif ($reshook > 0) {
616 $formconfirm = $hookmanager->resPrint;
625 $linkback =
'<a href="'.DOL_URL_ROOT.
'/mrp/mo_list.php?restore_lastsearch_values=1'.(!empty($socid) ?
'&socid='.$socid :
'').
'">'.$langs->trans(
"BackToList").
'</a>';
627 $morehtmlref =
'<div class="refidno">';
636 if (is_object(
$object->thirdparty)) {
637 $morehtmlref .=
$object->thirdparty->getNomUrl(1,
'customer');
639 $morehtmlref .=
' (<a href="'.DOL_URL_ROOT.
'/commande/list.php?socid='.
$object->thirdparty->id.
'&search_societe='.urlencode(
$object->thirdparty->name).
'">'.$langs->trans(
"OtherOrders").
'</a>)';
644 if (isModEnabled(
'project')) {
645 $langs->load(
"projects");
646 if (is_object(
$object->thirdparty)) {
647 $morehtmlref .=
'<br>';
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> ';
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');
656 if (!empty(
$object->fk_project)) {
658 $proj->fetch(
$object->fk_project);
659 $morehtmlref .= $proj->getNomUrl(1);
661 $morehtmlref .=
'<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).
'</span>';
666 $morehtmlref .=
'</div>';
669 dol_banner_tab($object,
'ref', $linkback, 1,
'ref',
'ref', $morehtmlref);
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";
678 $keyforbreak =
'fk_warehouse';
679 unset(
$object->fields[
'fk_project']);
680 unset(
$object->fields[
'fk_soc']);
681 include DOL_DOCUMENT_ROOT.
'/core/tpl/commonfields_view.tpl.php';
684 include DOL_DOCUMENT_ROOT.
'/core/tpl/extrafields_view.tpl.php';
690 print
'<div class="clearboth"></div>';
695 if (!in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
696 print
'<div class="tabsAction">';
698 $parameters = array();
700 $reshook = $hookmanager->executeHooks(
'addMoreActionsButtons', $parameters, $object, $action);
701 if (empty($reshook)) {
703 if (
$object->status == $object::STATUS_DRAFT) {
704 if ($permissiontoadd) {
706 print
'<a class="butAction" href="'.$_SERVER[
'PHP_SELF'].
'?id='.
$object->id.
'&action=validate&token='.$newToken.
'">'.$langs->trans(
"Validate").
'</a>';
708 $langs->load(
"errors");
709 print
'<a class="butActionRefused" href="" title="'.$langs->trans(
"ErrorAddAtLeastOneLineFirst").
'">'.$langs->trans(
"Validate").
'</a>';
715 if (
$object->status == Mo::STATUS_VALIDATED ||
$object->status == Mo::STATUS_INPROGRESS) {
716 if ($permissiontoproduce) {
717 print
'<a class="butAction" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=consumeorproduce&token='.$newToken.
'">'.$langs->trans(
'ConsumeOrProduce').
'</a>';
719 print
'<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans(
"NotEnoughPermissions").
'">'.$langs->trans(
'ConsumeOrProduce').
'</a>';
721 } elseif (
$object->status == Mo::STATUS_DRAFT) {
722 print
'<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans(
"ValidateBefore").
'">'.$langs->trans(
'ConsumeOrProduce').
'</a>';
726 if (
$object->status == Mo::STATUS_VALIDATED ||
$object->status == Mo::STATUS_INPROGRESS) {
727 if ($permissiontoproduce) {
728 print
'<a class="butAction" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=consumeandproduceall&token='.$newToken.
'">'.$langs->trans(
'ConsumeAndProduceAll').
'</a>';
730 print
'<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans(
"NotEnoughPermissions").
'">'.$langs->trans(
'ConsumeAndProduceAll').
'</a>';
732 } elseif (
$object->status == Mo::STATUS_DRAFT) {
733 print
'<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans(
"ValidateBefore").
'">'.$langs->trans(
'ConsumeAndProduceAll').
'</a>';
737 if ($permissiontoadd) {
738 if (
$object->status == $object::STATUS_VALIDATED ||
$object->status == $object::STATUS_INPROGRESS) {
739 $arrayproduced =
$object->fetchLinesLinked(
'produced', 0);
741 foreach ($arrayproduced as $lineproduced) {
742 $nbProduced += $lineproduced[
'qty'];
744 if ($nbProduced > 0) {
745 print
'<a class="butAction" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=confirm_produced&confirm=yes&token='.$newToken.
'">'.$langs->trans(
"Close").
'</a>'.
"\n";
747 print
'<a class="butActionRefused" href="#" title="'.$langs->trans(
"GoOnTabProductionToProduceFirst", $langs->transnoentitiesnoconv(
"Production")).
'">'.$langs->trans(
"Close").
'</a>'.
"\n";
750 print
'<a class="butActionDelete" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=cancel&token='.$newToken.
'">'.$langs->trans(
"Cancel").
'</a>'.
"\n";
753 if (
$object->status == $object::STATUS_CANCELED) {
754 print
'<a class="butAction" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=confirm_reopen&confirm=yes&token='.$newToken.
'">'.$langs->trans(
"ReOpen").
'</a>'.
"\n";
757 if (
$object->status == $object::STATUS_PRODUCED) {
758 if ($permissiontoproduce) {
759 print
'<a class="butAction" href="'.$_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=confirm_reopen&token='.$newToken.
'">'.$langs->trans(
'ReOpen').
'</a>';
761 print
'<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans(
"NotEnoughPermissions").
'">'.$langs->trans(
'ReOpen').
'</a>';
770 if (in_array($action, array(
'consumeorproduce',
'consumeandproduceall',
'addconsumeline',
'addproduceline',
'editline'))) {
771 print
'<form method="POST" action="'.$_SERVER[
"PHP_SELF"].
'">';
772 print
'<input type="hidden" name="token" value="'.newToken().
'">';
773 print
'<input type="hidden" name="action" value="confirm_'.$action.
'">';
774 print
'<input type="hidden" name="backtopage" value="'.$backtopage.
'">';
775 print
'<input type="hidden" name="id" value="'.$id.
'">';
778 if (in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
779 $defaultstockmovementlabel =
GETPOST(
'inventorylabel',
'alphanohtml') ?
GETPOST(
'inventorylabel',
'alphanohtml') : $langs->trans(
"ProductionForRef",
$object->
ref);
782 print
'<div class="center'.(in_array($action, array(
'consumeorproduce',
'consumeandproduceall')) ?
' formconsumeproduce' :
'').
'">';
783 print
'<div class="opacitymedium hideonsmartphone paddingbottom">'.$langs->trans(
"ConfirmProductionDesc", $langs->transnoentitiesnoconv(
"Confirm")).
'<br></div>';
784 print
'<span class="fieldrequired">'.$langs->trans(
"InventoryCode").
':</span> <input type="text" class="minwidth150 maxwidth200" name="inventorycode" value="'.$defaultstockmovementcode.
'"> ';
785 print
'<span class="clearbothonsmartphone"></span>';
786 print $langs->trans(
"MovementLabel").
': <input type="text" class="minwidth300" name="inventorylabel" value="'.$defaultstockmovementlabel.
'"><br><br>';
787 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>';
788 print
'<input type="submit" class="button" value="'.$langs->trans(
"Confirm").
'" name="confirm">';
790 print
'<input class="button button-cancel" type="submit" value="'.$langs->trans(
"Cancel").
'" name="cancel">';
804 if (!empty(
$object->table_element_line)) {
811 $res = $bom->fetch(
$object->fk_bom);
813 $bom->calculateCosts();
814 $bomcost = $bom->unit_cost;
820 print
'<div class="fichecenter">';
821 print
'<div class="fichehalfleft">';
822 print
'<div class="clearboth"></div>';
824 $url = $_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=addconsumeline&token='.
newToken();
825 $permissiontoaddaconsumeline =
$object->status != $object::STATUS_PRODUCED &&
$object->status != $object::STATUS_CANCELED;
826 $parameters = array(
'morecss' =>
'reposition');
829 if ($action !=
'consumeorproduce' && $action !=
'consumeandproduceall') {
830 $newcardbutton =
dolGetButtonTitle($langs->trans(
'AddNewConsumeLines'),
'',
'fa fa-plus-circle size15x', $url,
'', $permissiontoaddaconsumeline, $parameters);
833 print
load_fiche_titre($langs->trans(
'Consumption'), $newcardbutton,
'', 0,
'',
'',
'');
835 print
'<div class="div-table-responsive-no-min">';
836 print
'<table class="noborder noshadow centpercent nobottom">';
838 print
'<!-- Line of title for products to consume -->'.
"\n";
839 print
'<tr class="liste_titre">';
841 print
'<td>'.$langs->trans(
"Product").
'</td>';
843 print
'<td class="right">'.$langs->trans(
"Qty").
'</td>';
848 print
'<td class="right">'.$langs->trans(
"UnitCost").
'</td>';
851 print
'<td class="right">'.$form->textwithpicto($langs->trans(
"QtyAlreadyConsumedShort"), $langs->trans(
"QtyAlreadyConsumed")).
'</td>';
854 if ($collapse || in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
855 print $langs->trans(
"Warehouse");
856 if (isModEnabled(
'workstation')) {
857 print
' '.$langs->trans(
"or").
' '.$langs->trans(
"Workstation");
860 if (in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
861 $listwarehouses = $tmpwarehouse->list_array(1);
862 if (count($listwarehouses) > 1) {
863 print
'<br>'.$form->selectarray(
'fk_default_warehouse', $listwarehouses, $fk_default_warehouse, $langs->trans(
"ForceTo"), 0, 0,
'', 0, 0, 0,
'',
'minwidth100 maxwidth200', 1);
864 } elseif (count($listwarehouses) == 1) {
865 print
'<br>'.$form->selectarray(
'fk_default_warehouse', $listwarehouses, $fk_default_warehouse, 0, 0, 0,
'', 0, 0, 0,
'',
'minwidth100 maxwidth200', 1);
871 if (isModEnabled(
'stock')) {
873 print
'<td align="right">';
874 if ($collapse || in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
875 print $langs->trans(
"Stock");
880 if (isModEnabled(
'productbatch')) {
882 if ($collapse || in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
883 print $langs->trans(
"Batch");
895 if (
$object->status == Mo::STATUS_DRAFT) {
900 if ($permissiontodelete) {
906 if ($action ==
'addconsumeline') {
907 print
'<!-- Add line to consume -->'.
"\n";
908 print
'<tr class="liste_titre">';
911 print $form->select_produits(
'',
'productidtoadd',
'', 0, 0, -1, 2,
'', 1, array(), 0,
'1', 0,
'maxwidth300');
914 print
'<td class="right"><input type="text" name="qtytoadd" value="1" class="width50 right"></td>';
922 print
'<td colspan="2">';
923 print
'<input type="submit" class="button buttongen button-add" name="addconsumelinebutton" value="'.$langs->trans(
"Add").
'">';
924 print
'<input type="submit" class="button buttongen button-cancel" name="canceladdconsumelinebutton" value="'.$langs->trans(
"Cancel").
'">';
926 if (isModEnabled(
'stock')) {
930 if (isModEnabled(
'productbatch')) {
938 if (
$object->status == Mo::STATUS_DRAFT) {
942 if ($permissiontodelete) {
948 if (is_object($objectline)) {
949 $extrafields->fetch_name_optionals_label(
$object->table_element_line);
950 $temps = $objectline->showOptionals($extrafields,
'edit', array(),
'',
'', 1,
'line');
951 if (!empty($temps)) {
952 print
'<tr class="liste_titre"><td style="padding-top: 20px" colspan="9" id="extrafield_lines_area_edit" name="extrafield_lines_area_edit">';
964 $nblinetoconsume = 0;
965 foreach (
$object->lines as $line) {
966 if ($line->role ==
'toconsume') {
971 $nblinetoconsumecursor = 0;
972 foreach (
$object->lines as $line) {
973 if ($line->role ==
'toconsume') {
974 $nblinetoconsumecursor++;
976 $tmpproduct =
new Product($db);
977 $tmpproduct->fetch($line->fk_product);
978 $linecost =
price2num($tmpproduct->pmp,
'MT');
982 $costprice =
price2num((!empty($tmpproduct->cost_price)) ? $tmpproduct->cost_price : $tmpproduct->pmp);
983 if (empty($costprice)) {
984 require_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.product.class.php';
986 if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0) {
987 $costprice = $productFournisseur->fourn_unitprice;
995 if ($useunit && $line->fk_unit > 0) {
998 if (preg_match(
'/^(\d+)([a-z]+)$/', $tmpproduct->duration, $reg)) {
1001 $qtyhourforline = 0;
1002 if ($line->fk_unit) {
1007 if ($qtyhourservice && $qtyhourforline) {
1008 $linecost =
price2num(($qtyhourforline / $qtyhourservice * $costprice) /
$object->qty,
'MT');
1009 $bomcostupdated +=
price2num(($qtyhourforline / $qtyhourservice * $costprice) /
$object->qty,
'MU');
1012 $bomcostupdated +=
price2num(($line->qty * $costprice) /
$object->qty,
'MU');
1016 $bomcostupdated +=
price2num(($line->qty * $costprice) /
$object->qty,
'MU');
1020 $bomcostupdated =
price2num($bomcostupdated,
'MU');
1021 $arrayoflines =
$object->fetchLinesLinked(
'consumed', $line->id);
1022 $alreadyconsumed = 0;
1023 foreach ($arrayoflines as $line2) {
1024 $alreadyconsumed += $line2[
'qty'];
1027 if ($action ==
'editline' && $lineid == $line->id) {
1028 $linecost =
price2num($tmpproduct->pmp,
'MT');
1030 $arrayoflines =
$object->fetchLinesLinked(
'consumed', $line->id);
1031 $alreadyconsumed = 0;
1032 if (is_array($arrayoflines) && !empty($arrayoflines)) {
1033 foreach ($arrayoflines as $line2) {
1034 $alreadyconsumed += $line2[
'qty'];
1037 $suffix =
'_' . $line->id;
1038 print
'<!-- Line to dispatch ' . $suffix .
' (line edited) -->' .
"\n";
1040 print
'<input id="qty_ordered' . $suffix .
'" type="hidden" value="' . $line->qty .
'">';
1042 print
'<input id="qty_dispatched' . $suffix .
'" type="hidden" value="' . $alreadyconsumed .
'">';
1044 print
'<input name="lineid" type="hidden" value="' . $line->id .
'">';
1047 print
'<td>' . $tmpproduct->getNomUrl(1);
1048 print
'<br><div class="opacitymedium small tdoverflowmax150" title="' .
dol_escape_htmltag($tmpproduct->label) .
'">' . $tmpproduct->label .
'</span>';
1052 print
'<td class="right nowraponall">';
1053 print
'<input class="width40 right" name="qty_lineProduce" value="'. $line->qty.
'">';
1057 print
'<td class="right nowraponall">';
1065 if ($permissiontoupdatecost &&
getDolGlobalString(
'MRP_SHOW_COST_FOR_CONSUMPTION')) {
1070 print
'<td class="right">';
1071 print
' ' .
price2num($alreadyconsumed,
'MS');
1079 if (isModEnabled(
'stock')) {
1080 print
'<td class="nowraponall right">';
1081 if ($tmpproduct->isStockManaged()) {
1082 if ($tmpproduct->stock_reel < ($line->qty - $alreadyconsumed)) {
1083 print
img_warning($langs->trans(
'StockTooLow')).
' ';
1085 print
'<span class="left">'. $tmpproduct->stock_reel .
' </span>';
1091 if (isModEnabled(
'productbatch')) {
1095 print
'<td colspan="'.(3 + (
$object->status == Mo::STATUS_DRAFT ? 1 : 0) + ($permissiontodelete ? 1 : 0)).
'">';
1096 print
'<input type="submit" class="button buttongen button-add small nominwidth" name="save" value="' . $langs->trans(
"Save") .
'">';
1097 print
'<input type="submit" class="button buttongen button-cancel small nominwidth" name="cancel" value="' . $langs->trans(
"Cancel") .
'">';
1103 if (!empty($extrafields)) {
1104 $line->fetch_optionals();
1105 $temps = $line->showOptionals($extrafields,
'edit', array(),
'',
'', 1,
'line');
1106 if (!empty($temps)) {
1108 print
'<tr><td colspan="'.$colspan.
'"><div style="padding-top: 20px" id="extrafield_lines_area_edit" name="extrafield_lines_area_edit">';
1110 print
'</div></td></tr>';
1114 $suffix =
'_' . $line->id;
1115 print
'<!-- Line to dispatch ' . $suffix .
' -->' .
"\n";
1117 print
'<input id="qty_ordered' . $suffix .
'" type="hidden" value="' . $line->qty .
'">';
1118 print
'<input id="qty_dispatched' . $suffix .
'" type="hidden" value="' . $alreadyconsumed .
'">';
1120 print
'<tr data-line-id="' . $line->id .
'">';
1123 print
'<td>' . $tmpproduct->getNomUrl(1);
1124 print
'<br><div class="opacitymedium small tdoverflowmax150" title="' .
dol_escape_htmltag($tmpproduct->label) .
'">' . $tmpproduct->label .
'</div>';
1128 print
'<td class="right nowraponall">';
1130 if ($line->qty_frozen) {
1131 $help = ($help ?
'<br>' :
'') .
'<strong>' . $langs->trans(
"QuantityFrozen") .
'</strong>: ' .
yn(1) .
' (' . $langs->trans(
"QuantityConsumedInvariable") .
')';
1132 print $form->textwithpicto(
'', $help, -1,
'lock') .
' ';
1134 if ($line->disable_stock_change) {
1135 $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")) .
')';
1136 print $form->textwithpicto(
'', $help, -1,
'help') .
' ';
1142 print
'<td class="right nowraponall">';
1150 if ($permissiontoupdatecost &&
getDolGlobalString(
'MRP_SHOW_COST_FOR_CONSUMPTION')) {
1151 print
'<td class="right nowraponall">';
1152 print
price($linecost);
1157 print
'<td class="right">';
1158 if ($alreadyconsumed) {
1160 print
'jQuery(document).ready(function() {
1161 jQuery("#expandtoproduce' . $line->id .
'").click(function() {
1162 console.log("Expand mrp_production line ' . $line->id .
'");
1163 jQuery(".expanddetail' . $line->id .
'").toggle();';
1164 if ($nblinetoconsume == $nblinetoconsumecursor) {
1165 print
'if (jQuery("#tablelines").hasClass("nobottom")) { jQuery("#tablelines").removeClass("nobottom"); } else { jQuery("#tablelines").addClass("nobottom"); }';
1171 if (empty($conf->use_javascript_ajax)) {
1172 print
'<a href="' . $_SERVER[
"PHP_SELF"] .
'?collapse=' . $collapse .
',' . $line->id .
'">';
1174 print
img_picto($langs->trans(
"ShowDetails"),
"chevron-down",
'id="expandtoproduce' . $line->id .
'"');
1175 if (empty($conf->use_javascript_ajax)) {
1179 if ($nblinetoconsume == $nblinetoconsumecursor) {
1180 print
'<script>jQuery("#tablelines").removeClass("nobottom");</script>';
1183 print
' ' .
price2num($alreadyconsumed,
'MS');
1188 if (
getDolGlobalString(
'STOCK_CONSUMPTION_FROM_MANUFACTURING_WAREHOUSE') && $tmpwarehouse->id > 0) {
1189 print
img_picto(
'', $tmpwarehouse->picto) .
" " . $tmpwarehouse->label;
1191 if (isModEnabled(
'workstation') && $line->fk_default_workstation > 0) {
1193 $tmpworkstation->fetch($line->fk_default_workstation);
1194 print $tmpworkstation->getNomUrl(1);
1199 if (isModEnabled(
'stock')) {
1200 print
'<td class="nowraponall right">';
1202 if (!$line->disable_stock_change && $tmpproduct->stock_reel < ($line->qty - $alreadyconsumed)) {
1203 print
img_warning($langs->trans(
'StockTooLow')) .
' ';
1205 if (!
getDolGlobalString(
'STOCK_CONSUMPTION_FROM_MANUFACTURING_WAREHOUSE') || empty($tmpwarehouse->id)) {
1206 print
price2num($tmpproduct->stock_reel,
'MS');
1209 $tmpproduct->load_stock();
1210 $wh_stock = $tmpproduct->stock_warehouse[$tmpwarehouse->id];
1211 if (!empty($wh_stock)) {
1222 if (isModEnabled(
'productbatch')) {
1233 if (
$object->status == Mo::STATUS_DRAFT) {
1234 $href = $_SERVER[
"PHP_SELF"] .
'?id=' . ((int)
$object->id) .
'&action=editline&token=' .
newToken() .
'&lineid=' . ((int) $line->id);
1235 print
'<td class="center">';
1236 print
'<a class="reposition editfielda" href="' . $href .
'">';
1237 print
img_picto($langs->trans(
'TooltipEditAndRevertStockMovement'),
'edit');
1243 if ($permissiontodelete) {
1244 $href = $_SERVER[
"PHP_SELF"] .
'?id=' . ((int)
$object->id) .
'&action=deleteline&token=' .
newToken() .
'&lineid=' . ((int) $line->id);
1245 print
'<td class="center">';
1246 print
'<a class="reposition" href="' . $href .
'">';
1247 print
img_picto($langs->trans(
'TooltipDeleteAndRevertStockMovement'),
'delete');
1255 if (!empty($extrafields)) {
1256 $line->fetch_optionals();
1257 $temps = $line->showOptionals($extrafields,
'view', array(),
'',
'', 1,
'line');
1258 if (!empty($temps)) {
1260 print
'<tr><td colspan="'.$colspan.
'"><div id="extrafield_lines_area_'.$line->id.
'" name="extrafield_lines_area_'.$line->id.
'">';
1262 print
'</div></td></tr>';
1268 foreach ($arrayoflines as $line2) {
1269 print
'<tr class="expanddetail'.$line->id.
' hideobject opacitylow">';
1273 $tmpstockmovement->id = $line2[
'fk_stock_movement'];
1274 print
'<a href="'.DOL_URL_ROOT.
'/product/stock/movement_list.php?search_ref='.$tmpstockmovement->id.
'">'.
img_picto($langs->trans(
"StockMovement"),
'movement',
'class="paddingright"').
'</a>';
1285 if ($permissiontoupdatecost &&
getDolGlobalString(
'MRP_SHOW_COST_FOR_CONSUMPTION')) {
1290 print
'<td class="right">'.$line2[
'qty'].
'</td>';
1293 print
'<td class="tdoverflowmax150">';
1294 if ($line2[
'fk_warehouse'] > 0) {
1295 $result = $tmpwarehouse->fetch($line2[
'fk_warehouse']);
1297 print $tmpwarehouse->getNomUrl(1);
1303 if (isModEnabled(
'stock')) {
1308 if (isModEnabled(
'productbatch')) {
1310 if ($line2[
'batch'] !=
'') {
1311 $tmpbatch->fetch(0, $line2[
'fk_product'], $line2[
'batch']);
1312 print $tmpbatch->getNomUrl(1);
1324 if (
$object->status == Mo::STATUS_DRAFT) {
1325 $href = $_SERVER[
"PHP_SELF"] .
'?id=' . ((int)
$object->id) .
'&action=editline&token=' .
newToken() .
'&lineid=' . ((int) $line2[
'rowid']);
1326 print
'<td class="center">';
1327 print
'<a class="reposition" href="' . $href .
'">';
1328 print
img_picto($langs->trans(
'TooltipEditAndRevertStockMovement'),
'edit');
1334 if ($permissiontodelete) {
1335 $href = $_SERVER[
"PHP_SELF"].
'?id='.((int)
$object->id).
'&action=deleteline&token='.
newToken().
'&lineid='.((int) $line2[
'rowid']).
'&fk_movement='.((int) $line2[
'fk_stock_movement']);
1336 print
'<td class="center">';
1337 print
'<a class="reposition" href="'.$href.
'">';
1338 print
img_picto($langs->trans(
'TooltipDeleteAndRevertStockMovement'),
'delete');
1346 if (in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
1348 print
'<!-- Enter line to consume -->'.
"\n";
1350 print
'<tr data-max-qty="'.$maxQty.
'" name="batch_'.$line->id.
'_'.$i.
'">';
1352 print
'<td><span class="opacitymedium">'.$langs->trans(
"ToConsume").
'</span></td>';
1353 $preselected = (GETPOSTISSET(
'qty-'.$line->id.
'-'.$i) ?
GETPOST(
'qty-'.$line->id.
'-'.$i) : max(0, $line->qty - $alreadyconsumed));
1354 if ($action ==
'consumeorproduce' && !GETPOSTISSET(
'qty-'.$line->id.
'-'.$i)) {
1359 if (
getDolGlobalString(
'MRP_NEVER_CONSUME_MORE_THAN_EXPECTED') && ($line->qty - $alreadyconsumed) <= 0) {
1360 $disable =
'disabled';
1364 print
'<input type="hidden" name="product-'.$line->id.
'-'.$i.
'" value="'.$line->fk_product.
'">';
1367 print
'<td class="right"><input type="text" class="width50 right" id="qtytoconsume-' . $line->id .
'-' . $i .
'" name="qty-' . $line->id .
'-' . $i .
'" value="' . $preselected .
'" ' . $disable .
'></td>';
1373 if ($permissiontoupdatecost &&
getDolGlobalString(
'MRP_SHOW_COST_FOR_CONSUMPTION')) {
1383 if (empty($line->disable_stock_change)) {
1384 $preselected = (GETPOSTISSET(
'idwarehouse-'.$line->id.
'-'.$i) ?
GETPOST(
'idwarehouse-'.$line->id.
'-'.$i) : ($tmpproduct->fk_default_warehouse > 0 ? $tmpproduct->fk_default_warehouse :
'ifone'));
1385 print $formproduct->selectWarehouses($preselected,
'idwarehouse-'.$line->id.
'-'.$i,
'', 1, 0, $line->fk_product,
'', 1, 0,
null,
'maxwidth200 csswarehouse_'.$line->id.
'_'.$i);
1387 print
'<span class="opacitymedium">'.$langs->trans(
"DisableStockChange").
'</span>';
1390 print
'<span class="opacitymedium">'.$langs->trans(
"NoStockChangeOnServices").
'</span>';
1395 if (isModEnabled(
'stock')) {
1400 if (isModEnabled(
'productbatch')) {
1401 print
'<td class="nowraponall">';
1402 if ($tmpproduct->status_batch) {
1403 $preselected = (GETPOSTISSET(
'batch-'.$line->id.
'-'.$i) ?
GETPOST(
'batch-'.$line->id.
'-'.$i) :
'');
1404 print
'<input type="text" class="width75" name="batch-'.$line->id.
'-'.$i.
'" value="'.$preselected.
'" list="batch-'.$line->id.
'-'.$i.
'">';
1405 print $formproduct->selectLotDataList(
'batch-'.$line->id.
'-'.$i, 0, $line->fk_product,
'',
'');
1412 print
'<td align="right" class="split">';
1413 print
' '.img_picto($langs->trans(
'AddStockLocationLine'),
'split.png',
'class="splitbutton" onClick="addDispatchLine('.((int) $line->id).
', \''.
dol_escape_js($type).
'\', \
'qtymissingconsume\')"');
1417 print
'<td align="right" class="splitall">';
1418 if (($action ==
'consumeorproduce' || $action ==
'consumeandproduceall') && $tmpproduct->status_batch == 2) {
1419 print
img_picto($langs->trans(
'SplitAllQuantity'),
'split.png',
'class="splitbutton splitallbutton field-error-icon" data-max-qty="1" onClick="addDispatchLine('.$line->id.
', \'batch\', \'allmissingconsume\')"');
1424 if (
$object->status == Mo::STATUS_DRAFT) {
1429 if ($permissiontodelete) {
1443 print
'<script type="text/javascript">
1444 $(document).ready(function () {
1445 $("select[name=fk_default_warehouse]").change(function() {
1446 var fk_default_warehouse = $("option:selected", this).val();
1447 $("select[name^=idwarehouse-]").val(fk_default_warehouse).change();
1452 if (in_array($action, array(
'consumeorproduce',
'consumeandproduceall')) &&
1454 print
'<script>$(document).ready(function () {
1455 $("#fk_default_warehouse").change();
1463 print
'<div class="fichehalfright">';
1464 print
'<div class="clearboth"></div>';
1466 $nblinetoproduce = 0;
1467 foreach (
$object->lines as $line) {
1468 if ($line->role ==
'toproduce') {
1473 $newcardbutton =
'';
1474 $url = $_SERVER[
"PHP_SELF"].
'?id='.
$object->id.
'&action=addproduceline&token='.
newToken();
1475 $permissiontoaddaproductline =
$object->status != $object::STATUS_PRODUCED &&
$object->status != $object::STATUS_CANCELED;
1476 $parameters = array(
'morecss' =>
'reposition');
1477 if ($action !=
'consumeorproduce' && $action !=
'consumeandproduceall') {
1478 if ($nblinetoproduce == 0 ||
$object->mrptype == 1) {
1479 $newcardbutton =
dolGetButtonTitle($langs->trans(
'AddNewProduceLines'),
'',
'fa fa-plus-circle size15x', $url,
'', $permissiontoaddaproductline, $parameters);
1483 print
load_fiche_titre($langs->trans(
'Production'), $newcardbutton,
'', 0,
'',
'');
1485 print
'<div class="div-table-responsive-no-min">';
1486 print
'<table id="tablelinestoproduce" class="noborder noshadow nobottom centpercent">';
1488 print
'<tr class="liste_titre">';
1490 print
'<td>'.$langs->trans(
"Product").
'</td>';
1492 print
'<td class="right">'.$langs->trans(
"Qty").
'</td>';
1495 print
'<td class="right">'.$langs->trans(
"Unit").
'</td>';
1498 if ($permissiontoupdatecost) {
1499 if (empty($bomcostupdated)) {
1500 print
'<td class="right">'.$form->textwithpicto($langs->trans(
"UnitCost"), $langs->trans(
"AmountUsedToUpdateWAP")).
'</td>';
1502 print
'<td class="right">'.$form->textwithpicto($langs->trans(
"ManufacturingPrice"), $langs->trans(
"AmountUsedToUpdateWAP")).
'</td>';
1506 print
'<td class="right">'.$form->textwithpicto($langs->trans(
"QtyAlreadyProducedShort"), $langs->trans(
"QtyAlreadyProduced")).
'</td>';
1509 if ($collapse || in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
1510 print $langs->trans(
"Warehouse");
1515 if (isModEnabled(
'productbatch')) {
1517 if ($collapse || in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
1518 print $langs->trans(
"Batch");
1530 if ($permissiontodelete) {
1536 if ($action ==
'addproduceline') {
1537 print
'<!-- Add line to produce -->'.
"\n";
1538 print
'<tr class="liste_titre">';
1542 print $form->select_produits(
'',
'productidtoadd',
'', 0, 0, -1, 2,
'', 1, array(), 0,
'1', 0,
'maxwidth300');
1545 print
'<td class="right"><input type="text" name="qtytoadd" value="1" class="width50 right"></td>';
1551 if ($permissiontoupdatecost) {
1555 print
'<td colspan="2">';
1556 print
'<input type="submit" class="button buttongen button-add" name="addproducelinebutton" value="'.$langs->trans(
"Add").
'">';
1557 print
'<input type="submit" class="button buttongen button-cancel" name="canceladdproducelinebutton" value="'.$langs->trans(
"Cancel").
'">';
1560 if (isModEnabled(
'productbatch')) {
1570 if ($permissiontodelete) {
1577 $nblinetoproduce = 0;
1578 foreach (
$object->lines as $line) {
1579 if ($line->role ==
'toproduce') {
1584 $nblinetoproducecursor = 0;
1585 foreach (
$object->lines as $line) {
1586 if ($line->role ==
'toproduce') {
1589 $nblinetoproducecursor++;
1591 $tmpproduct =
new Product($db);
1592 $tmpproduct->fetch($line->fk_product);
1594 $arrayoflines =
$object->fetchLinesLinked(
'produced', $line->id);
1595 $alreadyproduced = 0;
1596 foreach ($arrayoflines as $line2) {
1597 $alreadyproduced += $line2[
'qty'];
1600 $suffix =
'_'.$line->id;
1601 print
'<!-- Line to dispatch '.$suffix.
' (toproduce) -->'.
"\n";
1603 print
'<input id="qty_ordered'.$suffix.
'" type="hidden" value="'.$line->qty.
'">';
1604 print
'<input id="qty_dispatched'.$suffix.
'" type="hidden" value="'.$alreadyproduced.
'">';
1608 print
'<td>'.$tmpproduct->getNomUrl(1);
1609 print
'<br><span class="opacitymedium small">'.$tmpproduct->label.
'</span>';
1612 print
'<td class="right">'.$line->qty.
'</td>';
1615 print
'<td class="right">'.measuringUnitString($line->fk_unit,
'',
'', 1).
'</td>';
1618 if ($permissiontoupdatecost) {
1620 $manufacturingcost = 0;
1621 $manufacturingcostsrc =
'';
1623 $manufacturingcost = $bomcostupdated;
1624 $manufacturingcostsrc = $langs->trans(
"CalculatedFromProductsToConsume");
1625 if (empty($manufacturingcost)) {
1626 $manufacturingcost = $bomcost;
1627 $manufacturingcostsrc = $langs->trans(
"ValueFromBom");
1629 if (empty($manufacturingcost)) {
1630 $manufacturingcost =
price2num($tmpproduct->cost_price,
'MU');
1631 $manufacturingcostsrc = $langs->trans(
"CostPrice");
1633 if (empty($manufacturingcost)) {
1634 $manufacturingcost =
price2num($tmpproduct->pmp,
'MU');
1635 $manufacturingcostsrc = $langs->trans(
"PMPValue");
1639 print
'<td class="right nowraponall" title="'.dol_escape_htmltag($manufacturingcostsrc).
'">';
1640 if ($manufacturingcost) {
1641 print
price($manufacturingcost);
1646 print
'<td class="right nowraponall">';
1647 if ($alreadyproduced) {
1649 print
'jQuery(document).ready(function() {
1650 jQuery("#expandtoproduce'.$line->id.
'").click(function() {
1651 console.log("Expand mrp_production line '.$line->id.
'");
1652 jQuery(".expanddetailtoproduce'.$line->id.
'").toggle();';
1653 if ($nblinetoproduce == $nblinetoproducecursor) {
1654 print
'if (jQuery("#tablelinestoproduce").hasClass("nobottom")) { jQuery("#tablelinestoproduce").removeClass("nobottom"); } else { jQuery("#tablelinestoproduce").addClass("nobottom"); }';
1660 if (empty($conf->use_javascript_ajax)) {
1661 print
'<a href="'.$_SERVER[
"PHP_SELF"].
'?collapse='.$collapse.
','.$line->id.
'">';
1663 print
img_picto($langs->trans(
"ShowDetails"),
"chevron-down",
'id="expandtoproduce'.$line->id.
'"');
1664 if (empty($conf->use_javascript_ajax)) {
1668 print
' '.$alreadyproduced;
1674 if (isModEnabled(
'productbatch')) {
1684 if ($permissiontodelete) {
1685 if ($line->origin_type ==
'free') {
1686 $href = $_SERVER[
"PHP_SELF"];
1687 $href .=
'?id='.$object->id;
1688 $href .=
'&action=deleteline';
1689 $href .=
'&lineid='.$line->id;
1690 print
'<td class="center">';
1691 print
'<a class="reposition" href="'.$href.
'">';
1692 print
img_picto($langs->trans(
'TooltipDeleteAndRevertStockMovement'),
"delete");
1702 foreach ($arrayoflines as $line2) {
1703 print
'<tr class="expanddetailtoproduce'.$line->id.
' hideobject opacitylow">';
1706 $tmpstockmovement->id = $line2[
'fk_stock_movement'];
1707 print
'<a href="'.DOL_URL_ROOT.
'/product/stock/movement_list.php?search_ref='.$tmpstockmovement->id.
'">'.
img_picto($langs->trans(
"StockMovement"),
'movement',
'class="paddingright"').
'</a>';
1717 if ($permissiontoupdatecost) {
1721 print
'<td class="right">'.$line2[
'qty'].
'</td>';
1723 print
'<td class="tdoverflowmax150">';
1724 if ($line2[
'fk_warehouse'] > 0) {
1725 $result = $tmpwarehouse->fetch($line2[
'fk_warehouse']);
1727 print $tmpwarehouse->getNomUrl(1);
1732 if (isModEnabled(
'productbatch')) {
1734 if ($line2[
'batch'] !=
'') {
1735 $tmpbatch->fetch(0, $line2[
'fk_product'], $line2[
'batch']);
1736 print $tmpbatch->getNomUrl(1);
1747 if ($permissiontodelete) {
1753 if (in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
1754 print
'<!-- Enter line to produce -->'.
"\n";
1756 print
'<tr data-max-qty="'.$maxQty.
'" name="batch_'.$line->id.
'_'.$i.
'">';
1758 print
'<td><span class="opacitymedium">'.$langs->trans(
"ToProduce").
'</span></td>';
1759 $preselected = (GETPOSTISSET(
'qtytoproduce-'.$line->id.
'-'.$i) ?
GETPOST(
'qtytoproduce-'.$line->id.
'-'.$i) : max(0, $line->qty - $alreadyproduced));
1760 if ($action ==
'consumeorproduce' && !GETPOSTISSET(
'qtytoproduce-'.$line->id.
'-'.$i)) {
1764 print
'<td class="right"><input type="text" class="width50 right" id="qtytoproduce-'.$line->id.
'-'.$i.
'" name="qtytoproduce-'.$line->id.
'-'.$i.
'" value="'.$preselected.
'"></td>';
1767 print
'<td class="right"></td>';
1770 if ($permissiontoupdatecost) {
1772 $manufacturingcost = 0;
1773 $manufacturingcostsrc =
'';
1775 $manufacturingcost = $bomcostupdated;
1776 $manufacturingcostsrc = $langs->trans(
"CalculatedFromProductsToConsume");
1777 if (empty($manufacturingcost)) {
1778 $manufacturingcost = $bomcost;
1779 $manufacturingcostsrc = $langs->trans(
"ValueFromBom");
1781 if (empty($manufacturingcost)) {
1782 $manufacturingcost =
price2num($tmpproduct->cost_price,
'MU');
1783 $manufacturingcostsrc = $langs->trans(
"CostPrice");
1785 if (empty($manufacturingcost)) {
1786 $manufacturingcost =
price2num($tmpproduct->pmp,
'MU');
1787 $manufacturingcostsrc = $langs->trans(
"PMPValue");
1792 $preselected = (GETPOSTISSET(
'pricetoproduce-'.$line->id.
'-'.$i) ?
GETPOST(
'pricetoproduce-'.$line->id.
'-'.$i) : ($manufacturingcost ?
price($manufacturingcost) :
''));
1793 print
'<td class="right"><input type="text" class="width75 right" name="pricetoproduce-'.$line->id.
'-'.$i.
'" value="'.$preselected.
'"></td>';
1795 print
'<td><input type="hidden" class="width50 right" name="pricetoproduce-'.$line->id.
'-'.$i.
'" value="'.($manufacturingcost ? $manufacturingcost :
'').
'"></td>';
1803 $preselected = (GETPOSTISSET(
'idwarehousetoproduce-'.$line->id.
'-'.$i) ?
GETPOST(
'idwarehousetoproduce-'.$line->id.
'-'.$i) : (
$object->fk_warehouse > 0 ?
$object->fk_warehouse :
'ifone'));
1804 print $formproduct->selectWarehouses($preselected,
'idwarehousetoproduce-'.$line->id.
'-'.$i,
'', 1, 0, $line->fk_product,
'', 1, 0,
null,
'maxwidth200 csswarehouse_'.$line->id.
'_'.$i);
1806 print
'<span class="opacitymedium">'.$langs->trans(
"NoStockChangeOnServices").
'</span>';
1810 if (isModEnabled(
'productbatch')) {
1812 if ($tmpproduct->status_batch) {
1813 $preselected = (GETPOSTISSET(
'batchtoproduce-'.$line->id.
'-'.$i) ?
GETPOST(
'batchtoproduce-'.$line->id.
'-'.$i) :
'');
1814 print
'<input type="text" class="width75" name="batchtoproduce-'.$line->id.
'-'.$i.
'" value="'.$preselected.
'">';
1818 if ($tmpproduct->status_batch) {
1820 print
'<td align="right" class="split">';
1821 print
img_picto($langs->trans(
'AddStockLocationLine'),
'split.png',
'class="splitbutton" onClick="addDispatchLine('.$line->id.
', \''.$type.
'\', \
'qtymissing\')"');
1824 print
'<td align="right" class="splitall">';
1825 if (($action ==
'consumeorproduce' || $action ==
'consumeandproduceall') && $tmpproduct->status_batch == 2) {
1826 print
img_picto($langs->trans(
'SplitAllQuantity'),
'split.png',
'class="splitbutton splitallbutton field-error-icon" onClick="addDispatchLine('.$line->id.
', \'batch\', \'alltoproduce\')"');
1852 if (in_array($action, array(
'consumeorproduce',
'consumeandproduceall',
'addconsumeline'))) {
1856 <script
type=
"text/javascript" language=
"javascript">
1858 $(document).ready(
function() {
1860 updateselectbatchbywarehouse();
1862 updateselectwarehousebybatch();
1865 function updateselectbatchbywarehouse() {
1866 $(document).on(
'change',
"select[name*='idwarehouse']",
function () {
1867 console.log(
"We change warehouse so we update the list of possible batch number");
1869 var selectwarehouse = $(
this);
1871 var selectbatch_name = selectwarehouse.attr(
'name').replace(
'idwarehouse',
'batch');
1872 var selectbatch = $(
"datalist[id*='" + selectbatch_name +
"']");
1873 var selectedbatch = selectbatch.val();
1875 var product_element_name = selectwarehouse.attr(
'name').replace(
'idwarehouse',
'product');
1879 url:
"<?php echo DOL_URL_ROOT . '/mrp/ajax/interface.php'; ?>",
1881 action:
"updateselectbatchbywarehouse",
1882 permissiontoproduce: <?php echo $permissiontoproduce ?>,
1883 warehouse_id: $(
this).val(),
1884 token:
'<?php echo currentToken(); ?>',
1885 product_id: $(
"input[name='" + product_element_name +
"']").val()
1887 }).done(
function (data) {
1889 selectbatch.empty();
1891 if (typeof data ==
"object") {
1892 console.log(
"data is already type object, no need to parse it");
1894 console.log(
"data is type "+(typeof data));
1895 data = JSON.parse(data);
1898 selectbatch.append($(
'<option>', {
1902 $.each(data,
function (key, value) {
1904 if(selectwarehouse.val() == -1) {
1905 var label = key +
" (<?php echo $langs->trans('Stock total') ?> : " + value +
")";
1907 var label = key +
" (<?php echo $langs->trans('Stock') ?> : " + value +
")";
1910 if(key === selectedbatch) {
1911 var option =
'<option value="'+key+
'" selected>'+ label +
'</option>';
1913 var option =
'<option value="'+key+
'">'+ label +
'</option>';
1916 selectbatch.append(option);
1922 function updateselectwarehousebybatch() {
1923 $(document).on(
'change',
'input[name*=batch]',
function(){
1924 console.log(
"We change batch so we update the list of possible warehouses");
1926 var selectbatch = $(
this);
1928 var selectwarehouse_name = selectbatch.attr(
'name').replace(
'batch',
'idwarehouse');
1929 var selectwarehouse = $(
"select[name*='" + selectwarehouse_name +
"']");
1930 var selectedwarehouse = selectwarehouse.val();
1932 if(selectedwarehouse != -1){
1936 var product_element_name = selectbatch.attr(
'name').replace(
'batch',
'product');
1940 url:
"<?php echo DOL_URL_ROOT . '/mrp/ajax/interface.php'; ?>",
1942 action:
"updateselectwarehousebybatch",
1943 permissiontoproduce: <?php echo $permissiontoproduce ?>,
1944 batch: $(
this).val(),
1945 token:
'<?php echo currentToken(); ?>',
1946 product_id: $(
"input[name='" + product_element_name +
"']").val()
1948 }).done(
function (data) {
1950 if (typeof data ==
"object") {
1951 console.log(
"data is already type object, no need to parse it");
1953 console.log(
"data is type "+(typeof data));
1954 data = JSON.parse(data);
1958 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.
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.