420 if (!DolibarrApiAccess::$user->hasRight(
'mrp',
'write')) {
421 throw new RestException(403,
'Not enough permission');
423 $result = $this->mo->fetch(
$id);
425 throw new RestException(404,
'MO not found');
428 if ($this->mo->status != Mo::STATUS_VALIDATED && $this->mo->status != Mo::STATUS_INPROGRESS) {
429 throw new RestException(405,
'Error bad status of MO');
433 require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
434 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
435 require_once DOL_DOCUMENT_ROOT.
'/mrp/lib/mrp_mo.lib.php';
442 $arraytoconsume = array();
443 $arraytoproduce = array();
445 foreach ($request_data as $field => $value) {
446 if ($field ==
'inventorylabel') {
447 $labelmovement = $value;
449 if ($field ==
'inventorycode') {
450 $codemovement = $value;
452 if ($field ==
'autoclose') {
455 if ($field ==
'arraytoconsume') {
456 $arraytoconsume = $value;
458 if ($field ==
'arraytoproduce') {
459 $arraytoproduce = $value;
461 if ($field ===
'caller') {
463 $stockmove->context[
'caller'] =
sanitizeVal($request_data[
'caller'],
'aZ09');
468 if (empty($labelmovement)) {
469 throw new RestException(500,
"Field inventorylabel not provided");
471 if (empty($codemovement)) {
472 throw new RestException(500,
"Field inventorycode not provided");
475 $consumptioncomplete =
true;
476 $productioncomplete =
true;
478 if (!empty($arraytoconsume) && !empty($arraytoproduce)) {
480 $arrayofarrayname = array(
"arraytoconsume",
"arraytoproduce");
481 foreach ($arrayofarrayname as $arrayname) {
482 foreach (${$arrayname} as $value) {
483 $tmpproduct =
new Product($this->db);
484 if (empty($value[
"objectid"])) {
485 throw new RestException(500,
"Field objectid required in ".$arrayname);
487 $tmpproduct->fetch($value[
"objectid"]);
488 if (empty($value[
"qty"])) {
489 throw new RestException(500,
"Field qty required in ".$arrayname);
491 if ($value[
"qty"] != 0) {
492 $qtytoprocess = $value[
"qty"];
493 if (isset($value[
"fk_warehouse"])) {
494 if (!($value[
"fk_warehouse"] > 0)) {
496 throw new RestException(500,
"Field fk_warehouse must be > 0 in ".$arrayname);
498 if ($tmpproduct->status_batch) {
500 throw new RestException(500,
"Product ".$tmpproduct->ref.
"must be in batch");
504 if (!$error && $value[
"fk_warehouse"] > 0) {
506 $id_product_batch = 0;
508 $stockmove->setOrigin($this->mo->element, $this->mo->id);
512 if ($arrayname ==
'arraytoconsume') {
513 $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $value[
"objectid"], $value[
"fk_warehouse"], $qtytoprocess, 0, $labelmovement,
dol_now(),
'',
'', (
string) $tmpproduct->status_batch, $id_product_batch, $codemovement);
515 $idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $value[
"objectid"], $value[
"fk_warehouse"], $qtytoprocess, 0, $labelmovement,
'',
'', (
string) $tmpproduct->status_batch,
dol_now(), $id_product_batch, $codemovement);
517 if ($idstockmove < 0) {
519 throw new RestException(500, $stockmove->error);
522 $moline =
new MoLine($this->db);
523 $moline->fk_mo = $this->mo->id;
524 $moline->position = $pos;
525 $moline->fk_product = $value[
"objectid"];
526 $moline->fk_warehouse = (int) $value[
"fk_warehouse"];
527 $moline->qty = $qtytoprocess;
528 $moline->batch = (
string) $tmpproduct->status_batch;
529 $moline->role = ($arrayname ==
'arraytoconsume' ?
'toproduce' :
'toconsume');
530 $moline->fk_mrp_production = 0;
531 $moline->fk_stock_movement = $idstockmove > 0 ? $idstockmove :
null;
532 $moline->fk_user_creat = DolibarrApiAccess::$user->id;
534 $resultmoline = $moline->create(DolibarrApiAccess::$user);
535 if ($resultmoline <= 0) {
537 throw new RestException(500, $moline->error ? $moline->error : implode(
', ', $moline->errors));
542 $moline =
new MoLine($this->db);
543 $moline->fk_mo = $this->mo->id;
544 $moline->position = $pos;
545 $moline->fk_product = $value[
"objectid"];
546 $moline->fk_warehouse = $value[
"fk_warehouse"];
547 $moline->qty = $qtytoprocess;
548 $moline->batch = (
string) $tmpproduct->status_batch;
549 if ($arrayname ==
"arraytoconsume") {
550 $moline->role =
'consumed';
552 $moline->role =
'produced';
554 $moline->fk_mrp_production = 0;
555 $moline->fk_stock_movement = $idstockmove > 0 ? $idstockmove :
null;
556 $moline->fk_user_creat = DolibarrApiAccess::$user->id;
558 $resultmoline = $moline->create(DolibarrApiAccess::$user);
559 if ($resultmoline <= 0) {
561 throw new RestException(500, $moline->error ? $moline->error : implode(
', ', $moline->errors));
570 if ($autoclose <= 0) {
571 $consumptioncomplete =
false;
572 $productioncomplete =
false;
577 foreach ($this->mo->lines as $line) {
578 if ($line->role ==
'toconsume') {
579 $tmpproduct =
new Product($this->db);
580 $tmpproduct->fetch($line->fk_product);
581 if ($line->qty != 0) {
582 $qtytoprocess = $line->qty;
583 if (isset($line->fk_warehouse)) {
584 if (!($line->fk_warehouse > 0)) {
585 $langs->load(
"errors");
587 throw new RestException(500, $langs->trans(
"ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv(
"Warehouse"), (
string) $tmpproduct->ref));
589 if ($tmpproduct->status_batch) {
590 $langs->load(
"errors");
592 throw new RestException(500, $langs->trans(
"ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv(
"Batch"), (
string) $tmpproduct->ref));
596 if (!$error && $line->fk_warehouse > 0) {
598 $id_product_batch = 0;
599 $stockmove->origin_type =
'mo';
600 $stockmove->origin_id = $this->mo->id;
601 if ($qtytoprocess >= 0) {
602 $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $line->fk_product, (
int) $line->fk_warehouse, $qtytoprocess, 0, $labelmovement,
dol_now(),
'',
'', (
string) $tmpproduct->status_batch, $id_product_batch, $codemovement);
604 $idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $line->fk_product, (
int) $line->fk_warehouse, $qtytoprocess, 0, $labelmovement,
'',
'', (
string) $tmpproduct->status_batch,
dol_now(), $id_product_batch, $codemovement);
606 if ($idstockmove < 0) {
608 throw new RestException(500, $stockmove->error);
613 $moline =
new MoLine($this->db);
614 $moline->fk_mo = $this->mo->id;
615 $moline->position = $pos;
616 $moline->fk_product = $line->fk_product;
617 $moline->fk_warehouse = $line->fk_warehouse;
618 $moline->qty = $qtytoprocess;
619 $moline->batch = (
string) $tmpproduct->status_batch;
620 $moline->role =
'consumed';
621 $moline->fk_mrp_production = $line->id;
622 $moline->fk_stock_movement = $idstockmove;
623 $moline->fk_user_creat = DolibarrApiAccess::$user->id;
625 $resultmoline = $moline->create(DolibarrApiAccess::$user);
626 if ($resultmoline <= 0) {
628 throw new RestException(500, $moline->error);
637 foreach ($this->mo->lines as $line) {
638 if ($line->role ==
'toproduce') {
639 $tmpproduct =
new Product($this->db);
640 $tmpproduct->fetch($line->fk_product);
641 if ($line->qty != 0) {
642 $qtytoprocess = $line->qty;
643 if (isset($line->fk_warehouse)) {
644 if (!($line->fk_warehouse > 0)) {
645 $langs->load(
"errors");
647 throw new RestException(500, $langs->trans(
"ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv(
"Warehouse"), (
string) $tmpproduct->ref));
649 if ($tmpproduct->status_batch) {
650 $langs->load(
"errors");
652 throw new RestException(500, $langs->trans(
"ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv(
"Batch"), (
string) $tmpproduct->ref));
656 if (!$error && $line->fk_warehouse > 0) {
658 $id_product_batch = 0;
659 $stockmove->origin_type =
'mo';
660 $stockmove->origin_id = $this->mo->id;
661 if ($qtytoprocess >= 0) {
669 foreach ($this->mo->lines as $consumedline) {
670 if ($consumedline->role ==
'toconsume') {
671 $consumedproduct =
new Product($this->db);
672 $consumedproduct->fetch($consumedline->fk_product);
673 $consumedcost =
price2num(!empty($consumedproduct->cost_price) ? $consumedproduct->cost_price : $consumedproduct->pmp);
674 if (empty($consumedcost)) {
675 require_once DOL_DOCUMENT_ROOT.
'/fourn/class/fournisseur.product.class.php';
677 if ($productFournisseur->find_min_price_product_fournisseur($consumedline->fk_product, $consumedline->qty) > 0) {
678 $consumedcost = $productFournisseur->fourn_unitprice;
681 $mfgcost +=
price2num(($consumedline->qty * $consumedcost) / ($this->mo->qty > 0 ? $this->mo->qty : 1),
'MU');
684 $mfgcost = (float)
price2num($mfgcost,
'MU');
685 $idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $line->fk_product, (
int) $line->fk_warehouse, $qtytoprocess, $mfgcost, $labelmovement,
'',
'', (
string) $tmpproduct->status_batch,
dol_now(), $id_product_batch, $codemovement);
687 $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $line->fk_product, (
int) $line->fk_warehouse, $qtytoprocess, 0, $labelmovement,
dol_now(),
'',
'', (
string) $tmpproduct->status_batch, $id_product_batch, $codemovement);
689 if ($idstockmove < 0) {
691 throw new RestException(500, $stockmove->error);
696 $moline =
new MoLine($this->db);
697 $moline->fk_mo = $this->mo->id;
698 $moline->position = $pos;
699 $moline->fk_product = $line->fk_product;
700 $moline->fk_warehouse = $line->fk_warehouse;
701 $moline->qty = $qtytoprocess;
702 $moline->batch = (
string) $tmpproduct->status_batch;
703 $moline->role =
'produced';
704 $moline->fk_mrp_production = $line->id;
705 $moline->fk_stock_movement = $idstockmove;
706 $moline->fk_user_creat = DolibarrApiAccess::$user->id;
708 $resultmoline = $moline->create(DolibarrApiAccess::$user);
709 if ($resultmoline <= 0) {
711 throw new RestException(500, $moline->error);
721 if ($autoclose > 0) {
722 foreach ($this->mo->lines as $line) {
723 if ($line->role ==
'toconsume') {
724 $arrayoflines = $this->mo->fetchLinesLinked(
'consumed', $line->id);
725 $alreadyconsumed = 0;
726 foreach ($arrayoflines as $line2) {
727 $alreadyconsumed += $line2[
'qty'];
730 if ($alreadyconsumed < $line->qty) {
731 $consumptioncomplete =
false;
734 if ($line->role ==
'toproduce') {
735 $arrayoflines = $this->mo->fetchLinesLinked(
'produced', $line->id);
736 $alreadyproduced = 0;
737 foreach ($arrayoflines as $line2) {
738 $alreadyproduced += $line2[
'qty'];
741 if ($alreadyproduced < $line->qty) {
742 $productioncomplete =
false;
747 $consumptioncomplete =
false;
748 $productioncomplete =
false;
754 dol_syslog(
"consumptioncomplete = ".json_encode($consumptioncomplete).
" productioncomplete = ".json_encode($productioncomplete));
755 if ($consumptioncomplete && $productioncomplete) {
756 $result = $this->mo->setStatut(Mo::STATUS_PRODUCED, 0,
'',
'MRP_MO_PRODUCED');
758 $result = $this->mo->setStatut(Mo::STATUS_INPROGRESS, 0,
'',
'MRP_MO_PRODUCED');
761 throw new RestException(500, $this->mo->error);
764 return $this->mo->id;
803 if (!DolibarrApiAccess::$user->hasRight(
"mrp",
"write")) {
804 throw new RestException(403,
'Not enough permission');
806 $result = $this->mo->fetch(
$id);
808 throw new RestException(404,
'MO not found');
811 if ($this->mo->status != Mo::STATUS_VALIDATED && $this->mo->status != Mo::STATUS_INPROGRESS) {
812 throw new RestException(405,
'Error bad status of MO');
816 require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
817 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
818 require_once DOL_DOCUMENT_ROOT.
'/mrp/lib/mrp_mo.lib.php';
825 $arraytoconsume = array();
826 $arraytoproduce = array();
828 foreach ($request_data as $field => $value) {
829 if ($field ==
'inventorylabel') {
830 $labelmovement = $value;
832 if ($field ==
'inventorycode') {
833 $codemovement = $value;
835 if ($field ==
'autoclose') {
838 if ($field ==
'arraytoconsume') {
839 $arraytoconsume = $value;
841 if ($field ==
'arraytoproduce') {
842 $arraytoproduce = $value;
844 if ($field ===
'caller') {
846 $stockmove->context[
'caller'] = $request_data[
'caller'];
851 if (empty($labelmovement)) {
852 throw new RestException(500,
"Field inventorylabel not provided");
854 if (empty($codemovement)) {
855 throw new RestException(500,
"Field inventorycode not provided");
861 $arrayofarrayname = array(
"arraytoconsume",
"arraytoproduce");
862 foreach ($arrayofarrayname as $arrayname) {
863 foreach (${$arrayname} as $value) {
864 if (empty($value[
"objectid"])) {
865 throw new RestException(500,
"Field objectid required in " . $arrayname);
868 $molinetoprocess =
new MoLine($this->db);
869 $tmpmolineid = $molinetoprocess->fetch($value[
"objectid"]);
870 if ($tmpmolineid <= 0) {
871 throw new RestException(500,
"MoLine with rowid " . $value[
"objectid"] .
" not exist.");
874 $tmpproduct =
new Product($this->db);
875 $tmpproduct->fetch($molinetoprocess->fk_product);
876 if ($tmpproduct->status_batch) {
877 throw new RestException(500,
"Product " . $tmpproduct->ref .
" must be in batch, this API can't handle it currently.");
880 if (empty($value[
"qty"]) && $value[
"qty"] != 0) {
881 throw new RestException(500,
"Field qty with lower or higher then 0 required in " . $arrayname);
883 $qtytoprocess = $value[
"qty"];
885 $fk_warehousetoprocess = 0;
886 if ($molinetoprocess->disable_stock_change ==
false) {
887 if (isset($value[
"fk_warehouse"])) {
888 if (!($value[
"fk_warehouse"] > 0)) {
889 throw new RestException(500,
"Field fk_warehouse required in " . $arrayname);
892 $fk_warehousetoprocess = (int) $value[
"fk_warehouse"];
896 if (isset($value[
"pricetoproduce"])) {
897 if ($value[
"pricetoproduce"] > 0) {
898 $pricetoproduce = $value[
"pricetoproduce"];
904 if ($molinetoprocess->disable_stock_change ==
false) {
906 $id_product_batch = 0;
907 $stockmove->origin_type =
'mo';
908 $stockmove->origin_id = $this->mo->id;
909 if ($arrayname ==
"arraytoconsume") {
910 if ($qtytoprocess >= 0) {
911 $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $molinetoprocess->fk_product, $fk_warehousetoprocess, $qtytoprocess, 0, $labelmovement,
dol_now(),
'',
'', (
string) $tmpproduct->status_batch, $id_product_batch, $codemovement);
913 $idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $molinetoprocess->fk_product, $fk_warehousetoprocess, $qtytoprocess, 0, $labelmovement,
'',
'', (
string) $tmpproduct->status_batch,
dol_now(), $id_product_batch, $codemovement);
916 if ($qtytoprocess >= 0) {
917 $idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $molinetoprocess->fk_product, $fk_warehousetoprocess, $qtytoprocess, $pricetoproduce, $labelmovement,
'',
'', (
string) $tmpproduct->status_batch,
dol_now(), $id_product_batch, $codemovement);
919 $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $molinetoprocess->fk_product, $fk_warehousetoprocess, $qtytoprocess, 0, $labelmovement,
dol_now(),
'',
'', (
string) $tmpproduct->status_batch, $id_product_batch, $codemovement);
922 if ($idstockmove <= 0) {
923 throw new RestException(500, $stockmove->error);
928 $moline =
new MoLine($this->db);
929 $moline->fk_mo = $this->mo->id;
930 $moline->position = $pos;
931 $moline->fk_product = $tmpproduct->id;
932 $moline->fk_warehouse = $idstockmove > 0 ? $fk_warehousetoprocess :
null;
933 $moline->qty = $qtytoprocess;
935 $moline->fk_mrp_production = $molinetoprocess->id;
936 $moline->fk_stock_movement = $idstockmove > 0 ? $idstockmove :
null;
937 $moline->fk_user_creat = DolibarrApiAccess::$user->id;
939 if ($arrayname ==
"arraytoconsume") {
940 $moline->role =
'consumed';
942 $moline->role =
'produced';
945 $resultmoline = $moline->create(DolibarrApiAccess::$user);
946 if ($resultmoline <= 0) {
947 throw new RestException(500, $moline->error);
954 $consumptioncomplete =
true;
955 $productioncomplete =
true;
957 if ($autoclose > 0) {
959 $this->mo->fetchLines();
961 foreach ($this->mo->lines as $line) {
962 if ($line->role ==
'toconsume') {
963 $arrayoflines = $this->mo->fetchLinesLinked(
'consumed', $line->id);
964 $alreadyconsumed = 0;
965 foreach ($arrayoflines as $line2) {
966 $alreadyconsumed += $line2[
'qty'];
969 if ($alreadyconsumed < $line->qty) {
970 $consumptioncomplete =
false;
973 if ($line->role ==
'toproduce') {
974 $arrayoflines = $this->mo->fetchLinesLinked(
'produced', $line->id);
975 $alreadyproduced = 0;
976 foreach ($arrayoflines as $line2) {
977 $alreadyproduced += $line2[
'qty'];
980 if ($alreadyproduced < $line->qty) {
981 $productioncomplete =
false;
986 $consumptioncomplete =
false;
987 $productioncomplete =
false;
991 dol_syslog(
"consumptioncomplete = " . (
string) $consumptioncomplete .
" productioncomplete = " . (
string) $productioncomplete);
993 if ($consumptioncomplete && $productioncomplete) {
994 $result = $this->mo->setStatut(Mo::STATUS_PRODUCED, 0,
'',
'MRP_MO_PRODUCED');
996 $result = $this->mo->setStatut(Mo::STATUS_INPROGRESS, 0,
'',
'MRP_MO_PRODUCED');
999 throw new RestException(500, $this->mo->error);
1002 $this->db->commit();
1003 return $this->mo->id;