diff --git a/htdocs/blockedlog/class/blockedlog.class.php b/htdocs/blockedlog/class/blockedlog.class.php index 027bebe41aa..e7376e67656 100644 --- a/htdocs/blockedlog/class/blockedlog.class.php +++ b/htdocs/blockedlog/class/blockedlog.class.php @@ -173,6 +173,12 @@ class BlockedLog */ public $trackedevents = array(); + /** + * Array of controlled event codes + * @var array + */ + public $controlledevents = array(); + /** * Array of tracked modules (key => label) * @var array @@ -193,7 +199,7 @@ class BlockedLog /** - * Load list of tracked events into $this->trackedevents. + * Load list of tracked and controlled events into $this->controlled, $this->trackedevents and $this->trackedmodules * * @return int<1,1> Always 1 */ @@ -201,11 +207,14 @@ class BlockedLog { global $langs; + $this->controlledevents = array(); $this->trackedevents = array(); $this->trackedmodules = array(); $sep = 0; + $this->controlledevents = array('BILL_MODIFY'); + $this->trackedmodules[0] = 'None'; if (isModEnabled('takepos')) { $this->trackedmodules['takepos'] = 'TakePOS'; diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index b144fd554ec..77e1f85723e 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -1787,7 +1787,9 @@ function dol_get_object_properties($obj, $properties = []) * Create a clone of instance of object (new instance with same value for each properties) * With native = 0: Deprecated. Property that are references are different memory area in the new object (full isolation clone). This means $this->objectproperty of the new object may not be valid (except this->db that is voluntarly kept). * With native = 1: Use PHP clone. Property that are reference are same pointer. This means $this->db of new object is still valid but point to same this->db than original object. - * With native = 2: Property that are reference are different memory area in the new object (full isolation clone). Only scalar and array values are cloned. This means method are not availables and $this->db of new object is not valid. + * With native = 2: Property that are reference are different memory area in the new object (full isolation clone). Only scalar and array values are cloned. This means that the methods are not available and $this->db of new object is not valid. + * You can use it with: $object->oldcopy = dol_clone($object, 2); // @phan-suppress-current-line PhanTypeMismatchProperty + * * * @template T * diff --git a/htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php b/htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php index b4c49e1bb84..8b5c7a15e68 100644 --- a/htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php +++ b/htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php @@ -66,7 +66,7 @@ class InterfaceActionsBlockedLog extends DolibarrTriggers } // List of mandatory logged actions - $listofqualifiedelement = array('invoice', 'facture', 'don', 'payment', 'payment_donation', 'subscription', 'payment_various', 'cashcontrol'); + $listofqualifiedelement = array('invoice', 'facture', 'don', 'payment', 'payment_donation', 'subscription', 'cashcontrol'); // Add custom actions to log if (getDolGlobalString('BLOCKEDLOG_ADD_ACTIONS_SUPPORTED')) { @@ -86,7 +86,7 @@ class InterfaceActionsBlockedLog extends DolibarrTriggers $b->loadTrackedEvents(); // Get the list of tracked events into $b->trackedevents // Tracked events - if (!in_array($action, array_keys($b->trackedevents))) { + if (!in_array($action, array_keys($b->trackedevents)) && !in_array($action, array_keys($b->controlledevents))) { return 0; } @@ -105,13 +105,32 @@ class InterfaceActionsBlockedLog extends DolibarrTriggers } } // Test there is not invoices with id in $invoiceids and with a module_source that is not empty - - //$this->errors[] = 'The payment mode '.$object->paiementcode.' is not available in this version.'; - //return -1; + $tmpinvoice = new Facture($this->db); + foreach ($invoiceids as $invoiceid) { + $tmpinvoice->fetch($invoiceid); + if ($tmpinvoice->module_source == 'takepos') { + $this->errors[] = 'The payment mode '.$object->paiementcode.' is not available in this version for payment of invoices generated from '.$tmpinvoice->module_source; + return -1; + } + } } } } + // Protect against modification of data that should be immutable on a validated invoice + if (($action === 'BILL_MODIFY' || $action === 'FACTURE_MODIFY') && !empty($object->oldcopy) && in_array($object->element, array('invoice', 'facture')) && $object->status != 0) { + if ($object->oldcopy->ref != $object->ref) { + $this->errors[] = 'Modifying the property Ref of a non draft invoice is not allowed'; + return -2; + } + if (($object->oldcopy->total_ht != $object->total_ht) || ($object->oldcopy->total_tva != $object->total_tva) || ($object->oldcopy->total_ttc != $object->total_ttc) + || ($object->oldcopy->date != $object->date) || ($object->oldcopy->thirdparty->revenuestamp != $object->thirdparty->revenuestamp) + ) { + $this->errors[] = 'You try to modify a property that is locked once the invoice has been validated (total, revenu stamp).'; + return -2; + } + } + // Event/record is qualified $qualified = 0; $amounts_taxexcl = null;