diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 53f9e57fceb..db7fa8330bf 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -223,6 +223,7 @@ ErrorSearchCriteriaTooSmall=Search criteria too small. ErrorObjectMustHaveStatusActiveToBeDisabled=Objects must have status 'Active' to be disabled ErrorObjectMustHaveStatusDraftOrDisabledToBeActivated=Objects must have status 'Draft' or 'Disabled' to be enabled ErrorNoFieldWithAttributeShowoncombobox=No fields has property 'showoncombobox' into definition of object '%s'. No way to show the combolist. +ErrorFieldRequiredForProduct=Field '%s' is required for product %s # Warnings WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup. WarningPasswordSetWithNoAccount=A password was set for this member. However, no user account was created. So this password is stored but can't be used to login to Dolibarr. It may be used by an external module/interface but if you don't need to define any login nor password for a member, you can disable option "Manage a login for each member" from Member module setup. If you need to manage a login but don't need any password, you can keep this field empty to avoid this warning. Note: Email can also be used as a login if the member is linked to a user. diff --git a/htdocs/langs/en_US/mrp.lang b/htdocs/langs/en_US/mrp.lang index a414920ff83..e336dd2552d 100644 --- a/htdocs/langs/en_US/mrp.lang +++ b/htdocs/langs/en_US/mrp.lang @@ -44,8 +44,8 @@ StatusMOProduced=Produced QtyFrozen=Frozen Qty QuantityFrozen=Frozen Quantity QuantityConsumedInvariable=When this flag is set, the quantity consumed is always the value defined and is not relative to the quantity produced. -DisableStockChange=Disable stock change -DisableStockChangeHelp=When this flag is set, there is no stock change on this product, whatever is the quantity produced +DisableStockChange=Stock change disabled +DisableStockChangeHelp=When this flag is set, there is no stock change on this product, whatever is the quantity consumed BomAndBomLines=Bills Of Material and lines BOMLine=Line of BOM WarehouseForProduction=Warehouse for production @@ -61,3 +61,5 @@ ForAQuantityOf1=For a quantity to produce of 1 ConfirmValidateMo=Are you sure you want to validate this Manufacturing Order? ConfirmProductionDesc=By clicking on '%s', you will validate the consumption and/or production for the quantities set. This will also update the stock and record stock movements. ProductionForRefAndDate=Production %s - %s +AutoCloseMO=Close automatically the Manufacturing Order if quantities to consume and to produce are reached +NoStockChangeOnServices=No stock change on services \ No newline at end of file diff --git a/htdocs/mrp/class/mo.class.php b/htdocs/mrp/class/mo.class.php index cc51515eeb6..e5ac29616a7 100644 --- a/htdocs/mrp/class/mo.class.php +++ b/htdocs/mrp/class/mo.class.php @@ -505,7 +505,7 @@ class Mo extends CommonObject } /** - * Erase and update the line to produce + * Erase and update the line to produce. * * @param User $user User that modifies * @return int <0 if KO, >0 if OK @@ -557,7 +557,11 @@ class Mo extends CommonObject $moline = new MoLine($this->db); $moline->fk_mo = $this->id; - $moline->qty = round($line->qty * $this->qty / $bom->efficiency, 2); + if ($line->qty_frozen) { + $moline->qty = $line->qty; // Qty to consume does not depends on quantity to produce + } else { + $moline->qty = round($line->qty * $this->qty / $bom->efficiency, 2); + } if ($moline->qty <= 0) { $error++; $this->error = "BadValueForquantityToConsume"; @@ -980,10 +984,16 @@ class Mo extends CommonObject global $langs; //$langs->load("mrp"); $this->labelStatus[self::STATUS_DRAFT] = $langs->trans('Draft'); - $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Validated'); + $this->labelStatus[self::STATUS_VALIDATED] = $langs->trans('Validated').' ('.$langs->trans("ToProduce").')'; $this->labelStatus[self::STATUS_INPROGRESS] = $langs->trans('InProgress'); $this->labelStatus[self::STATUS_PRODUCED] = $langs->trans('StatusMOProduced'); $this->labelStatus[self::STATUS_CANCELED] = $langs->trans('Canceled'); + + $this->labelStatusShort[self::STATUS_DRAFT] = $langs->trans('Draft'); + $this->labelStatusShort[self::STATUS_VALIDATED] = $langs->trans('Validated'); + $this->labelStatusShort[self::STATUS_INPROGRESS] = $langs->trans('InProgress'); + $this->labelStatusShort[self::STATUS_PRODUCED] = $langs->trans('StatusMOProduced'); + $this->labelStatusShort[self::STATUS_CANCELED] = $langs->trans('Canceled'); } $statusType = 'status'.$status; @@ -992,7 +1002,7 @@ class Mo extends CommonObject if ($status == self::STATUS_PRODUCED) $statusType = 'status5'; if ($status == self::STATUS_CANCELED) $statusType = 'status6'; - return dolGetStatus($this->labelStatus[$status], $this->labelStatus[$status], '', $statusType, $mode); + return dolGetStatus($this->labelStatus[$status], $this->labelStatusShort[$status], '', $statusType, $mode); } /** @@ -1448,6 +1458,24 @@ class MoLine extends CommonObjectLine } } + /** + * Get list of lines linked to current line for a defined role + * + * @param string $role Get lines linked to current line with the selected role ('consumed', 'produced', ...) + * @return array Array of lines + */ + public function fetchLinesLinked($role) { + $array = array(); + + $sql = 'SELECT rowid, qty '; + $sql .= $this->getFieldList(); + $sql .= ' FROM '.MAIN_DB_PREFIX.$this->table_element.' as t'; + if (isset($this->ismultientitymanaged) && $this->ismultientitymanaged == 1) $sql .= ' WHERE t.entity IN ('.getEntity($this->table_element).')'; + else $sql .= ' WHERE 1 = 1'; + + return $array; + } + /** * Update object into database * diff --git a/htdocs/mrp/mo_card.php b/htdocs/mrp/mo_card.php index 671353ff961..68938f97a58 100644 --- a/htdocs/mrp/mo_card.php +++ b/htdocs/mrp/mo_card.php @@ -117,8 +117,6 @@ $upload_dir = $conf->mrp->multidir_output[isset($object->entity) ? $object->enti /* * Actions - * - * Put here all code to do according to value of "action" parameter */ $parameters = array(); diff --git a/htdocs/mrp/mo_production.php b/htdocs/mrp/mo_production.php index cc08486e27d..212a7040927 100644 --- a/htdocs/mrp/mo_production.php +++ b/htdocs/mrp/mo_production.php @@ -47,6 +47,7 @@ require '../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; +require_once DOL_DOCUMENT_ROOT.'/product/class/product.class.php'; require_once DOL_DOCUMENT_ROOT.'/product/class/html.formproduct.class.php'; dol_include_once('/mrp/class/mo.class.php'); dol_include_once('/mrp/lib/mrp_mo.lib.php'); @@ -149,6 +150,89 @@ if (empty($reshook)) { $object->setProject(GETPOST('projectid', 'int')); } + + if ($action == 'confirm_consumeandproduceall') { + $db->begin(); + + // Process line to consume + foreach($object->lines as $line) { + if ($line->role == 'toconsume') { + $tmpproduct = new Product($db); + $tmpproduct->fetch($line->fk_product); + + $i=1; + while (GETPOSTISSET('qty-'.$line->id.'-'.$i)) { + // Check warehouse is set if we should have to + if (GETPOST('idwarehouse-'.$line->id.'-'.$i)) { + if (! (GETPOST('idwarehouse-'.$line->id.'-'.$i) > 0)) { + $langs->load("errors"); + setEventMessages($langs->trans("ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv("Warehouse"), $tmpproduct->ref), null, 'errors'); + $error++; + } + if ($tmpproduct->status_batch && (! GETPOST('batch-'.$line->id.'-'.$i))) { + $langs->load("errors"); + setEventMessages($langs->trans("ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv("Batch"), $tmpproduct->ref), null, 'errors'); + $error++; + } + } + + if (! $error) { + + + + } + + $i++; + } + } + } + + // Process line to produce + foreach($object->lines as $line) { + if ($line->role == 'toproduce') { + $tmpproduct = new Product($db); + $tmpproduct->fetch($line->fk_product); + + $i=1; + while (GETPOSTISSET('qtytoproduce-'.$line->id.'-'.$i)) { + // Check warehouse is set if we should have to + if (GETPOST('idwarehousetoproduce-'.$line->id.'-'.$i)) { + if (! (GETPOST('idwarehousetoproduce-'.$line->id.'-'.$i) > 0)) { + $langs->load("errors"); + setEventMessages($langs->trans("ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv("Warehouse"), $tmpproduct->ref), null, 'errors'); + $error++; + } + if ($tmpproduct->status_batch && (! GETPOST('batchtoproduce-'.$line->id.'-'.$i))) { + $langs->load("errors"); + setEventMessages($langs->trans("ErrorFieldRequiredForProduct", $langs->transnoentitiesnoconv("Batch"), $tmpproduct->ref), null, 'errors'); + $error++; + } + } + + if (! $error) { + + + + } + + $i++; + } + } + } + + if (! $error) { + // Update status of MO + + } + + if ($error) { + $action = str_replace('confirm_', '', $action); + $db->rollback(); + } else { + $db->commit(); + } + + } } @@ -357,7 +441,7 @@ if ($object->id > 0 && (empty($action) || ($action != 'edit' && $action != 'crea { print '