diff --git a/htdocs/admin/workflow.php b/htdocs/admin/workflow.php index ada5a6e0b3b..a58c3378ecd 100644 --- a/htdocs/admin/workflow.php +++ b/htdocs/admin/workflow.php @@ -123,9 +123,25 @@ $workflowcodes = array( ), // Automatic classification supplier order + 'WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION'=>array( + 'family'=>'classify_supplier_order', + 'position'=>63, + 'enabled'=>(!empty($conf->global->MAIN_FEATURES_LEVEL) && (!empty($conf->reception->enabled)) && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || empty($conf->supplier_order->enabled))), + 'picto'=>'supplier_order', + 'warning'=>'' + ), + + 'WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION_CLOSED'=>array( + 'family'=>'classify_supplier_order', + 'position'=>64, + 'enabled'=>(!empty($conf->global->MAIN_FEATURES_LEVEL) && (!empty($conf->reception->enabled)) && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || empty($conf->supplier_order->enabled))), + 'picto'=>'supplier_order', + 'warning'=>'' + ), + 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER'=>array( 'family'=>'classify_supplier_order', - 'position'=>62, + 'position'=>65, 'enabled'=>((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled)), 'picto'=>'supplier_order', 'warning'=>'' @@ -134,7 +150,7 @@ $workflowcodes = array( // Automatic classification reception 'WORKFLOW_BILL_ON_RECEPTION'=>array( 'family'=>'classify_reception', - 'position'=>64, + 'position'=>80, 'enabled'=>(!empty($conf->reception->enabled) && ((!empty($conf->fournisseur->enabled) && empty($conf->global->MAIN_USE_NEW_SUPPLIERMOD)) || !empty($conf->supplier_order->enabled) || !empty($conf->supplier_invoice->enabled))), 'picto'=>'reception' ), @@ -142,7 +158,7 @@ $workflowcodes = array( // Automatic classification shipping 'WORKFLOW_SHIPPING_CLASSIFY_CLOSED_INVOICE' => array( 'family' => 'classify_shipping', - 'position' => 66, + 'position' => 90, 'enabled' => ! empty($conf->expedition->enabled) && ! empty($conf->facture->enabled), 'picto' => 'shipment' ) diff --git a/htdocs/core/modules/modWorkflow.class.php b/htdocs/core/modules/modWorkflow.class.php index eaaf15d40a1..4122f347664 100644 --- a/htdocs/core/modules/modWorkflow.class.php +++ b/htdocs/core/modules/modWorkflow.class.php @@ -90,8 +90,10 @@ class modWorkflow extends DolibarrModules 3=>array('WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING_CLOSED', 'chaine', '1', 'WORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING_CLOSED', 0, 'current', 0), 4=>array('WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER', 'chaine', '1', 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER', 0, 'current', 0), 5=>array('WORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL', 'chaine', '1', 'WORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL', 0, 'current', 0), - 6=>array('WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER', 'chaine', '1', 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER', 0, 'current', 0), - 7=>array('WORKFLOW_BILL_ON_RECEPTION', 'chaine', '1', 'WORKFLOW_BILL_ON_RECEPTION', 0, 'current', 0) + 6=>array('WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION', 'chaine', '1', 'WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION', 0, 'current', 0), + 7=>array('WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION_CLOSED', 'chaine', '1', 'WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION_CLOSED', 0, 'current', 0), + 8=>array('WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER', 'chaine', '1', 'WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER', 0, 'current', 0), + 9=>array('WORKFLOW_BILL_ON_RECEPTION', 'chaine', '1', 'WORKFLOW_BILL_ON_RECEPTION', 0, 'current', 0) ); // Boxes diff --git a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php index c45ce9d2406..048dc170c0a 100644 --- a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php +++ b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php @@ -188,7 +188,7 @@ class InterfaceWorkflowManager extends DolibarrTriggers return $ret; } - // classify billed order & billed propososal + // classify billed order & billed proposal if ($action == 'BILL_SUPPLIER_VALIDATE') { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); @@ -286,6 +286,7 @@ class InterfaceWorkflowManager extends DolibarrTriggers } } + // If we validate or close a shipment if (($action == 'SHIPPING_VALIDATE') || ($action == 'SHIPPING_CLOSED')) { dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); @@ -354,6 +355,75 @@ class InterfaceWorkflowManager extends DolibarrTriggers } } + // If we validate or close a shipment + if (($action == 'RECEPTION_VALIDATE') || ($action == 'RECEPTION_CLOSED')) { + dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); + + if ((!empty($conf->fournisseur->enabled) || !empty($conf->supplier_order->enabled)) && !empty($conf->reception->enabled) && !empty($conf->workflow->enabled) && + ( + (!empty($conf->global->WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION) && ($action == 'RECEPTION_VALIDATE')) || + (!empty($conf->global->WORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION_CLOSED) && ($action == 'RECEPTION_CLOSED')) + ) + ) { + $qtyshipped = array(); + $qtyordred = array(); + require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.commande.class.php'; + + // Find all reception on purchase order origin + $order = new CommandeFournisseur($this->db); + $ret = $order->fetch($object->origin_id); + if ($ret < 0) { + $this->error = $order->error; + $this->errors = $order->errors; + return $ret; + } + $ret = $order->fetchObjectLinked($order->id, 'supplier_order', null, 'reception'); + if ($ret < 0) { + $this->error = $order->error; + $this->errors = $order->errors; + return $ret; + } + //Build array of quantity received by product for a purchase order + if (is_array($order->linkedObjects) && count($order->linkedObjects) > 0) { + foreach ($order->linkedObjects as $type => $shipping_array) { + if ($type == 'reception' && is_array($shipping_array) && count($shipping_array) > 0) { + foreach ($shipping_array as $shipping) { + if (is_array($shipping->lines) && count($shipping->lines) > 0) { + foreach ($shipping->lines as $shippingline) { + $qtyshipped[$shippingline->fk_product] += $shippingline->qty; + } + } + } + } + } + } + + //Build array of quantity ordered to be received + if (is_array($order->lines) && count($order->lines) > 0) { + foreach ($order->lines as $orderline) { + // Exclude lines not qualified for shipment, similar code is found into calcAndSetStatusDispatch() for vendors + if (empty($conf->global->STOCK_SUPPORTS_SERVICES) && $orderline->product_type > 0) { + continue; + } + $qtyordred[$orderline->fk_product] += $orderline->qty; + } + } + //dol_syslog(var_export($qtyordred,true),LOG_DEBUG); + //dol_syslog(var_export($qtyshipped,true),LOG_DEBUG); + //Compare array + $diff_array = array_diff_assoc($qtyordred, $qtyshipped); + if (count($diff_array) == 0) { + //No diff => mean everythings is received + $ret = $order->setStatut(CommandeFournisseur::STATUS_RECEIVED_COMPLETELY, $object->origin_id, $object->origin, 'SUPPLIER_ORDER_CLOSE'); + if ($ret < 0) { + $this->error = $order->error; + $this->errors = $order->errors; + return $ret; + } + } + } + } + return 0; } diff --git a/htdocs/langs/en_US/workflow.lang b/htdocs/langs/en_US/workflow.lang index fafbc6e8d8a..b65f8449fef 100644 --- a/htdocs/langs/en_US/workflow.lang +++ b/htdocs/langs/en_US/workflow.lang @@ -14,9 +14,13 @@ descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER=Classify linked source sales o descWORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER=Classify linked source sales order as billed when customer invoice is set to paid (and if the amount of the invoice is the same as the total amount of the linked order) descWORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING=Classify linked source sales order as shipped when a shipment is validated (and if the quantity shipped by all shipments is the same as in the order to update) descWORKFLOW_ORDER_CLASSIFY_SHIPPED_SHIPPING_CLOSED=Classify linked source sales order as shipped when a shipment is closed (and if the quantity shipped by all shipments is the same as in the order to update) -# Autoclassify purchase order +# Autoclassify purchase proposal descWORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL=Classify linked source vendor proposal as billed when vendor invoice is validated (and if the amount of the invoice is the same as the total amount of the linked proposal) +# Autoclassify purchase order descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_SUPPLIER_ORDER=Classify linked source purchase order as billed when vendor invoice is validated (and if the amount of the invoice is the same as the total amount of the linked order) +descWORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION=Classify linked source purchase order as received when a reception is validated (and if the quantity received by all receptions is the same as in the purchase order to update) +descWORKFLOW_ORDER_CLASSIFY_RECEIVED_RECEPTION_CLOSED=Classify linked source purchase order as received when a reception is closed (and if the quantity received by all rceptions is the same as in the purchase order to update) +# Autoclassify purchase invoice descWORKFLOW_BILL_ON_RECEPTION=Classify receptions to "billed" when a linked supplier order is validated # Autoclose intervention descWORKFLOW_TICKET_CLOSE_INTERVENTION=Close all interventions linked to the ticket when a ticket is closed