27 require
'../main.inc.php';
29 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formcompany.class.php';
30 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formfile.class.php';
31 require_once DOL_DOCUMENT_ROOT.
'/core/class/html.formprojet.class.php';
32 require_once DOL_DOCUMENT_ROOT.
'/projet/class/project.class.php';
33 require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
34 require_once DOL_DOCUMENT_ROOT.
'/product/class/html.formproduct.class.php';
35 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/entrepot.class.php';
36 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/productlot.class.php';
37 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
44 $langs->loadLangs(array(
"mrp",
"stocks",
"other",
"product",
"productbatch"));
49 $action =
GETPOST(
'action',
'aZ09');
50 $confirm =
GETPOST(
'confirm',
'alpha');
51 $cancel =
GETPOST(
'cancel',
'aZ09');
52 $contextpage =
GETPOST(
'contextpage',
'aZ') ?
GETPOST(
'contextpage',
'aZ') :
'mocard';
53 $backtopage =
GETPOST(
'backtopage',
'alpha');
54 $lineid =
GETPOST(
'lineid',
'int');
55 $fk_movement =
GETPOST(
'fk_movement',
'int');
56 $fk_default_warehouse =
GETPOST(
'fk_default_warehouse',
'int');
58 $collapse =
GETPOST(
'collapse',
'aZ09comma');
61 $object =
new Mo($db);
63 $diroutputmassaction = $conf->mrp->dir_output.
'/temp/massgeneration/'.$user->id;
65 $hookmanager->initHooks(array(
'mocard',
'globalcard'));
68 $extrafields->fetch_name_optionals_label($object->table_element);
70 $search_array_options = $extrafields->getOptionalsFromPost($object->table_element,
'',
'search_');
73 $search_all =
GETPOST(
"search_all",
'alpha');
75 foreach ($object->fields as $key => $val) {
76 if (
GETPOST(
'search_'.$key,
'alpha')) {
77 $search[$key] =
GETPOST(
'search_'.$key,
'alpha');
81 if (empty($action) && empty($id) && empty($ref)) {
86 include DOL_DOCUMENT_ROOT.
'/core/actions_fetchobject.inc.php';
91 $isdraft = (($object->status == $object::STATUS_DRAFT) ? 1 : 0);
92 $result =
restrictedArea($user,
'mrp', $object->id,
'mrp_mo',
'',
'fk_soc',
'rowid', $isdraft);
95 $permissionnote = $user->rights->mrp->write;
96 $permissiondellink = $user->rights->mrp->write;
97 $permissiontoadd = $user->rights->mrp->write;
98 $permissiontodelete = $user->rights->mrp->delete || ($permissiontoadd && isset($object->status) && $object->status == $object::STATUS_DRAFT);
100 $permissiontoproduce = $permissiontoadd;
101 $permissiontoupdatecost = $user->hasRight(
'bom',
'read');
103 $upload_dir = $conf->mrp->multidir_output[isset($object->entity) ? $object->entity : 1];
110 $parameters = array();
111 $reshook = $hookmanager->executeHooks(
'doActions', $parameters, $object, $action);
116 if (empty($reshook)) {
121 if (empty($backtopage) || ($cancel && empty($id))) {
123 if (empty($id) && (($action !=
'add' && $action !=
'create') || $cancel)) {
124 $backtopage = $backurlforlist;
126 $backtopage = DOL_URL_ROOT.
'/mrp/mo_production.php?id='.($id > 0 ? $id :
'__ID__');
129 $triggermodname =
'MO_MODIFY';
132 include DOL_DOCUMENT_ROOT.
'/core/actions_addupdatedelete.inc.php';
135 include DOL_DOCUMENT_ROOT.
'/core/actions_dellink.inc.php';
138 include DOL_DOCUMENT_ROOT.
'/core/actions_printing.inc.php';
141 $triggersendname =
'MO_SENTBYMAIL';
142 $autocopy =
'MAIN_MAIL_AUTOCOPY_MO_TO';
143 $trackid =
'mo'.$object->id;
144 include DOL_DOCUMENT_ROOT.
'/core/actions_sendmails.inc.php';
149 if ($action ==
'set_thirdparty' && $permissiontoadd) {
150 $object->setValueFrom(
'fk_soc',
GETPOST(
'fk_soc',
'int'),
'',
'',
'date',
'', $user, $triggermodname);
152 if ($action ==
'classin' && $permissiontoadd) {
153 $object->setProject(
GETPOST(
'projectid',
'int'));
156 if ($action ==
'confirm_reopen' && $permissiontoadd) {
157 $result = $object->setStatut($object::STATUS_INPROGRESS, 0,
'',
'MRP_REOPEN');
160 if (($action ==
'confirm_addconsumeline' &&
GETPOST(
'addconsumelinebutton') && $permissiontoadd)
161 || ($action ==
'confirm_addproduceline' &&
GETPOST(
'addproducelinebutton') && $permissiontoadd)) {
162 $moline =
new MoLine($db);
165 $moline->fk_mo = $object->id;
166 $moline->qty =
GETPOST(
'qtytoadd',
'int');
167 $moline->fk_product =
GETPOST(
'productidtoadd',
'int');
168 if (
GETPOST(
'addconsumelinebutton')) {
169 $moline->role =
'toconsume';
171 $moline->role =
'toproduce';
173 $moline->origin_type =
'free';
174 $moline->position = 0;
177 if (!empty($moline->fk_product)) {
178 $tmpproduct =
new Product($db);
179 $tmpproduct->fetch($moline->fk_product);
181 $moline->fk_default_workstation = $tmpproduct->fk_default_workstation;
186 $resultline = $moline->create($user,
false);
187 if ($resultline <= 0) {
194 header(
"Location: ".$_SERVER[
"PHP_SELF"].
'?id='.$object->id);
198 if (in_array($action, array(
'confirm_consumeorproduce',
'confirm_consumeandproduceall')) && $permissiontoproduce) {
201 $labelmovement =
GETPOST(
'inventorylabel',
'alphanohtml');
202 $codemovement =
GETPOST(
'inventorycode',
'alphanohtml');
207 foreach ($object->lines as $line) {
208 if ($line->role ==
'toconsume') {
209 $tmpproduct =
new Product($db);
210 $tmpproduct->fetch($line->fk_product);
216 if ($qtytoprocess != 0) {
219 if (!(
GETPOST(
'idwarehouse-'.$line->id.
'-'.$i) > 0)) {
220 $langs->load(
"errors");
221 setEventMessages($langs->trans(
"ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv(
"Warehouse"), $tmpproduct->ref),
null,
'errors');
224 if ($tmpproduct->status_batch && (!
GETPOST(
'batch-'.$line->id.
'-'.$i))) {
225 $langs->load(
"errors");
226 setEventMessages($langs->trans(
"ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv(
"Batch"), $tmpproduct->ref),
null,
'errors');
232 if (!$error &&
GETPOST(
'idwarehouse-'.$line->id.
'-'.$i) > 0) {
234 $id_product_batch = 0;
235 $stockmove->setOrigin($object->element, $object->id);
236 $stockmove->context[
'mrp_role'] =
'toconsume';
238 if ($qtytoprocess >= 0) {
239 $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);
241 $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);
243 if ($idstockmove < 0) {
251 $moline =
new MoLine($db);
252 $moline->fk_mo = $object->id;
253 $moline->position = $pos;
254 $moline->fk_product = $line->fk_product;
255 $moline->fk_warehouse =
GETPOST(
'idwarehouse-'.$line->id.
'-'.$i);
256 $moline->qty = $qtytoprocess;
257 $moline->batch =
GETPOST(
'batch-'.$line->id.
'-'.$i);
258 $moline->role =
'consumed';
259 $moline->fk_mrp_production = $line->id;
260 $moline->fk_stock_movement = $idstockmove == 0 ? null : $idstockmove;
261 $moline->fk_user_creat = $user->id;
263 $resultmoline = $moline->create($user);
264 if ($resultmoline <= 0) {
281 foreach ($object->lines as $line) {
282 if ($line->role ==
'toproduce') {
283 $tmpproduct =
new Product($db);
284 $tmpproduct->fetch($line->fk_product);
287 while (
GETPOSTISSET(
'qtytoproduce-'.$line->id.
'-'.$i)) {
289 $pricetoprocess =
GETPOST(
'pricetoproduce-'.$line->id.
'-'.$i) ?
price2num(
GETPOST(
'pricetoproduce-'.$line->id.
'-'.$i)) : 0;
291 if ($qtytoprocess != 0) {
293 if (
GETPOSTISSET(
'idwarehousetoproduce-'.$line->id.
'-'.$i)) {
294 if (!(
GETPOST(
'idwarehousetoproduce-'.$line->id.
'-'.$i) > 0)) {
295 $langs->load(
"errors");
296 setEventMessages($langs->trans(
"ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv(
"Warehouse"), $tmpproduct->ref),
null,
'errors');
299 if (
isModEnabled(
'productbatch') && $tmpproduct->status_batch && (!
GETPOST(
'batchtoproduce-'.$line->id.
'-'.$i))) {
300 $langs->load(
"errors");
301 setEventMessages($langs->trans(
"ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv(
"Batch"), $tmpproduct->ref),
null,
'errors');
307 if (!$error &&
GETPOST(
'idwarehousetoproduce-'.$line->id.
'-'.$i) > 0) {
309 $id_product_batch = 0;
310 $stockmove->origin_type = $object->element;
311 $stockmove->origin_id = $object->id;
312 $stockmove->context[
'mrp_role'] =
'toproduce';
314 $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);
315 if ($idstockmove < 0) {
323 $moline =
new MoLine($db);
324 $moline->fk_mo = $object->id;
325 $moline->position = $pos;
326 $moline->fk_product = $line->fk_product;
327 $moline->fk_warehouse =
GETPOST(
'idwarehousetoproduce-'.$line->id.
'-'.$i);
328 $moline->qty = $qtytoprocess;
329 $moline->batch =
GETPOST(
'batchtoproduce-'.$line->id.
'-'.$i);
330 $moline->role =
'produced';
331 $moline->fk_mrp_production = $line->id;
332 $moline->fk_stock_movement = $idstockmove;
333 $moline->fk_user_creat = $user->id;
335 $resultmoline = $moline->create($user);
336 if ($resultmoline <= 0) {
351 $consumptioncomplete =
true;
352 $productioncomplete =
true;
354 if (
GETPOST(
'autoclose',
'int')) {
355 foreach ($object->lines as $line) {
356 if ($line->role ==
'toconsume') {
357 $arrayoflines = $object->fetchLinesLinked(
'consumed', $line->id);
358 $alreadyconsumed = 0;
359 foreach ($arrayoflines as $line2) {
360 $alreadyconsumed += $line2[
'qty'];
363 if ($alreadyconsumed < $line->qty) {
364 $consumptioncomplete =
false;
367 if ($line->role ==
'toproduce') {
368 $arrayoflines = $object->fetchLinesLinked(
'produced', $line->id);
369 $alreadyproduced = 0;
370 foreach ($arrayoflines as $line2) {
371 $alreadyproduced += $line2[
'qty'];
374 if ($alreadyproduced < $line->qty) {
375 $productioncomplete =
false;
380 $consumptioncomplete =
false;
381 $productioncomplete =
false;
385 dol_syslog(
"consumptioncomplete = ".$consumptioncomplete.
" productioncomplete = ".$productioncomplete);
387 if ($consumptioncomplete && $productioncomplete) {
388 $result = $object->setStatut($object::STATUS_PRODUCED, 0,
'',
'MRP_MO_PRODUCED');
390 $result = $object->setStatut($object::STATUS_INPROGRESS, 0,
'',
'MRP_MO_PRODUCED');
399 $action = str_replace(
'confirm_',
'', $action);
405 header(
"Location: ".$_SERVER[
"PHP_SELF"].
'?id='.$object->id);
411 if ($action ==
'confirm_produced' && $confirm ==
'yes' && $permissiontoadd) {
412 $result = $object->setStatut($object::STATUS_PRODUCED, 0,
'',
'MRP_MO_PRODUCED');
415 if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) {
416 $outputlangs = $langs;
419 $newlang =
GETPOST(
'lang_id',
'aZ09');
422 $newlang = $object->thirdparty->default_lang;
424 if (!empty($newlang)) {
426 $outputlangs->setDefaultLang($newlang);
428 $model = $object->model_pdf;
429 $ret = $object->fetch($id);
431 $object->generateDocument($model, $outputlangs, 0, 0, 0);
452 $help_url =
'EN:Module_Manufacturing_Orders|FR:Module_Ordres_de_Fabrication|DE:Modul_Fertigungsauftrag';
453 $morejs = array(
'/mrp/js/lib_dispatch.js.php');
459 if ($object->id > 0 && (empty($action) || ($action !=
'edit' && $action !=
'create'))) {
460 $res = $object->fetch_thirdparty();
461 $res = $object->fetch_optionals();
463 if (!empty($conf->global->STOCK_CONSUMPTION_FROM_MANUFACTURING_WAREHOUSE) && $object->fk_warehouse > 0) {
464 $tmpwarehouse->fetch($object->fk_warehouse);
465 $fk_default_warehouse = $object->fk_warehouse;
470 print
dol_get_fiche_head($head,
'production', $langs->trans(
"ManufacturingOrder"), -1, $object->picto);
475 if ($action ==
'delete') {
476 $formconfirm =
$form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.$object->id, $langs->trans(
'DeleteMo'), $langs->trans(
'ConfirmDeleteMo'),
'confirm_delete',
'', 0, 1);
479 if ($action ==
'deleteline') {
480 $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);
483 if ($action ==
'clone') {
485 $formquestion = array();
486 $formconfirm =
$form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.$object->id, $langs->trans(
'ToClone'), $langs->trans(
'ConfirmCloneMo', $object->ref),
'confirm_clone', $formquestion,
'yes', 1);
490 if ($action ==
'validate') {
492 $ref = substr($object->ref, 1, 4);
493 if ($ref ==
'PROV') {
494 $object->fetch_product();
495 $numref = $object->getNextNumRef($object->product);
497 $numref = $object->ref;
500 $text = $langs->trans(
'ConfirmValidateMo', $numref);
509 $formquestion = array();
512 require_once DOL_DOCUMENT_ROOT.
'/product/class/html.formproduct.class.php';
515 if ($conf->browser->name ==
'ie') {
518 $formquestion = array(
525 $formconfirm =
$form->formconfirm($_SERVER[
"PHP_SELF"].
'?id='.$object->id, $langs->trans(
'Validate'), $text,
'confirm_validate', $formquestion, 0, 1, 220);
529 $parameters = array(
'formConfirm' =>
$formconfirm,
'lineid' => $lineid);
530 $reshook = $hookmanager->executeHooks(
'formConfirm', $parameters, $object, $action);
531 if (empty($reshook)) {
533 } elseif ($reshook > 0) {
543 $linkback =
'<a href="'.DOL_URL_ROOT.
'/mrp/mo_list.php?restore_lastsearch_values=1'.(!empty($socid) ?
'&socid='.$socid :
'').
'">'.$langs->trans(
"BackToList").
'</a>';
545 $morehtmlref =
'<div class="refidno">';
554 if (is_object($object->thirdparty)) {
555 $morehtmlref .= $object->thirdparty->getNomUrl(1,
'customer');
556 if (empty($conf->global->MAIN_DISABLE_OTHER_LINK) && $object->thirdparty->id > 0) {
557 $morehtmlref .=
' (<a href="'.DOL_URL_ROOT.
'/commande/list.php?socid='.$object->thirdparty->id.
'&search_societe='.urlencode($object->thirdparty->name).
'">'.$langs->trans(
"OtherOrders").
'</a>)';
563 $langs->load(
"projects");
564 if (is_object($object->thirdparty)) {
565 $morehtmlref .=
'<br>';
567 if ($permissiontoadd) {
568 $morehtmlref .=
img_picto($langs->trans(
"Project"),
'project',
'class="pictofixedwidth"');
569 if ($action !=
'classify') {
570 $morehtmlref .=
'<a class="editfielda" href="'.$_SERVER[
'PHP_SELF'].
'?action=classify&token='.
newToken().
'&id='.$object->id.
'">'.
img_edit($langs->transnoentitiesnoconv(
'SetProject')).
'</a> ';
572 $morehtmlref .=
$form->form_project($_SERVER[
'PHP_SELF'].
'?id='.$object->id, $object->socid, $object->fk_project, ($action ==
'classify' ?
'projectid' :
'none'), 0, 0, 0, 1,
'',
'maxwidth300');
574 if (!empty($object->fk_project)) {
576 $proj->fetch($object->fk_project);
577 $morehtmlref .= $proj->getNomUrl(1);
579 $morehtmlref .=
'<span class="opacitymedium"> - '.dol_escape_htmltag($proj->title).
'</span>';
584 $morehtmlref .=
'</div>';
587 dol_banner_tab($object,
'ref', $linkback, 1,
'ref',
'ref', $morehtmlref);
590 print
'<div class="fichecenter">';
591 print
'<div class="fichehalfleft">';
592 print
'<div class="underbanner clearboth"></div>';
593 print
'<table class="border centpercent tableforfield">'.
"\n";
596 $keyforbreak =
'fk_warehouse';
597 unset($object->fields[
'fk_project']);
598 unset($object->fields[
'fk_soc']);
599 include DOL_DOCUMENT_ROOT.
'/core/tpl/commonfields_view.tpl.php';
602 include DOL_DOCUMENT_ROOT.
'/core/tpl/extrafields_view.tpl.php';
608 print
'<div class="clearboth"></div>';
613 if (!in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
614 print
'<div class="tabsAction">';
616 $parameters = array();
618 $reshook = $hookmanager->executeHooks(
'addMoreActionsButtons', $parameters, $object, $action);
619 if (empty($reshook)) {
621 if ($object->status == $object::STATUS_DRAFT) {
622 if ($permissiontoadd) {
623 if (empty($object->table_element_line) || (is_array($object->lines) && count($object->lines) > 0)) {
624 print
'<a class="butAction" href="'.$_SERVER[
'PHP_SELF'].
'?id='.$object->id.
'&action=validate&token='.$newToken.
'">'.$langs->trans(
"Validate").
'</a>';
626 $langs->load(
"errors");
627 print
'<a class="butActionRefused" href="" title="'.$langs->trans(
"ErrorAddAtLeastOneLineFirst").
'">'.$langs->trans(
"Validate").
'</a>';
633 if ($object->status == Mo::STATUS_VALIDATED || $object->status == Mo::STATUS_INPROGRESS) {
634 if ($permissiontoproduce) {
635 print
'<a class="butAction" href="'.$_SERVER[
"PHP_SELF"].
'?id='.$object->id.
'&action=consumeorproduce&token='.$newToken.
'">'.$langs->trans(
'ConsumeOrProduce').
'</a>';
637 print
'<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans(
"NotEnoughPermissions").
'">'.$langs->trans(
'ConsumeOrProduce').
'</a>';
639 } elseif ($object->status == Mo::STATUS_DRAFT) {
640 print
'<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans(
"ValidateBefore").
'">'.$langs->trans(
'ConsumeOrProduce').
'</a>';
644 if ($object->status == Mo::STATUS_VALIDATED || $object->status == Mo::STATUS_INPROGRESS) {
645 if ($permissiontoproduce) {
646 print
'<a class="butAction" href="'.$_SERVER[
"PHP_SELF"].
'?id='.$object->id.
'&action=consumeandproduceall&token='.$newToken.
'">'.$langs->trans(
'ConsumeAndProduceAll').
'</a>';
648 print
'<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans(
"NotEnoughPermissions").
'">'.$langs->trans(
'ConsumeAndProduceAll').
'</a>';
650 } elseif ($object->status == Mo::STATUS_DRAFT) {
651 print
'<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans(
"ValidateBefore").
'">'.$langs->trans(
'ConsumeAndProduceAll').
'</a>';
655 if ($permissiontoadd) {
656 if ($object->status == $object::STATUS_VALIDATED || $object->status == $object::STATUS_INPROGRESS) {
657 $arrayproduced = $object->fetchLinesLinked(
'produced', 0);
659 foreach ($arrayproduced as $lineproduced) {
660 $nbProduced += $lineproduced[
'qty'];
662 if ($nbProduced > 0) {
663 print
'<a class="butAction" href="'.$_SERVER[
"PHP_SELF"].
'?id='.$object->id.
'&action=confirm_produced&confirm=yes&token='.$newToken.
'">'.$langs->trans(
"Close").
'</a>'.
"\n";
665 print
'<a class="butActionRefused" href="#" title="'.$langs->trans(
"GoOnTabProductionToProduceFirst", $langs->transnoentitiesnoconv(
"Production")).
'">'.$langs->trans(
"Close").
'</a>'.
"\n";
668 print
'<a class="butActionDelete" href="'.$_SERVER[
"PHP_SELF"].
'?id='.$object->id.
'&action=confirm_close&confirm=yes&token='.$newToken.
'">'.$langs->trans(
"Cancel").
'</a>'.
"\n";
671 if ($object->status == $object::STATUS_CANCELED) {
672 print
'<a class="butAction" href="'.$_SERVER[
"PHP_SELF"].
'?id='.$object->id.
'&action=confirm_reopen&confirm=yes&token='.$newToken.
'">'.$langs->trans(
"Re-Open").
'</a>'.
"\n";
675 if ($object->status == $object::STATUS_PRODUCED) {
676 if ($permissiontoproduce) {
677 print
'<a class="butAction" href="'.$_SERVER[
"PHP_SELF"].
'?id='.$object->id.
'&action=confirm_reopen&token='.$newToken.
'">'.$langs->trans(
'ReOpen').
'</a>';
679 print
'<a class="butActionRefused classfortooltip" href="#" title="'.$langs->trans(
"NotEnoughPermissions").
'">'.$langs->trans(
'ReOpen').
'</a>';
688 if (in_array($action, array(
'consumeorproduce',
'consumeandproduceall',
'addconsumeline',
'addproduceline'))) {
689 print
'<form method="POST" action="'.$_SERVER[
"PHP_SELF"].
'">';
690 print
'<input type="hidden" name="token" value="'.newToken().
'">';
691 print
'<input type="hidden" name="action" value="confirm_'.$action.
'">';
692 print
'<input type="hidden" name="backtopage" value="'.$backtopage.
'">';
693 print
'<input type="hidden" name="id" value="'.$id.
'">';
696 if (in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
697 $defaultstockmovementlabel =
GETPOST(
'inventorylabel',
'alphanohtml') ?
GETPOST(
'inventorylabel',
'alphanohtml') : $langs->trans(
"ProductionForRef", $object->
ref);
700 print
'<div class="center'.(in_array($action, array(
'consumeorproduce',
'consumeandproduceall')) ?
' formconsumeproduce' :
'').
'">';
701 print
'<div class="opacitymedium hideonsmartphone paddingbottom">'.$langs->trans(
"ConfirmProductionDesc", $langs->transnoentitiesnoconv(
"Confirm")).
'<br></div>';
702 print
'<span class="fieldrequired">'.$langs->trans(
"InventoryCode").
':</span> <input type="text" class="minwidth150 maxwidth200" name="inventorycode" value="'.$defaultstockmovementcode.
'"> ';
703 print
'<span class="clearbothonsmartphone"></span>';
704 print $langs->trans(
"MovementLabel").
': <input type="text" class="minwidth300" name="inventorylabel" value="'.$defaultstockmovementlabel.
'"><br><br>';
705 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>';
706 print
'<input type="submit" class="button" value="'.$langs->trans(
"Confirm").
'" name="confirm">';
708 print
'<input class="button button-cancel" type="submit" value="'.$langs->trans(
"Cancel").
'" name="cancel">';
722 if (!empty($object->table_element_line)) {
724 $object->fetchLines();
727 if ($object->fk_bom > 0) {
729 $res = $bom->fetch($object->fk_bom);
731 $bom->calculateCosts();
732 $bomcost = $bom->unit_cost;
738 print
'<div class="fichecenter">';
739 print
'<div class="fichehalfleft">';
740 print
'<div class="clearboth"></div>';
742 $url = $_SERVER[
"PHP_SELF"].
'?id='.$object->id.
'&action=addconsumeline&token='.
newToken();
743 $permissiontoaddaconsumeline = $object->status != $object::STATUS_PRODUCED && $object->status != $object::STATUS_CANCELED;
744 $parameters = array(
'morecss'=>
'reposition');
747 if ($action !=
'consumeorproduce' && $action !=
'consumeandproduceall') {
748 $newcardbutton =
dolGetButtonTitle($langs->trans(
'AddNewConsumeLines'),
'',
'fa fa-plus-circle size15x', $url,
'', $permissiontoaddaconsumeline, $parameters);
751 print
load_fiche_titre($langs->trans(
'Consumption'), $newcardbutton,
'', 0,
'',
'',
'');
753 print
'<div class="div-table-responsive-no-min">';
754 print
'<table class="noborder noshadow centpercent nobottom">';
756 print
'<tr class="liste_titre">';
758 print
'<td>'.$langs->trans(
"Product").
'</td>';
760 print
'<td class="right">'.$langs->trans(
"Qty").
'</td>';
762 if ($permissiontoupdatecost && !empty($conf->global->MRP_SHOW_COST_FOR_CONSUMPTION)) {
763 print
'<td class="right">'.$langs->trans(
"UnitCost").
'</td>';
766 print
'<td class="right">'.$langs->trans(
"QtyAlreadyConsumed").
'</td>';
769 if ($collapse || in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
770 print $langs->trans(
"Warehouse");
773 if (in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
774 $listwarehouses = $tmpwarehouse->list_array(1);
775 if (count($listwarehouses) > 1) {
776 print
'<br>'.$form->selectarray(
'fk_default_warehouse', $listwarehouses, $fk_default_warehouse, $langs->trans(
"ForceTo"), 0, 0,
'', 0, 0, 0,
'',
'minwidth100 maxwidth200', 1);
777 } elseif (count($listwarehouses) == 1) {
778 print
'<br>'.$form->selectarray(
'fk_default_warehouse', $listwarehouses, $fk_default_warehouse, 0, 0, 0,
'', 0, 0, 0,
'',
'minwidth100 maxwidth200', 1);
786 print
'<td align="right">';
787 if ($collapse || in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
788 print $langs->trans(
"Stock");
795 if ($collapse || in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
796 print $langs->trans(
"Batch");
801 if ($permissiontodelete) {
813 if ($action ==
'addconsumeline') {
814 print
'<!-- Add line to consume -->'.
"\n";
815 print
'<tr class="liste_titre">';
817 print
$form->select_produits(
'',
'productidtoadd',
'', 0, 0, -1, 2,
'', 1, array(), 0,
'1', 0,
'maxwidth300');
820 print
'<td class="right"><input type="text" name="qtytoadd" value="1" class="width50 right"></td>';
822 if ($permissiontoupdatecost && !empty($conf->global->MRP_SHOW_COST_FOR_CONSUMPTION)) {
826 print
'<td colspan="2">';
828 print
'<input type="submit" class="button buttongen button-add" name="addconsumelinebutton" value="'.$langs->trans(
"Add").
'">';
829 print
'<input type="submit" class="button buttongen button-cancel" name="canceladdconsumelinebutton" value="'.$langs->trans(
"Cancel").
'">';
839 if ($permissiontodelete) {
853 if (!empty($object->lines)) {
854 $nblinetoconsume = 0;
855 foreach ($object->lines as $line) {
856 if ($line->role ==
'toconsume') {
861 $nblinetoconsumecursor = 0;
862 foreach ($object->lines as $line) {
863 if ($line->role ==
'toconsume') {
864 $nblinetoconsumecursor++;
866 $tmpproduct =
new Product($db);
867 $tmpproduct->fetch($line->fk_product);
868 $linecost =
price2num($tmpproduct->pmp,
'MT');
870 if ($object->qty > 0) {
872 $costprice =
price2num((!empty($tmpproduct->cost_price)) ? $tmpproduct->cost_price : $tmpproduct->pmp);
873 if (empty($costprice)) {
874 require_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.product.class.php';
876 if ($productFournisseur->find_min_price_product_fournisseur($line->fk_product) > 0) {
877 $costprice = $productFournisseur->fourn_unitprice;
882 $linecost =
price2num(($line->qty * $costprice) / $object->qty,
'MT');
883 $bomcostupdated +=
price2num(($line->qty * $costprice) / $object->qty,
'MU');
886 $bomcostupdated =
price2num($bomcostupdated,
'MU');
887 $arrayoflines = $object->fetchLinesLinked(
'consumed', $line->id);
888 $alreadyconsumed = 0;
889 foreach ($arrayoflines as $line2) {
890 $alreadyconsumed += $line2[
'qty'];
893 $suffix =
'_'.$line->id;
894 print
'<!-- Line to dispatch '.$suffix.
' -->'.
"\n";
896 print
'<input id="qty_ordered'.$suffix.
'" type="hidden" value="'.$line->qty.
'">';
897 print
'<input id="qty_dispatched'.$suffix.
'" type="hidden" value="'.$alreadyconsumed.
'">';
899 print
'<tr data-line-id="'.$line->id.
'">';
901 print
'<td>'.$tmpproduct->getNomUrl(1);
902 print
'<br><div class="opacitymedium small tdoverflowmax150" title="'.dol_escape_htmltag($tmpproduct->label).
'">'.$tmpproduct->label.
'</div>';
905 print
'<td class="right nowraponall">';
906 $help =
''; $picto =
'help';
907 if ($line->qty_frozen) {
908 $help = ($help ?
'<br>' :
'').
'<strong>'.$langs->trans(
"QuantityFrozen").
'</strong>: '.
yn(1).
' ('.$langs->trans(
"QuantityConsumedInvariable").
')';
909 print
$form->textwithpicto(
'', $help, -1,
'lock').
' ';
911 if ($line->disable_stock_change) {
912 $help = ($help ?
'<br>' :
'').
'<strong>'.$langs->trans(
"DisableStockChange").
'</strong>: '.
yn(1).
' ('.(($tmpproduct->type ==
Product::TYPE_SERVICE && empty($conf->global->STOCK_SUPPORTS_SERVICES)) ? $langs->trans(
"NoStockChangeOnServices") : $langs->trans(
"DisableStockChangeHelp")).
')';
913 print
$form->textwithpicto(
'', $help, -1,
'help').
' ';
918 if ($permissiontoupdatecost && !empty($conf->global->MRP_SHOW_COST_FOR_CONSUMPTION)) {
919 print
'<td class="right nowraponall">';
920 print
price($linecost);
924 print
'<td class="right">';
925 if ($alreadyconsumed) {
927 print
'jQuery(document).ready(function() {
928 jQuery("#expandtoproduce'.$line->id.
'").click(function() {
929 console.log("Expand mrp_production line '.$line->id.
'");
930 jQuery(".expanddetail'.$line->id.
'").toggle();';
931 if ($nblinetoconsume == $nblinetoconsumecursor) {
932 print
'if (jQuery("#tablelines").hasClass("nobottom")) { jQuery("#tablelines").removeClass("nobottom"); } else { jQuery("#tablelines").addClass("nobottom"); }';
938 if (empty($conf->use_javascript_ajax)) {
939 print
'<a href="'.$_SERVER[
"PHP_SELF"].
'?collapse='.$collapse.
','.$line->id.
'">';
941 print
img_picto($langs->trans(
"ShowDetails"),
"chevron-down",
'id="expandtoproduce'.$line->id.
'"');
942 if (empty($conf->use_javascript_ajax)) {
946 if ($nblinetoconsume == $nblinetoconsumecursor) {
947 print
'<script>jQuery("#tablelines").removeClass("nobottom");</script>';
950 print
' '.price2num($alreadyconsumed,
'MS');
954 if (!empty($conf->global->STOCK_CONSUMPTION_FROM_MANUFACTURING_WAREHOUSE) && $tmpwarehouse->id > 0) {
955 print
img_picto(
'', $tmpwarehouse->picto).
" ".$tmpwarehouse->label;
960 print
'<td class="nowraponall right">';
962 if (!$line->disable_stock_change && $tmpproduct->stock_reel < ($line->qty - $alreadyconsumed)) {
963 print
img_warning($langs->trans(
'StockTooLow')) .
' ';
965 if (empty($conf->global->STOCK_CONSUMPTION_FROM_MANUFACTURING_WAREHOUSE) || empty($tmpwarehouse->id)) {
966 print
price2num($tmpproduct->stock_reel,
'MS');
969 $tmpproduct->load_stock();
970 $wh_stock = $tmpproduct->stock_warehouse[$tmpwarehouse->id];
971 if (!empty($wh_stock)) {
992 if ($permissiontodelete) {
993 $href = $_SERVER[
"PHP_SELF"].
'?id='.((int) $object->id).
'&action=deleteline&token='.
newToken().
'&lineid='.((int) $line->id);
994 print
'<td class="center">';
995 print
'<a class="reposition" href="'.$href.
'">';
996 print
img_picto($langs->trans(
'TooltipDeleteAndRevertStockMovement'),
'delete');
1004 foreach ($arrayoflines as $line2) {
1005 print
'<tr class="expanddetail'.$line->id.
' hideobject opacitylow">';
1009 $tmpstockmovement->id = $line2[
'fk_stock_movement'];
1010 print
'<a href="'.DOL_URL_ROOT.
'/product/stock/movement_list.php?search_ref='.$tmpstockmovement->id.
'">'.
img_picto($langs->trans(
"StockMovement"),
'movement',
'class="paddingright"').
'</a>';
1018 print
'<td class="right">'.$line2[
'qty'].
'</td>';
1021 if ($permissiontoupdatecost && !empty($conf->global->MRP_SHOW_COST_FOR_CONSUMPTION)) {
1026 print
'<td class="tdoverflowmax150">';
1027 if ($line2[
'fk_warehouse'] > 0) {
1028 $result = $tmpwarehouse->fetch($line2[
'fk_warehouse']);
1030 print $tmpwarehouse->getNomUrl(1);
1043 if ($line2[
'batch'] !=
'') {
1044 $tmpbatch->fetch(0, $line2[
'fk_product'], $line2[
'batch']);
1045 print $tmpbatch->getNomUrl(1);
1057 if ($permissiontodelete) {
1058 $href = $_SERVER[
"PHP_SELF"].
'?id='.((int) $object->id).
'&action=deleteline&token='.
newToken().
'&lineid='.((int) $line->id).
'&fk_movement='.((int) $line2[
'fk_stock_movement']);
1059 print
'<td class="center">';
1060 print
'<a class="reposition" href="'.$href.
'">';
1061 print
img_picto($langs->trans(
'TooltipDeleteAndRevertStockMovement'),
'delete');
1069 if (in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
1071 print
'<!-- Enter line to consume -->'.
"\n";
1073 print
'<tr data-max-qty="'.$maxQty.
'" name="batch_'.$line->id.
'_'.$i.
'">';
1075 print
'<td><span class="opacitymedium">'.$langs->trans(
"ToConsume").
'</span></td>';
1076 $preselected = (
GETPOSTISSET(
'qty-'.$line->id.
'-'.$i) ?
GETPOST(
'qty-'.$line->id.
'-'.$i) : max(0, $line->qty - $alreadyconsumed));
1077 if ($action ==
'consumeorproduce' && !
GETPOSTISSET(
'qty-'.$line->id.
'-'.$i)) {
1082 if (!empty($conf->global->MRP_NEVER_CONSUME_MORE_THAN_EXPECTED) && ($line->qty - $alreadyconsumed) <= 0) {
1083 $disable =
'disabled';
1087 print
'<input type="hidden" name="product-'.$line->id.
'-'.$i.
'" value="'.$line->fk_product.
'">';
1090 print
'<td class="right"><input type="text" class="width50 right" id="qtytoconsume-'.$line->id.
'-'.$i.
'" name="qty-'.$line->id.
'-'.$i.
'" value="'.$preselected.
'" '.$disable.
'></td>';
1093 if ($permissiontoupdatecost && !empty($conf->global->MRP_SHOW_COST_FOR_CONSUMPTION)) {
1103 if (empty($line->disable_stock_change)) {
1104 $preselected = (
GETPOSTISSET(
'idwarehouse-'.$line->id.
'-'.$i) ?
GETPOST(
'idwarehouse-'.$line->id.
'-'.$i) : ($tmpproduct->fk_default_warehouse > 0 ? $tmpproduct->fk_default_warehouse :
'ifone'));
1105 print $formproduct->selectWarehouses($preselected,
'idwarehouse-'.$line->id.
'-'.$i,
'', 1, 0, $line->fk_product,
'', 1, 0,
null,
'maxwidth200 csswarehouse_'.$line->id.
'_'.$i);
1107 print
'<span class="opacitymedium">'.$langs->trans(
"DisableStockChange").
'</span>';
1110 print
'<span class="opacitymedium">'.$langs->trans(
"NoStockChangeOnServices").
'</span>';
1121 print
'<td class="nowraponall">';
1122 if ($tmpproduct->status_batch) {
1123 $preselected = (
GETPOSTISSET(
'batch-'.$line->id.
'-'.$i) ?
GETPOST(
'batch-'.$line->id.
'-'.$i) :
'');
1124 print
'<input type="text" class="width75" name="batch-'.$line->id.
'-'.$i.
'" value="'.$preselected.
'" list="batch-'.$line->id.
'-'.$i.
'">';
1125 print $formproduct->selectLotDataList(
'batch-'.$line->id.
'-'.$i, 0, $line->fk_product,
'',
'');
1132 print
'<td align="right" class="split">';
1133 print
' '.img_picto($langs->trans(
'AddStockLocationLine'),
'split.png',
'class="splitbutton" onClick="addDispatchLine('.((int) $line->id).
', \''.
dol_escape_js($type).
'\', \
'qtymissingconsume\')"');
1137 print
'<td align="right" class="splitall">';
1138 if (($action ==
'consumeorproduce' || $action ==
'consumeandproduceall') && $tmpproduct->status_batch == 2) {
1139 print
img_picto($langs->trans(
'SplitAllQuantity'),
'split.png',
'class="splitbutton splitallbutton field-error-icon" data-max-qty="1" onClick="addDispatchLine('.$line->id.
', \'batch\', \'allmissingconsume\')"');
1144 if ($permissiontodelete) {
1158 print
'<script type="text/javascript">
1159 $(document).ready(function () {
1160 $("select[name=fk_default_warehouse]").change(function() {
1161 var fk_default_warehouse = $("option:selected", this).val();
1162 $("select[name^=idwarehouse-]").val(fk_default_warehouse).change();
1167 if (in_array($action, array(
'consumeorproduce',
'consumeandproduceall')) &&
1168 !empty($conf->global->STOCK_CONSUMPTION_FROM_MANUFACTURING_WAREHOUSE)) {
1169 print
'<script>$(document).ready(function () {
1170 $("#fk_default_warehouse").change();
1177 print
'<div class="fichehalfright">';
1178 print
'<div class="clearboth"></div>';
1180 $nblinetoproduce = 0;
1181 foreach ($object->lines as $line) {
1182 if ($line->role ==
'toproduce') {
1187 $newcardbutton =
'';
1188 $url = $_SERVER[
"PHP_SELF"].
'?id='.$object->id.
'&action=addproduceline&token='.
newToken();
1189 $permissiontoaddaproductline = $object->status != $object::STATUS_PRODUCED && $object->status != $object::STATUS_CANCELED;
1190 $parameters = array(
'morecss'=>
'reposition');
1191 if ($action !=
'consumeorproduce' && $action !=
'consumeandproduceall') {
1192 if ($nblinetoproduce == 0 || $object->mrptype == 1) {
1193 $newcardbutton =
dolGetButtonTitle($langs->trans(
'AddNewProduceLines'),
'',
'fa fa-plus-circle size15x', $url,
'', $permissiontoaddaproductline, $parameters);
1197 print
load_fiche_titre($langs->trans(
'Production'), $newcardbutton,
'', 0,
'',
'');
1199 print
'<div class="div-table-responsive-no-min">';
1200 print
'<table id="tablelinestoproduce" class="noborder noshadow nobottom centpercent">';
1202 print
'<tr class="liste_titre">';
1204 print
'<td>'.$langs->trans(
"Product").
'</td>';
1206 print
'<td class="right">'.$langs->trans(
"Qty").
'</td>';
1208 if ($permissiontoupdatecost) {
1209 if (empty($bomcostupdated)) {
1210 print
'<td class="right">'.$form->textwithpicto($langs->trans(
"UnitCost"), $langs->trans(
"AmountUsedToUpdateWAP")).
'</td>';
1212 print
'<td class="right">'.$form->textwithpicto($langs->trans(
"ManufacturingPrice"), $langs->trans(
"AmountUsedToUpdateWAP")).
'</td>';
1216 print
'<td class="right">'.$langs->trans(
"QtyAlreadyProduced").
'</td>';
1219 if ($collapse || in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
1220 print $langs->trans(
"Warehouse");
1227 if ($collapse || in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
1228 print $langs->trans(
"Batch");
1240 if ($permissiontodelete) {
1246 if ($action ==
'addproduceline') {
1247 print
'<!-- Add line to produce -->'.
"\n";
1248 print
'<tr class="liste_titre">';
1252 print
$form->select_produits(
'',
'productidtoadd',
'', 0, 0, -1, 2,
'', 1, array(), 0,
'1', 0,
'maxwidth300');
1255 print
'<td class="right"><input type="text" name="qtytoadd" value="1" class="width50 right"></td>';
1257 if ($permissiontoupdatecost) {
1261 print
'<td colspan="2">';
1262 print
'<input type="submit" class="button buttongen button-add" name="addproducelinebutton" value="'.$langs->trans(
"Add").
'">';
1263 print
'<input type="submit" class="button buttongen button-cancel" name="canceladdproducelinebutton" value="'.$langs->trans(
"Cancel").
'">';
1276 if ($permissiontodelete) {
1282 if (!empty($object->lines)) {
1283 $nblinetoproduce = 0;
1284 foreach ($object->lines as $line) {
1285 if ($line->role ==
'toproduce') {
1290 $nblinetoproducecursor = 0;
1291 foreach ($object->lines as $line) {
1292 if ($line->role ==
'toproduce') {
1295 $nblinetoproducecursor++;
1297 $tmpproduct =
new Product($db);
1298 $tmpproduct->fetch($line->fk_product);
1300 $arrayoflines = $object->fetchLinesLinked(
'produced', $line->id);
1301 $alreadyproduced = 0;
1302 foreach ($arrayoflines as $line2) {
1303 $alreadyproduced += $line2[
'qty'];
1306 $suffix =
'_'.$line->id;
1307 print
'<!-- Line to dispatch '.$suffix.
' -->'.
"\n";
1309 print
'<input id="qty_ordered'.$suffix.
'" type="hidden" value="'.$line->qty.
'">';
1310 print
'<input id="qty_dispatched'.$suffix.
'" type="hidden" value="'.$alreadyproduced.
'">';
1314 print
'<td>'.$tmpproduct->getNomUrl(1);
1315 print
'<br><span class="opacitymedium small">'.$tmpproduct->label.
'</span>';
1318 print
'<td class="right">'.$line->qty.
'</td>';
1320 if ($permissiontoupdatecost) {
1322 $manufacturingcost = 0;
1323 $manufacturingcostsrc =
'';
1324 if ($object->mrptype == 0) {
1325 $manufacturingcost = $bomcostupdated;
1326 $manufacturingcostsrc = $langs->trans(
"CalculatedFromProductsToConsume");
1327 if (empty($manufacturingcost)) {
1328 $manufacturingcost = $bomcost;
1329 $manufacturingcostsrc = $langs->trans(
"ValueFromBom");
1331 if (empty($manufacturingcost)) {
1332 $manufacturingcost =
price2num($tmpproduct->cost_price,
'MU');
1333 $manufacturingcostsrc = $langs->trans(
"CostPrice");
1335 if (empty($manufacturingcost)) {
1336 $manufacturingcost =
price2num($tmpproduct->pmp,
'MU');
1337 $manufacturingcostsrc = $langs->trans(
"PMPValue");
1341 print
'<td class="right nowraponall" title="'.dol_escape_htmltag($manufacturingcostsrc).
'">';
1342 if ($manufacturingcost) {
1343 print
price($manufacturingcost);
1348 print
'<td class="right nowraponall">';
1349 if ($alreadyproduced) {
1351 print
'jQuery(document).ready(function() {
1352 jQuery("#expandtoproduce'.$line->id.
'").click(function() {
1353 console.log("Expand mrp_production line '.$line->id.
'");
1354 jQuery(".expanddetailtoproduce'.$line->id.
'").toggle();';
1355 if ($nblinetoproduce == $nblinetoproducecursor) {
1356 print
'if (jQuery("#tablelinestoproduce").hasClass("nobottom")) { jQuery("#tablelinestoproduce").removeClass("nobottom"); } else { jQuery("#tablelinestoproduce").addClass("nobottom"); }';
1362 if (empty($conf->use_javascript_ajax)) {
1363 print
'<a href="'.$_SERVER[
"PHP_SELF"].
'?collapse='.$collapse.
','.$line->id.
'">';
1365 print
img_picto($langs->trans(
"ShowDetails"),
"chevron-down",
'id="expandtoproduce'.$line->id.
'"');
1366 if (empty($conf->use_javascript_ajax)) {
1370 print
' '.$alreadyproduced;
1386 if ($permissiontodelete) {
1387 if ($line->origin_type ==
'free') {
1388 $href = $_SERVER[
"PHP_SELF"];
1389 $href .=
'?id='.$object->id;
1390 $href .=
'&action=deleteline';
1391 $href .=
'&lineid='.$line->id;
1392 print
'<td class="center">';
1393 print
'<a class="reposition" href="'.$href.
'">';
1394 print
img_picto($langs->trans(
'TooltipDeleteAndRevertStockMovement'),
"delete");
1404 foreach ($arrayoflines as $line2) {
1405 print
'<tr class="expanddetailtoproduce'.$line->id.
' hideobject opacitylow">';
1408 $tmpstockmovement->id = $line2[
'fk_stock_movement'];
1409 print
'<a href="'.DOL_URL_ROOT.
'/product/stock/movement_list.php?search_ref='.$tmpstockmovement->id.
'">'.
img_picto($langs->trans(
"StockMovement"),
'movement',
'class="paddingright"').
'</a>';
1415 if ($permissiontoupdatecost) {
1419 print
'<td class="right">'.$line2[
'qty'].
'</td>';
1421 print
'<td class="tdoverflowmax150">';
1422 if ($line2[
'fk_warehouse'] > 0) {
1423 $result = $tmpwarehouse->fetch($line2[
'fk_warehouse']);
1425 print $tmpwarehouse->getNomUrl(1);
1432 if ($line2[
'batch'] !=
'') {
1433 $tmpbatch->fetch(0, $line2[
'fk_product'], $line2[
'batch']);
1434 print $tmpbatch->getNomUrl(1);
1445 if ($permissiontodelete) {
1451 if (in_array($action, array(
'consumeorproduce',
'consumeandproduceall'))) {
1452 print
'<!-- Enter line to produce -->'.
"\n";
1454 print
'<tr data-max-qty="'.$maxQty.
'" name="batch_'.$line->id.
'_'.$i.
'">';
1456 print
'<td><span class="opacitymedium">'.$langs->trans(
"ToProduce").
'</span></td>';
1457 $preselected = (
GETPOSTISSET(
'qtytoproduce-'.$line->id.
'-'.$i) ?
GETPOST(
'qtytoproduce-'.$line->id.
'-'.$i) : max(0, $line->qty - $alreadyproduced));
1458 if ($action ==
'consumeorproduce' && !
GETPOSTISSET(
'qtytoproduce-'.$line->id.
'-'.$i)) {
1462 print
'<td class="right"><input type="text" class="width50 right" id="qtytoproduce-'.$line->id.
'-'.$i.
'" name="qtytoproduce-'.$line->id.
'-'.$i.
'" value="'.$preselected.
'"></td>';
1464 if ($permissiontoupdatecost) {
1466 $manufacturingcost = 0;
1467 $manufacturingcostsrc =
'';
1468 if ($object->mrptype == 0) {
1469 $manufacturingcost = $bomcostupdated;
1470 $manufacturingcostsrc = $langs->trans(
"CalculatedFromProductsToConsume");
1471 if (empty($manufacturingcost)) {
1472 $manufacturingcost = $bomcost;
1473 $manufacturingcostsrc = $langs->trans(
"ValueFromBom");
1475 if (empty($manufacturingcost)) {
1476 $manufacturingcost =
price2num($tmpproduct->cost_price,
'MU');
1477 $manufacturingcostsrc = $langs->trans(
"CostPrice");
1479 if (empty($manufacturingcost)) {
1480 $manufacturingcost =
price2num($tmpproduct->pmp,
'MU');
1481 $manufacturingcostsrc = $langs->trans(
"PMPValue");
1486 $preselected = (
GETPOSTISSET(
'pricetoproduce-'.$line->id.
'-'.$i) ?
GETPOST(
'pricetoproduce-'.$line->id.
'-'.$i) : ($manufacturingcost ?
price($manufacturingcost) :
''));
1487 print
'<td class="right"><input type="text" class="width75 right" name="pricetoproduce-'.$line->id.
'-'.$i.
'" value="'.$preselected.
'"></td>';
1489 print
'<td><input type="hidden" class="width50 right" name="pricetoproduce-'.$line->id.
'-'.$i.
'" value="'.($manufacturingcost ? $manufacturingcost :
'').
'"></td>';
1497 $preselected = (
GETPOSTISSET(
'idwarehousetoproduce-'.$line->id.
'-'.$i) ?
GETPOST(
'idwarehousetoproduce-'.$line->id.
'-'.$i) : ($object->fk_warehouse > 0 ? $object->fk_warehouse :
'ifone'));
1498 print $formproduct->selectWarehouses($preselected,
'idwarehousetoproduce-'.$line->id.
'-'.$i,
'', 1, 0, $line->fk_product,
'', 1, 0,
null,
'maxwidth200 csswarehouse_'.$line->id.
'_'.$i);
1500 print
'<span class="opacitymedium">'.$langs->trans(
"NoStockChangeOnServices").
'</span>';
1506 if ($tmpproduct->status_batch) {
1507 $preselected = (
GETPOSTISSET(
'batchtoproduce-'.$line->id.
'-'.$i) ?
GETPOST(
'batchtoproduce-'.$line->id.
'-'.$i) :
'');
1508 print
'<input type="text" class="width75" name="batchtoproduce-'.$line->id.
'-'.$i.
'" value="'.$preselected.
'">';
1512 if ($tmpproduct->status_batch) {
1514 print
'<td align="right" class="split">';
1515 print
img_picto($langs->trans(
'AddStockLocationLine'),
'split.png',
'class="splitbutton" onClick="addDispatchLine('.$line->id.
', \''.$type.
'\', \
'qtymissing\')"');
1518 print
'<td align="right" class="splitall">';
1519 if (($action ==
'consumeorproduce' || $action ==
'consumeandproduceall') && $tmpproduct->status_batch == 2) print
img_picto($langs->trans(
'SplitAllQuantity'),
'split.png',
'class="splitbutton splitallbutton field-error-icon" onClick="addDispatchLine('.$line->id.
', \'batch\', \'alltoproduce\')"');
1544 if (in_array($action, array(
'consumeorproduce',
'consumeandproduceall',
'addconsumeline'))) {
1550 <script
type=
"text/javascript" language=
"javascript">
1552 $(document).ready(
function() {
1554 updateselectbatchbywarehouse();
1556 updateselectwarehousebybatch();
1559 function updateselectbatchbywarehouse() {
1560 $(document).on(
'change',
"select[name*='idwarehouse']",
function () {
1561 console.log(
"We change warehouse so we update the list of possible batch number");
1563 var selectwarehouse = $(
this);
1565 var selectbatch_name = selectwarehouse.attr(
'name').replace(
'idwarehouse',
'batch');
1566 var selectbatch = $(
"datalist[id*='" + selectbatch_name +
"']");
1567 var selectedbatch = selectbatch.val();
1569 var product_element_name = selectwarehouse.attr(
'name').replace(
'idwarehouse',
'product');
1573 url:
"<?php echo DOL_URL_ROOT . '/mrp/ajax/interface.php'; ?>",
1575 action:
"updateselectbatchbywarehouse",
1576 permissiontoproduce: <?php echo $permissiontoproduce ?>,
1577 warehouse_id: $(
this).val(),
1578 token:
'<?php echo currentToken(); ?>',
1579 product_id: $(
"input[name='" + product_element_name +
"']").val()
1581 }).done(
function (data) {
1583 selectbatch.empty();
1585 if (typeof data ==
"object") {
1586 console.log(
"data is already type object, no need to parse it");
1588 console.log(
"data is type "+(typeof data));
1589 data = JSON.parse(data);
1592 selectbatch.append($(
'<option>', {
1596 $.each(data,
function (key, value) {
1598 if(selectwarehouse.val() == -1) {
1599 var label =
" (<?php echo $langs->trans('Stock total') ?> : " + value +
")";
1601 var label =
" (<?php echo $langs->trans('Stock') ?> : " + value +
")";
1604 if(key === selectedbatch) {
1605 var option =
'<option value="'+key+
'" selected>'+ label +
'</option>';
1607 var option =
'<option value="'+key+
'">'+ label +
'</option>';
1610 selectbatch.append(option);
1616 function updateselectwarehousebybatch() {
1617 $(document).on(
'change',
'input[name*=batch]',
function(){
1618 console.log(
"We change batch so we update the list of possible warehouses");
1620 var selectbatch = $(
this);
1622 var selectwarehouse_name = selectbatch.attr(
'name').replace(
'batch',
'idwarehouse');
1623 var selectwarehouse = $(
"select[name*='" + selectwarehouse_name +
"']");
1624 var selectedwarehouse = selectwarehouse.val();
1626 if(selectedwarehouse != -1){
1630 var product_element_name = selectbatch.attr(
'name').replace(
'batch',
'product');
1634 url:
"<?php echo DOL_URL_ROOT . '/mrp/ajax/interface.php'; ?>",
1636 action:
"updateselectwarehousebybatch",
1637 permissiontoproduce: <?php echo $permissiontoproduce ?>,
1638 batch: $(
this).val(),
1639 token:
'<?php echo currentToken(); ?>',
1640 product_id: $(
"input[name='" + product_element_name +
"']").val()
1642 }).done(
function (data) {
1644 if (typeof data ==
"object") {
1645 console.log(
"data is already type object, no need to parse it");
1647 console.log(
"data is type "+(typeof data));
1648 data = JSON.parse(data);
1652 selectwarehouse.val(data).change();
if(GETPOST('button_removefilter_x', 'alpha')||GETPOST('button_removefilter.x', 'alpha')||GETPOST('button_removefilter', 'alpha')) if(GETPOST('button_search_x', 'alpha')||GETPOST('button_search.x', 'alpha')||GETPOST('button_search', 'alpha')) if($action=="save" &&empty($cancel)) $help_url
View.
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.
if($cancel &&! $id) if($action=='add' &&! $cancel) if($action=='delete') if($id) $form
Actions.
dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='rowid', $fieldref='ref', $morehtmlref='', $moreparam='', $nodbprefix=0, $morehtmlleft='', $morehtmlstatus='', $onlybanner=0, $morehtmlright='')
Show tab footer of a card.
load_fiche_titre($titre, $morehtmlright='', $picto='generic', $pictoisfullpath=0, $id='', $morecssontable='', $morehtmlcenter='')
Load a title with picto.
img_warning($titlealt='default', $moreatt='', $morecss='pictowarning')
Show warning logo.
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_print_date($time, $format='', $tzoutput='auto', $outputlangs='', $encodetooutput=false)
Output date in a string format according to outputlangs (or langs if not defined).
if(!function_exists('dol_getprefix')) dol_include_once($relpath, $classname='')
Make an include_once using default root and alternate root if it fails.
dol_now($mode='auto')
Return date for now.
getDolGlobalInt($key, $default=0)
Return dolibarr global constant int value.
img_picto($titlealt, $picto, $moreatt='', $pictoisfullpath=false, $srconly=0, $notitle=0, $alt='', $morecss='', $marginleftonlyshort=2)
Show picto whatever it's its name (generic function)
dol_escape_js($stringtoescape, $mode=0, $noescapebackslashn=0)
Returns text escaped for inclusion into javascript code.
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.
dol_buildpath($path, $type=0, $returnemptyifnotfound=0)
Return path of url or filesystem.
GETPOSTISSET($paramname)
Return true if we are in a context of submitting the parameter $paramname from a POST of a form.
isModEnabled($module)
Is Dolibarr module enabled.
img_edit($titlealt='default', $float=0, $other='')
Show logo editer/modifier fiche.
dol_syslog($message, $level=LOG_INFO, $ident=0, $suffixinfilename='', $restricttologhandler='', $logcontext=null)
Write log message into outputs.
$formconfirm
if ($action == 'delbookkeepingyear') {
moPrepareHead($object)
Prepare array of tabs for Mo.
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.