diff --git a/ChangeLog b/ChangeLog index 41341fa2d45..82771d980ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -19,7 +19,8 @@ WARNING: Following changes may create regressions for some external modules, but were necessary to make Dolibarr better: * The property ->brouillon has been removed from all classes. It was not reliable and was a duplicate of ->status == self::STATUS_DRAFT. * The method get_substitutionarray_shipment_lines() has been removed. Use the generic get_substitutionarray_lines() instead. - +* Recheck setup of your module workflow to see if you need to enable the new setting to have shipment set to billed automatically + when an invoice from a shipment is validated (and if your process is to make invoice on shipment and not on order). ***** ChangeLog for 18.0.1 compared to 18.0.0 ***** diff --git a/htdocs/admin/workflow.php b/htdocs/admin/workflow.php index 28d347bcabe..a6cb4ee62ca 100644 --- a/htdocs/admin/workflow.php +++ b/htdocs/admin/workflow.php @@ -153,20 +153,40 @@ $workflowcodes = array( ), // Automatic classification shipping + /* Replaced by next option 'WORKFLOW_SHIPPING_CLASSIFY_CLOSED_INVOICE' => array( 'family' => 'classify_shipping', 'position' => 90, 'enabled' => isModEnabled("expedition") && isModEnabled("facture"), + 'picto' => 'shipment', + 'deprecated' => 1 + ), + */ + + 'WORKFLOW_SHIPPING_CLASSIFY_BILLED_INVOICE' => array( + 'family' => 'classify_shipping', + 'position' => 91, + 'enabled' => isModEnabled("expedition") && isModEnabled("facture") && getDolGlobalString('WORKFLOW_BILL_ON_SHIPMENT') !== '0', 'picto' => 'shipment' ), // Automatic classification reception - 'WORKFLOW_EXPEDITION_CLASSIFY_CLOSED_INVOICE'=>array( + /* + 'WORKFLOW_RECEPTION_CLASSIFY_CLOSED_INVOICE'=>array( 'family'=>'classify_reception', 'position'=>95, 'enabled'=>(isModEnabled("reception") && (isModEnabled("supplier_order") || isModEnabled("supplier_invoice"))), 'picto'=>'reception' ), + */ + + 'WORKFLOW_RECEPTION_CLASSIFY_BILLED_INVOICE' => array( + 'family' => 'classify_reception', + 'position' => 91, + 'enabled' => isModEnabled("reception") && isModEnabled("supplier_invoice") && getDolGlobalString('WORKFLOW_BILL_ON_RECEPTION') !== '0', + 'picto' => 'shipment' + ), + 'separator2'=>array('family'=>'separator', 'position'=>400, 'enabled' => (isModEnabled('ticket') && isModEnabled('contract'))), @@ -284,6 +304,9 @@ foreach ($workflowcodes as $key => $params) { if (!empty($params['warning'])) { print ' '.img_warning($langs->transnoentitiesnoconv($params['warning'])); } + if (!empty($params['deprecated'])) { + print ' '.img_warning($langs->transnoentitiesnoconv("Deprecated")); + } print ''; diff --git a/htdocs/commande/card.php b/htdocs/commande/card.php index 0134ac37e40..afe3818bab1 100644 --- a/htdocs/commande/card.php +++ b/htdocs/commande/card.php @@ -2954,14 +2954,14 @@ if ($action == 'create' && $usercancreate) { // Note: Even if module invoice is not enabled, we should be able to use button "Classified billed" if ($object->statut > Commande::STATUS_DRAFT && !$object->billed && $object->total_ttc >= 0) { if (isModEnabled('facture') && $user->hasRight('facture', 'creer') && empty($conf->global->WORKFLOW_DISABLE_CREATE_INVOICE_FROM_ORDER)) { - print dolGetButtonAction('', $langs->trans('CreateBill'), 'default', DOL_URL_ROOT.'/compta/facture/card.php?action=create&token='.newToken().'&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->socid, ''); + print dolGetButtonAction('', $langs->trans('CreateBill'), 'default', DOL_URL_ROOT.'/compta/facture/card.php?action=create&token='.newToken().'&origin='.urlencode($object->element).'&originid='.$object->id.'&socid='.$object->socid, ''); } - if ($usercancreate && $object->statut >= Commande::STATUS_VALIDATED && empty($conf->global->WORKFLOW_DISABLE_CLASSIFY_BILLED_FROM_ORDER) && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) { + if ($usercancreate && $object->statut >= Commande::STATUS_VALIDATED && empty($conf->global->WORKFLOW_DISABLE_CLASSIFY_BILLED_FROM_ORDER) && !getDolGlobalString('WORKFLOW_BILL_ON_SHIPMENT')) { print dolGetButtonAction('', $langs->trans('ClassifyBilled'), 'default', $_SERVER["PHP_SELF"].'?action=classifybilled&token='.newToken().'&id='.$object->id, ''); } } if ($object->statut > Commande::STATUS_DRAFT && $object->billed) { - if ($usercancreate && $object->statut >= Commande::STATUS_VALIDATED && empty($conf->global->WORKFLOW_DISABLE_CLASSIFY_BILLED_FROM_ORDER) && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) { + if ($usercancreate && $object->statut >= Commande::STATUS_VALIDATED && empty($conf->global->WORKFLOW_DISABLE_CLASSIFY_BILLED_FROM_ORDER) && !getDolGlobalString('WORKFLOW_BILL_ON_SHIPMENT')) { print dolGetButtonAction('', $langs->trans('ClassifyUnBilled'), 'default', $_SERVER["PHP_SELF"].'?action=classifyunbilled&token='.newToken().'&id='.$object->id, ''); } } diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 250d6c49aa0..67fcbb55d29 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -3729,14 +3729,6 @@ class Commande extends CommonOrder $labelTooltip .= ' - '.$langs->transnoentitiesnoconv("DateDeliveryPlanned").dol_print_date($this->delivery_date, 'day').$billedtext; } $statusType = 'status4'; - } elseif ($status == self::STATUS_CLOSED && (!$billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) { - $labelStatus = $langs->transnoentitiesnoconv('StatusOrderToBill'); // translated into Delivered - $labelStatusShort = $langs->transnoentitiesnoconv('StatusOrderToBillShort'); // translated into Delivered - $statusType = 'status4'; - } elseif ($status == self::STATUS_CLOSED && ($billed && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) { - $labelStatus = $langs->transnoentitiesnoconv('StatusOrderProcessed').$billedtext; - $labelStatusShort = $langs->transnoentitiesnoconv('StatusOrderProcessedShort').$billedtext; - $statusType = 'status6'; } elseif ($status == self::STATUS_CLOSED && (!empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) { $labelStatus = $langs->transnoentitiesnoconv('StatusOrderDelivered'); $labelStatusShort = $langs->transnoentitiesnoconv('StatusOrderDeliveredShort'); diff --git a/htdocs/commande/list.php b/htdocs/commande/list.php index ae0fd4e3d05..137eea575cf 100644 --- a/htdocs/commande/list.php +++ b/htdocs/commande/list.php @@ -206,7 +206,7 @@ $arrayfields = array( 'c.note_public'=>array('label'=>'NotePublic', 'checked'=>0, 'enabled'=>(!getDolGlobalInt('MAIN_LIST_HIDE_PUBLIC_NOTES')), 'position'=>135), 'c.note_private'=>array('label'=>'NotePrivate', 'checked'=>0, 'enabled'=>(!getDolGlobalInt('MAIN_LIST_HIDE_PRIVATE_NOTES')), 'position'=>140), 'shippable'=>array('label'=>"Shippable", 'checked'=>1,'enabled'=>(isModEnabled("expedition")), 'position'=>990), - 'c.facture'=>array('label'=>"Billed", 'checked'=>1, 'enabled'=>(empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)), 'position'=>995), + 'c.facture'=>array('label'=>"Billed", 'checked'=>1, 'enabled'=>(!getDolGlobalString('WORKFLOW_BILL_ON_SHIPMENT')), 'position'=>995), 'c.import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>999), 'c.fk_statut'=>array('label'=>"Status", 'checked'=>1, 'position'=>1000) ); diff --git a/htdocs/commande/list_det.php b/htdocs/commande/list_det.php index 9aa5aad7176..cc14aabf238 100644 --- a/htdocs/commande/list_det.php +++ b/htdocs/commande/list_det.php @@ -213,7 +213,7 @@ $arrayfields = array( 'c.note_public'=>array('label'=>'NotePublic', 'checked'=>0, 'enabled'=>(empty($conf->global->MAIN_LIST_ALLOW_PUBLIC_NOTES)), 'position'=>135), 'c.note_private'=>array('label'=>'NotePrivate', 'checked'=>0, 'enabled'=>(empty($conf->global->MAIN_LIST_ALLOW_PRIVATE_NOTES)), 'position'=>140), 'shippable'=>array('label'=>"Shippable", 'checked'=>1,'enabled'=>(isModEnabled('expedition')), 'position'=>990), - 'c.facture'=>array('label'=>"Billed", 'checked'=>1, 'enabled'=>(empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)), 'position'=>995), + 'c.facture'=>array('label'=>"Billed", 'checked'=>1, 'enabled'=>(!getDolGlobalString('WORKFLOW_BILL_ON_SHIPMENT')), 'position'=>995), 'c.import_key' =>array('type'=>'varchar(14)', 'label'=>'ImportId', 'enabled'=>1, 'visible'=>-2, 'position'=>999), 'c.fk_statut'=>array('label'=>"Status", 'checked'=>1, 'position'=>1000) ); diff --git a/htdocs/core/lib/order.lib.php b/htdocs/core/lib/order.lib.php index 349e3179f93..100d5a8d93e 100644 --- a/htdocs/core/lib/order.lib.php +++ b/htdocs/core/lib/order.lib.php @@ -298,10 +298,7 @@ function getCustomerOrderPieChart($socid = 0) if ($status == Commande::STATUS_SHIPMENTONPROCESS) { $colorseries[$status] = $badgeStatus4; } - if ($status == Commande::STATUS_CLOSED && empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) { - $colorseries[$status] = $badgeStatus6; - } - if ($status == Commande::STATUS_CLOSED && (!empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) { + if ($status == Commande::STATUS_CLOSED) { $colorseries[$status] = $badgeStatus6; } if ($status == Commande::STATUS_CANCELED) { diff --git a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php index 273da6a1752..03449f96f2a 100644 --- a/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php +++ b/htdocs/core/triggers/interface_20_modWorkflow_WorkflowManager.class.php @@ -189,6 +189,7 @@ class InterfaceWorkflowManager extends DolibarrTriggers } } + // Set shipment to "Closed" if WORKFLOW_SHIPPING_CLASSIFY_CLOSED_INVOICE is set (deprecated, WORKFLOW_SHIPPING_CLASSIFY_BILLED_INVOICE instead)) if (isModEnabled("expedition") && !empty($conf->workflow->enabled) && !empty($conf->global->WORKFLOW_SHIPPING_CLASSIFY_CLOSED_INVOICE)) { $object->fetchObjectLinked('', 'shipping', $object->id, $object->element); if (!empty($object->linkedObjects)) { @@ -210,6 +211,27 @@ class InterfaceWorkflowManager extends DolibarrTriggers } } + if (isModEnabled("expedition") && !empty($conf->workflow->enabled) && !empty($conf->global->WORKFLOW_SHIPPING_CLASSIFY_BILLED_INVOICE)) { + $object->fetchObjectLinked('', 'shipping', $object->id, $object->element); + if (!empty($object->linkedObjects)) { + $totalonlinkedelements = 0; + foreach ($object->linkedObjects['shipping'] as $element) { + if ($element->statut == Expedition::STATUS_VALIDATED || $element->statut == Expedition::STATUS_CLOSED) { + $totalonlinkedelements += $element->total_ht; + } + } + dol_syslog("Amount of linked shipment = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG); + if ($totalonlinkedelements == $object->total_ht) { + foreach ($object->linkedObjects['shipping'] as $element) { + $ret = $element->setBilled(); + if ($ret < 0) { + return $ret; + } + } + } + } + } + return $ret; } @@ -262,8 +284,32 @@ class InterfaceWorkflowManager extends DolibarrTriggers } } - // Then set reception to "Billed" if WORKFLOW_EXPEDITION_CLASSIFY_CLOSED_INVOICE is set - if (isModEnabled("reception") && !empty($conf->workflow->enabled) && !empty($conf->global->WORKFLOW_EXPEDITION_CLASSIFY_CLOSED_INVOICE)) { + // Set reception to "Closed" if WORKFLOW_RECEPTION_CLASSIFY_CLOSED_INVOICE is set (deprecated, WORKFLOW_RECEPTION_CLASSIFY_BILLED_INVOICE instead)) + /* + if (isModEnabled("reception") && !empty($conf->workflow->enabled) && !empty($conf->global->WORKFLOW_RECEPTION_CLASSIFY_CLOSED_INVOICE)) { + $object->fetchObjectLinked('', 'reception', $object->id, $object->element); + if (!empty($object->linkedObjects)) { + $totalonlinkedelements = 0; + foreach ($object->linkedObjects['reception'] as $element) { + if ($element->statut == Reception::STATUS_VALIDATED || $element->statut == Reception::STATUS_CLOSED) { + $totalonlinkedelements += $element->total_ht; + } + } + dol_syslog("Amount of linked reception = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht), LOG_DEBUG); + if ($totalonlinkedelements == $object->total_ht) { + foreach ($object->linkedObjects['reception'] as $element) { + $ret = $element->setClosed(); + if ($ret < 0) { + return $ret; + } + } + } + } + } + */ + + // Then set reception to "Billed" if WORKFLOW_RECEPTION_CLASSIFY_BILLED_INVOICE is set + if (isModEnabled("reception") && !empty($conf->workflow->enabled) && !empty($conf->global->WORKFLOW_RECEPTION_CLASSIFY_BILLED_INVOICE)) { $object->fetchObjectLinked('', 'reception', $object->id, $object->element); if (!empty($object->linkedObjects)) { $totalonlinkedelements = 0; diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index f34cc2d11a5..a13dec33985 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -2573,7 +2573,6 @@ if ($action == 'create') { } // 0=draft, 1=validated/delivered, 2=closed/delivered - // If WORKFLOW_BILL_ON_SHIPMENT: 0=draft, 1=validated, 2=billed (no status delivered) if ($object->statut == Expedition::STATUS_VALIDATED && !getDolGlobalString('STOCK_CALCULATE_ON_SHIPMENT')) { if ($user->hasRight('expedition', 'creer')) { print dolGetButtonAction('', $langs->trans('SetToDraft'), 'default', $_SERVER["PHP_SELF"].'?action=setdraft&token='.newToken().'&id='.$object->id, ''); @@ -2581,11 +2580,7 @@ if ($action == 'create') { } if ($object->statut == Expedition::STATUS_CLOSED) { if ($user->hasRight('expedition', 'creer')) { - if (isModEnabled('facture') && !empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) { // Quand l'option est on, il faut avoir le bouton en plus et non en remplacement du Close ? - print dolGetButtonAction('', $langs->trans('ClassifyUnbilled'), 'default', $_SERVER["PHP_SELF"].'?action=reopen&token='.newToken().'&id='.$object->id, ''); - } else { - print dolGetButtonAction('', $langs->trans('ReOpen'), 'default', $_SERVER["PHP_SELF"].'?action=reopen&token='.newToken().'&id='.$object->id, ''); - } + print dolGetButtonAction('', $langs->trans('ReOpen'), 'default', $_SERVER["PHP_SELF"].'?action=reopen&token='.newToken().'&id='.$object->id, ''); } } @@ -2603,9 +2598,9 @@ if ($action == 'create') { // Create bill if (isModEnabled('facture') && ($object->statut == Expedition::STATUS_VALIDATED || $object->statut == Expedition::STATUS_CLOSED)) { if ($user->hasRight('facture', 'creer')) { - // TODO show button only if (!empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) - // If we do that, we must also make this option official. - print dolGetButtonAction('', $langs->trans('CreateBill'), 'default', DOL_URL_ROOT.'/compta/facture/card.php?action=create&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->socid, ''); + if (getDolGlobalString('WORKFLOW_BILL_ON_SHIPMENT') !== '0') { + print dolGetButtonAction('', $langs->trans('CreateBill'), 'default', DOL_URL_ROOT.'/compta/facture/card.php?action=create&origin='.$object->element.'&originid='.$object->id.'&socid='.$object->socid, ''); + } } } @@ -2614,28 +2609,26 @@ if ($action == 'create') { if (getDolGlobalInt('MAIN_SUBMODULE_DELIVERY') && ($object->statut == Expedition::STATUS_VALIDATED || $object->statut == Expedition::STATUS_CLOSED) && $user->rights->expedition->delivery->creer && empty($object->linkedObjectsIds['delivery'])) { print dolGetButtonAction('', $langs->trans('CreateDeliveryOrder'), 'default', $_SERVER["PHP_SELF"].'?action=create_delivery&token='.newToken().'&id='.$object->id, ''); } - // Close + + // Set Billed and Closed if ($object->statut == Expedition::STATUS_VALIDATED) { - if ($user->rights->expedition->creer && $object->statut > 0 && !$object->billed) { - $label = "Close"; $paramaction = 'classifyclosed'; // = Transferred/Received - // Label here should be "Close" or "ClassifyBilled" if we decided to make bill on shipments instead of orders - if (isModEnabled('facture') && !empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) { // Quand l'option est on, il faut avoir le bouton en plus et non en remplacement du Close ? - $label = "ClassifyBilled"; - $paramaction = 'classifybilled'; + if ($user->hasRight('expedition', 'creer') && $object->statut > 0) { + if (!$object->billed && getDolGlobalString('WORKFLOW_BILL_ON_SHIPMENT') !== '0') { + print dolGetButtonAction('', $langs->trans('ClassifyBilled'), 'default', $_SERVER["PHP_SELF"].'?action=classifybilled&token='.newToken().'&id='.$object->id, ''); } - print dolGetButtonAction('', $langs->trans($label), 'default', $_SERVER["PHP_SELF"].'?action='. $paramaction .'&token='.newToken().'&id='.$object->id, ''); + print dolGetButtonAction('', $langs->trans("Close"), 'default', $_SERVER["PHP_SELF"].'?action='. $paramaction .'&token='.newToken().'&id='.$object->id, ''); } } // Cancel if ($object->statut == Expedition::STATUS_VALIDATED) { - if ($user->rights->expedition->supprimer) { + if ($user->hasRight('expedition', 'creer')) { print dolGetButtonAction('', $langs->trans('Cancel'), 'danger', $_SERVER["PHP_SELF"].'?action=cancel&token='.newToken().'&id='.$object->id.'&mode=init#formmailbeforetitle', ''); } } // Delete - if ($user->rights->expedition->supprimer) { + if ($user->hasRight('expedition', 'supprimer')) { print dolGetButtonAction('', $langs->trans('Delete'), 'delete', $_SERVER["PHP_SELF"].'?action=delete&token='.newToken().'&id='.$object->id, ''); } } diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 967b4e9a4fb..e538f36bf18 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -2108,13 +2108,13 @@ class Expedition extends CommonObject } /** - * Classify the shipping as closed. + * Classify the shipping as closed (this record also the stock movement) * * @return int <0 if KO, >0 if OK */ public function setClosed() { - global $conf, $langs, $user; + global $conf, $user; $error = 0; @@ -2280,7 +2280,7 @@ class Expedition extends CommonObject } /** - * Classify the shipping as invoiced (used when WORKFLOW_BILL_ON_SHIPMENT is on) + * Classify the shipping as invoiced (used for exemple by trigger when WORKFLOW_SHIPPING_CLASSIFY_BILLED_INVOICE is on) * * @return int <0 if ko, >0 if ok */ @@ -2291,17 +2291,17 @@ class Expedition extends CommonObject $this->db->begin(); - $sql = 'UPDATE '.MAIN_DB_PREFIX.'expedition SET fk_statut=2, billed=1'; // TODO Update only billed + $sql = 'UPDATE '.MAIN_DB_PREFIX.'expedition SET billed = 1'; $sql .= " WHERE rowid = ".((int) $this->id).' AND fk_statut > 0'; $resql = $this->db->query($sql); if ($resql) { - $this->statut = self::STATUS_CLOSED; $this->billed = 1; // Call trigger $result = $this->call_trigger('SHIPPING_BILLED', $user); if ($result < 0) { + $this->billed = 0; $error++; } } else { @@ -2313,8 +2313,6 @@ class Expedition extends CommonObject $this->db->commit(); return 1; } else { - $this->statut = self::STATUS_VALIDATED; - $this->billed = 0; $this->db->rollback(); return -1; } diff --git a/htdocs/expedition/list.php b/htdocs/expedition/list.php index 40c8191043a..5fe37b5c7ce 100644 --- a/htdocs/expedition/list.php +++ b/htdocs/expedition/list.php @@ -144,7 +144,7 @@ $arrayfields = array( 'e.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), 'l.ref'=>array('label'=>$langs->trans("DeliveryRef"), 'checked'=>1, 'enabled'=>(getDolGlobalInt('MAIN_SUBMODULE_DELIVERY') ? 1 : 0)), 'l.date_delivery'=>array('label'=>$langs->trans("DateReceived"), 'checked'=>1, 'enabled'=>(getDolGlobalInt('MAIN_SUBMODULE_DELIVERY') ? 1 : 0)), - 'e.billed'=>array('label'=>$langs->trans("Billed"), 'checked'=>1, 'position'=>1000, 'enabled'=>(!empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT))) + 'e.billed'=>array('label'=>$langs->trans("Billed"), 'checked'=>1, 'position'=>1000, 'enabled'=>'getDolGlobalConst("WORKFLOW_BILL_ON_SHIPMENT") !== "0"') ); // Extra fields diff --git a/htdocs/langs/en_US/workflow.lang b/htdocs/langs/en_US/workflow.lang index a2b6b4c1f95..bc9d4b6fa8e 100644 --- a/htdocs/langs/en_US/workflow.lang +++ b/htdocs/langs/en_US/workflow.lang @@ -9,11 +9,11 @@ descWORKFLOW_CONTRACT_AUTOCREATE_INVOICE=Automatically create a customer invoice descWORKFLOW_ORDER_AUTOCREATE_INVOICE=Automatically create a customer invoice after a sales order is closed (the new invoice will have same amount as the order) descWORKFLOW_TICKET_CREATE_INTERVENTION=On ticket creation, automatically create an intervention. # Autoclassify customer proposal or order -descWORKFLOW_ORDER_CLASSIFY_BILLED_PROPAL=Classify linked source proposal as billed when sales order is set to billed (and if the amount of the order is the same as the total amount of the signed linked proposal) -descWORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL=Classify linked source proposal as billed when customer invoice is validated (and if the amount of the invoice is the same as the total amount of the signed linked proposal) -descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER=Classify linked source sales order as billed when customer invoice is validated (and if the amount of the invoice is the same as the total amount of the linked order) -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_BILLED_PROPAL=Classify linked source proposals as billed when a sales order is set to billed (and if the amount of the order is the same as the total amount of the signed linked proposal) +descWORKFLOW_INVOICE_CLASSIFY_BILLED_PROPAL=Classify linked source proposals as billed when a customer invoice is validated (and if the amount of the invoice is the same as the total amount of the signed linked proposal) +descWORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER=Classify linked source sales order as billed when a customer invoice is validated (and if the amount of the invoice is the same as the total amount of the linked order) +descWORKFLOW_INVOICE_CLASSIFY_BILLED_ORDER=Classify linked source sales orders as billed when a 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 orders 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 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) @@ -21,8 +21,12 @@ descWORKFLOW_ORDER_CLASSIFY_BILLED_SUPPLIER_PROPOSAL=Classify linked source vend 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_EXPEDITION_CLASSIFY_CLOSED_INVOICE=Classify receptions to "billed" when a linked purchase invoice is validated (and if the amount of the invoice is the same as the total amount of the linked receptions) +# Autoclassify shipment +descWORKFLOW_SHIPPING_CLASSIFY_CLOSED_INVOICE=Classify linked source shipment as closed when a customer invoice is validated (and if the amount of the invoice is the same as the total amount of the linked shipments) +descWORKFLOW_SHIPPING_CLASSIFY_BILLED_INVOICE=Classify linked source shipment as billed when a customer invoice is validated (and if the amount of the invoice is the same as the total amount of the linked shipments) +# Autoclassify receptions +descWORKFLOW_RECEPTION_CLASSIFY_CLOSED_INVOICE=Classify linked source receptions as billed when a purchase invoice is validated (and if the amount of the invoice is the same as the total amount of the linked receptions) +descWORKFLOW_RECEPTION_CLASSIFY_BILLED_INVOICE=Classify linked source receptions as billed when a purchase invoice is validated (and if the amount of the invoice is the same as the total amount of the linked receptions) # Automatically link ticket to contract descWORKFLOW_TICKET_LINK_CONTRACT=When creating a ticket, link available contracts of matching thirdparty descWORKFLOW_TICKET_USE_PARENT_COMPANY_CONTRACTS=When linking contracts, search among those of parents companies @@ -30,7 +34,5 @@ descWORKFLOW_TICKET_USE_PARENT_COMPANY_CONTRACTS=When linking contracts, search descWORKFLOW_TICKET_CLOSE_INTERVENTION=Close all interventions linked to the ticket when a ticket is closed AutomaticCreation=Automatic creation AutomaticClassification=Automatic classification -# Autoclassify shipment -descWORKFLOW_SHIPPING_CLASSIFY_CLOSED_INVOICE=Classify linked source shipment as closed when customer invoice is validated (and if the amount of the invoice is the same as the total amount of the linked shipments) AutomaticClosing=Automatic closing AutomaticLinking=Automatic linking diff --git a/htdocs/reception/card.php b/htdocs/reception/card.php index 5c58c71f8e1..29ea1434b2e 100644 --- a/htdocs/reception/card.php +++ b/htdocs/reception/card.php @@ -2133,11 +2133,7 @@ if ($action == 'create') { // TODO add alternative status // 0=draft, 1=validated, 2=billed, we miss a status "delivered" (only available on order) if ($object->statut == Reception::STATUS_CLOSED && $user->rights->reception->creer) { - if (isModEnabled('facture') && !empty($conf->global->WORKFLOW_BILL_ON_RECEPTION)) { // Quand l'option est on, il faut avoir le bouton en plus et non en remplacement du Close ? - print ''.$langs->trans("ClassifyUnbilled").''; - } else { - print ''.$langs->trans("ReOpen").''; - } + print ''.$langs->trans("ReOpen").''; } // Send @@ -2154,27 +2150,24 @@ if ($action == 'create') { // Create bill if (isModEnabled("supplier_invoice") && ($object->statut == Reception::STATUS_VALIDATED || $object->statut == Reception::STATUS_CLOSED)) { if ($user->hasRight('fournisseur', 'facture', 'creer') || $user->hasRight('supplier_invoice', 'creer')) { - // TODO show button only if (!empty($conf->global->WORKFLOW_BILL_ON_RECEPTION)) - // If we do that, we must also make this option official. - print ''.$langs->trans("CreateBill").''; - } - } - - - // Close - if ($object->statut == Reception::STATUS_VALIDATED) { - if ($user->rights->reception->creer && $object->statut > 0 && !$object->billed) { - $label = "Close"; $paramaction = 'classifyclosed'; // = Transferred/Received - // Label here should be "Close" or "ClassifyBilled" if we decided to make bill on receptions instead of orders - if (isModEnabled("supplier_order") && !empty($conf->global->WORKFLOW_BILL_ON_RECEPTION)) { // Quand l'option est on, il faut avoir le bouton en plus et non en remplacement du Close ? - $label = "ClassifyBilled"; - $paramaction = 'classifybilled'; + if (getDolGlobalString('WORKFLOW_BILL_ON_RECEPTION') !== '0') { + print ''.$langs->trans("CreateBill").''; } - print ''.$langs->trans($label).''; } } - if ($user->rights->reception->supprimer) { + + // Set Billed and Closed + if ($object->statut == Reception::STATUS_VALIDATED) { + if ($user->hasRight('reception', 'creer') && $object->statut > 0) { + if (!$object->billed && getDolGlobalString('WORKFLOW_BILL_ON_RECEPTION') !== '0') { + print ''.$langs->trans('ClassifyBilled').''; + } + print ''.$langs->trans("Close").''; + } + } + + if ($user->hasRight('reception', 'supprimer')) { print ''.$langs->trans("Delete").''; } } diff --git a/htdocs/reception/class/reception.class.php b/htdocs/reception/class/reception.class.php index 9fb6a0cb6a9..6369190efe9 100644 --- a/htdocs/reception/class/reception.class.php +++ b/htdocs/reception/class/reception.class.php @@ -370,7 +370,7 @@ class Reception extends CommonObject return -1; } - $sql = "SELECT e.rowid, e.entity, e.ref, e.fk_soc as socid, e.date_creation, e.ref_supplier, e.ref_ext, e.fk_user_author, e.fk_statut"; + $sql = "SELECT e.rowid, e.entity, e.ref, e.fk_soc as socid, e.date_creation, e.ref_supplier, e.ref_ext, e.fk_user_author, e.fk_statut as status"; $sql .= ", e.weight, e.weight_units, e.size, e.size_units, e.width, e.height"; $sql .= ", e.date_reception as date_reception, e.model_pdf, e.date_delivery"; $sql .= ", e.fk_shipping_method, e.tracking_number"; @@ -404,7 +404,8 @@ class Reception extends CommonObject $this->socid = $obj->socid; $this->ref_supplier = $obj->ref_supplier; $this->ref_ext = $obj->ref_ext; - $this->statut = $obj->fk_statut; + $this->statut = $obj->status; + $this->status = $obj->status; $this->user_author_id = $obj->fk_user_author; $this->date_creation = $this->db->jdate($obj->date_creation); $this->date = $this->db->jdate($obj->date_reception); // TODO deprecated @@ -1530,9 +1531,14 @@ class Reception extends CommonObject $error = 0; + // Protection. This avoid to move stock later when we should not + if ($this->statut == self::STATUS_CLOSED) { + return 0; + } + $this->db->begin(); - $sql = 'UPDATE '.MAIN_DB_PREFIX.'reception SET fk_statut='.self::STATUS_CLOSED; + $sql = 'UPDATE '.MAIN_DB_PREFIX.'reception SET fk_statut = '.self::STATUS_CLOSED; $sql .= " WHERE rowid = ".((int) $this->id).' AND fk_statut > 0'; $resql = $this->db->query($sql); @@ -1562,7 +1568,7 @@ class Reception extends CommonObject } $this->statut = self::STATUS_CLOSED; - + $this->status = self::STATUS_CLOSED; // If stock increment is done on closing if (!$error && isModEnabled('stock') && !empty($conf->global->STOCK_CALCULATE_ON_RECEPTION_CLOSE)) { @@ -1653,7 +1659,7 @@ class Reception extends CommonObject } /** - * Classify the reception as invoiced (used when WORKFLOW_EXPEDITION_CLASSIFY_CLOSED_INVOICE is on) + * Classify the reception as invoiced (used for exemple by trigger when WORKFLOW_RECEPTION_CLASSIFY_BILLED_INVOICE is on) * * @return int <0 if ko, >0 if ok */ @@ -1666,17 +1672,17 @@ class Reception extends CommonObject $this->setClosed(); - $sql = 'UPDATE '.MAIN_DB_PREFIX.'reception SET billed=1'; + $sql = 'UPDATE '.MAIN_DB_PREFIX.'reception SET billed=1'; $sql .= " WHERE rowid = ".((int) $this->id).' AND fk_statut > 0'; $resql = $this->db->query($sql); if ($resql) { - $this->statut = 2; $this->billed = 1; // Call trigger $result = $this->call_trigger('RECEPTION_BILLED', $user); if ($result < 0) { + $this->billed = 0; $error++; } } else { diff --git a/htdocs/reception/list.php b/htdocs/reception/list.php index b06a11ef5b9..95180890233 100644 --- a/htdocs/reception/list.php +++ b/htdocs/reception/list.php @@ -129,7 +129,7 @@ $arrayfields = array( 'e.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), 'e.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), 'e.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), - 'e.billed'=>array('label'=>$langs->trans("Billed"), 'checked'=>1, 'position'=>1000, 'enabled'=>(!empty($conf->global->WORKFLOW_BILL_ON_RECEPTION))) + 'e.billed'=>array('label'=>$langs->trans("Billed"), 'checked'=>1, 'position'=>1000, 'enabled'=>'getDolGlobalConst("WORKFLOW_BILL_ON_RECEPTION") !== "0"') ); // Extra fields