NEW Add a protection against total change on a validated invoice.

This commit is contained in:
Laurent Destailleur
2026-01-12 13:44:30 +01:00
parent 15054810ba
commit 91c35d4e40
3 changed files with 37 additions and 7 deletions

View File

@@ -173,6 +173,12 @@ class BlockedLog
*/
public $trackedevents = array();
/**
* Array of controlled event codes
* @var array<string,string|mixed>
*/
public $controlledevents = array();
/**
* Array of tracked modules (key => label)
* @var array<int|string,string>
@@ -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';

View File

@@ -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
*

View File

@@ -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;