341 if (!DolibarrApiAccess::$user->hasRight(
'mrp',
'write')) {
342 throw new RestException(403,
'Not enough permission');
344 $result = $this->mo->fetch(
$id);
346 throw new RestException(404,
'MO not found');
349 if ($this->mo->status != Mo::STATUS_VALIDATED && $this->mo->status != Mo::STATUS_INPROGRESS) {
350 throw new RestException(405,
'Error bad status of MO');
354 require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
355 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
356 require_once DOL_DOCUMENT_ROOT.
'/mrp/lib/mrp_mo.lib.php';
363 $arraytoconsume = array();
364 $arraytoproduce = array();
366 foreach ($request_data as $field => $value) {
367 if ($field ==
'inventorylabel') {
368 $labelmovement = $value;
370 if ($field ==
'inventorycode') {
371 $codemovement = $value;
373 if ($field ==
'autoclose') {
376 if ($field ==
'arraytoconsume') {
377 $arraytoconsume = $value;
379 if ($field ==
'arraytoproduce') {
380 $arraytoproduce = $value;
382 if ($field ===
'caller') {
384 $stockmove->context[
'caller'] =
sanitizeVal($request_data[
'caller'],
'aZ09');
389 if (empty($labelmovement)) {
390 throw new RestException(500,
"Field inventorylabel not provided");
392 if (empty($codemovement)) {
393 throw new RestException(500,
"Field inventorycode not provided");
396 $consumptioncomplete =
true;
397 $productioncomplete =
true;
399 if (!empty($arraytoconsume) && !empty($arraytoproduce)) {
401 $arrayofarrayname = array(
"arraytoconsume",
"arraytoproduce");
402 foreach ($arrayofarrayname as $arrayname) {
403 foreach (${$arrayname} as $value) {
404 $tmpproduct =
new Product($this->db);
405 if (empty($value[
"objectid"])) {
406 throw new RestException(500,
"Field objectid required in ".$arrayname);
408 $tmpproduct->fetch($value[
"qty"]);
409 if (empty($value[
"qty"])) {
410 throw new RestException(500,
"Field qty required in ".$arrayname);
412 if ($value[
"qty"] != 0) {
413 $qtytoprocess = $value[
"qty"];
414 if (isset($value[
"fk_warehouse"])) {
415 if (!($value[
"fk_warehouse"] > 0)) {
417 throw new RestException(500,
"Field fk_warehouse must be > 0 in ".$arrayname);
419 if ($tmpproduct->status_batch) {
421 throw new RestException(500,
"Product ".$tmpproduct->ref.
"must be in batch");
425 if (!$error && $value[
"fk_warehouse"] > 0) {
427 $id_product_batch = 0;
429 $stockmove->setOrigin($this->mo->element, $this->mo->id);
431 if ($arrayname ==
'arraytoconsume') {
432 $moline =
new MoLine($this->db);
433 $moline->fk_mo = $this->mo->id;
434 $moline->position = $pos;
435 $moline->fk_product = $value[
"objectid"];
436 $moline->fk_warehouse = $value[
"fk_warehouse"];
437 $moline->qty = $qtytoprocess;
438 $moline->batch = (string) $tmpproduct->status_batch;
439 $moline->role =
'toproduce';
440 $moline->fk_mrp_production = 0;
441 $moline->fk_stock_movement = $idstockmove;
442 $moline->fk_user_creat = DolibarrApiAccess::$user->id;
444 $resultmoline = $moline->create(DolibarrApiAccess::$user);
445 if ($resultmoline <= 0) {
447 throw new RestException(500, $moline->error);
449 $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $value[
"objectid"], $value[
"fk_warehouse"], $qtytoprocess, 0, $labelmovement,
dol_now(),
'',
'', (
string) $tmpproduct->status_batch, $id_product_batch, $codemovement);
451 $moline =
new MoLine($this->db);
452 $moline->fk_mo = $this->mo->id;
453 $moline->position = $pos;
454 $moline->fk_product = $value[
"objectid"];
455 $moline->fk_warehouse = $value[
"fk_warehouse"];
456 $moline->qty = $qtytoprocess;
457 $moline->batch = (string) $tmpproduct->status_batch;
458 $moline->role =
'toconsume';
459 $moline->fk_mrp_production = 0;
460 $moline->fk_stock_movement = $idstockmove;
461 $moline->fk_user_creat = DolibarrApiAccess::$user->id;
463 $resultmoline = $moline->create(DolibarrApiAccess::$user);
464 if ($resultmoline <= 0) {
466 throw new RestException(500, $moline->error);
468 $idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $value[
"objectid"], $value[
"fk_warehouse"], $qtytoprocess, 0, $labelmovement,
'',
'', (
string) $tmpproduct->status_batch,
dol_now(), $id_product_batch, $codemovement);
470 if ($idstockmove < 0) {
472 throw new RestException(500, $stockmove->error);
477 $moline =
new MoLine($this->db);
478 $moline->fk_mo = $this->mo->id;
479 $moline->position = $pos;
480 $moline->fk_product = $value[
"objectid"];
481 $moline->fk_warehouse = $value[
"fk_warehouse"];
482 $moline->qty = $qtytoprocess;
483 $moline->batch = (string) $tmpproduct->status_batch;
484 if ($arrayname ==
"arraytoconsume") {
485 $moline->role =
'consumed';
487 $moline->role =
'produced';
489 $moline->fk_mrp_production = 0;
490 $moline->fk_stock_movement = $idstockmove;
491 $moline->fk_user_creat = DolibarrApiAccess::$user->id;
493 $resultmoline = $moline->create(DolibarrApiAccess::$user);
494 if ($resultmoline <= 0) {
496 throw new RestException(500, $moline->error);
505 if ($autoclose <= 0) {
506 $consumptioncomplete =
false;
507 $productioncomplete =
false;
512 foreach ($this->mo->lines as $line) {
513 if ($line->role ==
'toconsume') {
514 $tmpproduct =
new Product($this->db);
515 $tmpproduct->fetch($line->fk_product);
516 if ($line->qty != 0) {
517 $qtytoprocess = $line->qty;
518 if (isset($line->fk_warehouse)) {
519 if (!($line->fk_warehouse > 0)) {
520 $langs->load(
"errors");
522 throw new RestException(500, $langs->trans(
"ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv(
"Warehouse"), $tmpproduct->ref));
524 if ($tmpproduct->status_batch) {
525 $langs->load(
"errors");
527 throw new RestException(500, $langs->trans(
"ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv(
"Batch"), $tmpproduct->ref));
531 if (!$error && $line->fk_warehouse > 0) {
533 $id_product_batch = 0;
534 $stockmove->origin_type =
'mo';
535 $stockmove->origin_id = $this->mo->id;
536 if ($qtytoprocess >= 0) {
537 $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $line->fk_product, $line->fk_warehouse, $qtytoprocess, 0, $labelmovement,
dol_now(),
'',
'', (
string) $tmpproduct->status_batch, $id_product_batch, $codemovement);
539 $idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $line->fk_product, $line->fk_warehouse, $qtytoprocess, 0, $labelmovement,
'',
'', (
string) $tmpproduct->status_batch,
dol_now(), $id_product_batch, $codemovement);
541 if ($idstockmove < 0) {
543 throw new RestException(500, $stockmove->error);
548 $moline =
new MoLine($this->db);
549 $moline->fk_mo = $this->mo->id;
550 $moline->position = $pos;
551 $moline->fk_product = $line->fk_product;
552 $moline->fk_warehouse = $line->fk_warehouse;
553 $moline->qty = $qtytoprocess;
554 $moline->batch = (string) $tmpproduct->status_batch;
555 $moline->role =
'consumed';
556 $moline->fk_mrp_production = $line->id;
557 $moline->fk_stock_movement = $idstockmove;
558 $moline->fk_user_creat = DolibarrApiAccess::$user->id;
560 $resultmoline = $moline->create(DolibarrApiAccess::$user);
561 if ($resultmoline <= 0) {
563 throw new RestException(500, $moline->error);
572 foreach ($this->mo->lines as $line) {
573 if ($line->role ==
'toproduce') {
574 $tmpproduct =
new Product($this->db);
575 $tmpproduct->fetch($line->fk_product);
576 if ($line->qty != 0) {
577 $qtytoprocess = $line->qty;
578 if (isset($line->fk_warehouse)) {
579 if (!($line->fk_warehouse > 0)) {
580 $langs->load(
"errors");
582 throw new RestException(500, $langs->trans(
"ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv(
"Warehouse"), $tmpproduct->ref));
584 if ($tmpproduct->status_batch) {
585 $langs->load(
"errors");
587 throw new RestException(500, $langs->trans(
"ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv(
"Batch"), $tmpproduct->ref));
591 if (!$error && $line->fk_warehouse > 0) {
593 $id_product_batch = 0;
594 $stockmove->origin_type =
'mo';
595 $stockmove->origin_id = $this->mo->id;
596 if ($qtytoprocess >= 0) {
597 $idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $line->fk_product, $line->fk_warehouse, $qtytoprocess, 0, $labelmovement,
'',
'', (
string) $tmpproduct->status_batch,
dol_now(), $id_product_batch, $codemovement);
599 $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $line->fk_product, $line->fk_warehouse, $qtytoprocess, 0, $labelmovement,
dol_now(),
'',
'', (
string) $tmpproduct->status_batch, $id_product_batch, $codemovement);
601 if ($idstockmove < 0) {
603 throw new RestException(500, $stockmove->error);
608 $moline =
new MoLine($this->db);
609 $moline->fk_mo = $this->mo->id;
610 $moline->position = $pos;
611 $moline->fk_product = $line->fk_product;
612 $moline->fk_warehouse = $line->fk_warehouse;
613 $moline->qty = $qtytoprocess;
614 $moline->batch = (string) $tmpproduct->status_batch;
615 $moline->role =
'produced';
616 $moline->fk_mrp_production = $line->id;
617 $moline->fk_stock_movement = $idstockmove;
618 $moline->fk_user_creat = DolibarrApiAccess::$user->id;
620 $resultmoline = $moline->create(DolibarrApiAccess::$user);
621 if ($resultmoline <= 0) {
623 throw new RestException(500, $moline->error);
633 if ($autoclose > 0) {
634 foreach ($this->mo->lines as $line) {
635 if ($line->role ==
'toconsume') {
636 $arrayoflines = $this->mo->fetchLinesLinked(
'consumed', $line->id);
637 $alreadyconsumed = 0;
638 foreach ($arrayoflines as $line2) {
639 $alreadyconsumed += $line2[
'qty'];
642 if ($alreadyconsumed < $line->qty) {
643 $consumptioncomplete =
false;
646 if ($line->role ==
'toproduce') {
647 $arrayoflines = $this->mo->fetchLinesLinked(
'produced', $line->id);
648 $alreadyproduced = 0;
649 foreach ($arrayoflines as $line2) {
650 $alreadyproduced += $line2[
'qty'];
653 if ($alreadyproduced < $line->qty) {
654 $productioncomplete =
false;
659 $consumptioncomplete =
false;
660 $productioncomplete =
false;
666 dol_syslog(
"consumptioncomplete = ".json_encode($consumptioncomplete).
" productioncomplete = ".json_encode($productioncomplete));
667 if ($consumptioncomplete && $productioncomplete) {
668 $result = $this->mo->setStatut(Mo::STATUS_PRODUCED, 0,
'',
'MRP_MO_PRODUCED');
670 $result = $this->mo->setStatut(Mo::STATUS_INPROGRESS, 0,
'',
'MRP_MO_PRODUCED');
673 throw new RestException(500, $this->mo->error);
676 return $this->mo->id;
715 if (!DolibarrApiAccess::$user->hasRight(
"mrp",
"write")) {
716 throw new RestException(403,
'Not enough permission');
718 $result = $this->mo->fetch(
$id);
720 throw new RestException(404,
'MO not found');
723 if ($this->mo->status != Mo::STATUS_VALIDATED && $this->mo->status != Mo::STATUS_INPROGRESS) {
724 throw new RestException(405,
'Error bad status of MO');
728 require_once DOL_DOCUMENT_ROOT.
'/product/class/product.class.php';
729 require_once DOL_DOCUMENT_ROOT.
'/product/stock/class/mouvementstock.class.php';
730 require_once DOL_DOCUMENT_ROOT.
'/mrp/lib/mrp_mo.lib.php';
737 $arraytoconsume = array();
738 $arraytoproduce = array();
740 foreach ($request_data as $field => $value) {
741 if ($field ==
'inventorylabel') {
742 $labelmovement = $value;
744 if ($field ==
'inventorycode') {
745 $codemovement = $value;
747 if ($field ==
'autoclose') {
750 if ($field ==
'arraytoconsume') {
751 $arraytoconsume = $value;
753 if ($field ==
'arraytoproduce') {
754 $arraytoproduce = $value;
756 if ($field ===
'caller') {
758 $stockmove->context[
'caller'] = $request_data[
'caller'];
763 if (empty($labelmovement)) {
764 throw new RestException(500,
"Field inventorylabel not provided");
766 if (empty($codemovement)) {
767 throw new RestException(500,
"Field inventorycode not provided");
773 $arrayofarrayname = array(
"arraytoconsume",
"arraytoproduce");
774 foreach ($arrayofarrayname as $arrayname) {
775 foreach (${$arrayname} as $value) {
776 if (empty($value[
"objectid"])) {
777 throw new RestException(500,
"Field objectid required in " . $arrayname);
780 $molinetoprocess =
new MoLine($this->db);
781 $tmpmolineid = $molinetoprocess->fetch($value[
"objectid"]);
782 if ($tmpmolineid <= 0) {
783 throw new RestException(500,
"MoLine with rowid " . $value[
"objectid"] .
" not exist.");
786 $tmpproduct =
new Product($this->db);
787 $tmpproduct->fetch($molinetoprocess->fk_product);
788 if ($tmpproduct->status_batch) {
789 throw new RestException(500,
"Product " . $tmpproduct->ref .
" must be in batch, this API can't handle it currently.");
792 if (empty($value[
"qty"]) && $value[
"qty"] != 0) {
793 throw new RestException(500,
"Field qty with lower or higher then 0 required in " . $arrayname);
795 $qtytoprocess = $value[
"qty"];
797 $fk_warehousetoprocess = 0;
798 if ($molinetoprocess->disable_stock_change ==
false) {
799 if (isset($value[
"fk_warehouse"])) {
800 if (!($value[
"fk_warehouse"] > 0)) {
801 throw new RestException(500,
"Field fk_warehouse required in " . $arrayname);
804 $fk_warehousetoprocess = (int) $value[
"fk_warehouse"];
808 if (isset($value[
"pricetoproduce"])) {
809 if ($value[
"pricetoproduce"] > 0) {
810 $pricetoproduce = $value[
"pricetoproduce"];
816 if ($molinetoprocess->disable_stock_change ==
false) {
818 $id_product_batch = 0;
819 $stockmove->origin_type =
'mo';
820 $stockmove->origin_id = $this->mo->id;
821 if ($arrayname ==
"arraytoconsume") {
822 if ($qtytoprocess >= 0) {
823 $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $molinetoprocess->fk_product, $fk_warehousetoprocess, $qtytoprocess, 0, $labelmovement,
dol_now(),
'',
'', (string) $tmpproduct->status_batch, $id_product_batch, $codemovement);
825 $idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $molinetoprocess->fk_product, $fk_warehousetoprocess, $qtytoprocess, 0, $labelmovement,
'',
'', (
string) $tmpproduct->status_batch,
dol_now(), $id_product_batch, $codemovement);
828 if ($qtytoprocess >= 0) {
829 $idstockmove = $stockmove->reception(DolibarrApiAccess::$user, $molinetoprocess->fk_product, $fk_warehousetoprocess, $qtytoprocess, $pricetoproduce, $labelmovement,
'',
'', (
string) $tmpproduct->status_batch,
dol_now(), $id_product_batch, $codemovement);
831 $idstockmove = $stockmove->livraison(DolibarrApiAccess::$user, $molinetoprocess->fk_product, $fk_warehousetoprocess, $qtytoprocess, 0, $labelmovement,
dol_now(),
'',
'', (string) $tmpproduct->status_batch, $id_product_batch, $codemovement);
834 if ($idstockmove <= 0) {
835 throw new RestException(500, $stockmove->error);
840 $moline =
new MoLine($this->db);
841 $moline->fk_mo = $this->mo->id;
842 $moline->position = $pos;
843 $moline->fk_product = $tmpproduct->id;
844 $moline->fk_warehouse = $idstockmove > 0 ? $fk_warehousetoprocess :
null;
845 $moline->qty = $qtytoprocess;
847 $moline->fk_mrp_production = $molinetoprocess->id;
848 $moline->fk_stock_movement = $idstockmove > 0 ? $idstockmove :
null;
849 $moline->fk_user_creat = DolibarrApiAccess::$user->id;
851 if ($arrayname ==
"arraytoconsume") {
852 $moline->role =
'consumed';
854 $moline->role =
'produced';
857 $resultmoline = $moline->create(DolibarrApiAccess::$user);
858 if ($resultmoline <= 0) {
859 throw new RestException(500, $moline->error);
866 $consumptioncomplete =
true;
867 $productioncomplete =
true;
869 if ($autoclose > 0) {
871 $this->mo->fetchLines();
873 foreach ($this->mo->lines as $line) {
874 if ($line->role ==
'toconsume') {
875 $arrayoflines = $this->mo->fetchLinesLinked(
'consumed', $line->id);
876 $alreadyconsumed = 0;
877 foreach ($arrayoflines as $line2) {
878 $alreadyconsumed += $line2[
'qty'];
881 if ($alreadyconsumed < $line->qty) {
882 $consumptioncomplete =
false;
885 if ($line->role ==
'toproduce') {
886 $arrayoflines = $this->mo->fetchLinesLinked(
'produced', $line->id);
887 $alreadyproduced = 0;
888 foreach ($arrayoflines as $line2) {
889 $alreadyproduced += $line2[
'qty'];
892 if ($alreadyproduced < $line->qty) {
893 $productioncomplete =
false;
898 $consumptioncomplete =
false;
899 $productioncomplete =
false;
903 dol_syslog(
"consumptioncomplete = " . (
string) $consumptioncomplete .
" productioncomplete = " . (
string) $productioncomplete);
905 if ($consumptioncomplete && $productioncomplete) {
906 $result = $this->mo->setStatut(Mo::STATUS_PRODUCED, 0,
'',
'MRP_MO_PRODUCED');
908 $result = $this->mo->setStatut(Mo::STATUS_INPROGRESS, 0,
'',
'MRP_MO_PRODUCED');
911 throw new RestException(500, $this->mo->error);
915 return $this->mo->id;