diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php
index 80d8bb47020..7c6d65266c9 100644
--- a/htdocs/compta/facture/list.php
+++ b/htdocs/compta/facture/list.php
@@ -1466,10 +1466,8 @@ if (isModEnabled('prelevement') && $user->hasRight('prelevement', 'bons', 'creer
$arrayofmassactions['withdrawrequest'] = img_picto('', 'payment', 'class="pictofixedwidth"').$langs->trans("MakeWithdrawRequest");
}
if ($user->hasRight('facture', 'supprimer')) {
- if (getDolGlobalString('INVOICE_CAN_REMOVE_DRAFT_ONLY')) {
+ if (!getDolGlobalString('INVOICE_DIABLE_MASS_DELETION_ON_DRAFT_INVOICES')) {
$arrayofmassactions['predeletedraft'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Deletedraft");
- } elseif (getDolGlobalString('INVOICE_CAN_ALWAYS_BE_REMOVED')) { // mass deletion never possible on invoices on such situation
- $arrayofmassactions['predelete'] = img_picto('', 'delete', 'class="pictofixedwidth"').$langs->trans("Delete");
}
}
if (in_array($massaction, array('presend', 'predelete', 'makepayment'))) {
diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php
index b04acf3fb28..1ebe5c9ca5e 100644
--- a/htdocs/core/actions_massactions.inc.php
+++ b/htdocs/core/actions_massactions.inc.php
@@ -1150,7 +1150,7 @@ if (!$error && ($massaction == 'delete' || ($action == 'delete' && $confirm == '
$result = $objecttmp->fetch($toselectid);
if ($result > 0) {
// Refuse deletion for some objects/status
- if ($objectclass == 'Facture' && !getDolGlobalString('INVOICE_CAN_ALWAYS_BE_REMOVED') && $objecttmp->status != Facture::STATUS_DRAFT) {
+ if ($objectclass == 'Facture' && $objecttmp->status != Facture::STATUS_DRAFT) {
$langs->load("errors");
$nbignored++;
$TMsg[] = '
'.$langs->trans('ErrorOnlyDraftStatusCanBeDeletedInMassAction', $objecttmp->ref).'
';
diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php
index 703977c2035..139ac5245d4 100644
--- a/htdocs/core/class/commoninvoice.class.php
+++ b/htdocs/core/class/commoninvoice.class.php
@@ -777,6 +777,7 @@ abstract class CommonInvoice extends CommonObject
$this->fetch_thirdparty(); // We need to have this->thirdparty defined, in case of the numbering rule uses tags that depend on thirdparty (like {t} tag).
}
$maxref = $this->getNextNumRef($this->thirdparty, 'last');
+ // $maxref can be '' (means not found) if there is no invoice yet, but also if there is no invoice for the new period when there is a reset at each period
// If invoice to delete is not the last one, we refuse
if ($maxref != '' && $maxref != $this->ref) {
diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php
index 06c4d795345..936aba8d4e9 100644
--- a/htdocs/core/lib/admin.lib.php
+++ b/htdocs/core/lib/admin.lib.php
@@ -1188,7 +1188,7 @@ function purgeSessions($mysessionid)
/**
* Enable a module
*
- * @param string $value Name of module to activate
+ * @param string $value Name of module to activate (modModuleName)
* @param int $withdeps Activate/Disable also all dependencies
* @param int $noconfverification Remove verification of $conf variable for module
* @return array{nbmodules?:int,errors:string[],nbperms?:int} array('nbmodules'=>nb modules activated with success, 'errors=>array of error messages, 'nbperms'=>Nb permission added);
@@ -1249,7 +1249,6 @@ function activateModule($value, $withdeps = 1, $noconfverification = 0)
$ret['errors'][] = $langs->trans("ErrorModuleRequireJavascript");
return $ret;
}
-
$const_name = $objMod->const_name;
if ($noconfverification == 0) {
if (getDolGlobalString($const_name)) {
diff --git a/htdocs/core/modules/facture/mod_facture_mercure.php b/htdocs/core/modules/facture/mod_facture_mercure.php
index 31a01aa92ba..b5e4b2fe70f 100644
--- a/htdocs/core/modules/facture/mod_facture_mercure.php
+++ b/htdocs/core/modules/facture/mod_facture_mercure.php
@@ -188,6 +188,7 @@ class mod_facture_mercure extends ModeleNumRefFactures
// Get entities
$entity = getEntity('invoicenumber', 1, $invoice);
+
$numFinal = get_next_value($db, $mask, 'facture', 'ref', $where, $objsoc, (empty($invoice) ? dol_now() : $invoice->date), $mode, false, null, $entity);
if (!preg_match('/([0-9])+/', $numFinal)) {
$this->error = $numFinal;
diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang
index 05319e52d9b..bf2c9629a9c 100644
--- a/htdocs/langs/en_US/errors.lang
+++ b/htdocs/langs/en_US/errors.lang
@@ -374,6 +374,7 @@ ErrorBlockLogNeedElement=The unalterbale log object needs element type to be set
ErrorBlockLogNeedObject=The unalterbale log object needs object to be set
ErrorBadParameterWhenCallingCreateOfBlockedLog=Bad parameter when calling create of blocked log
ErrorMaxDecimalsShownTooLowComparedToUnitOrTotal=Value for 'Max. decimals for prices shown on screen' (%s) must be equal to or greater than both 'Max. decimals for unit prices' (%s) and 'Max. decimals for total prices' (%s). This is required to prevent rounding inconsistencies on documents.
+ErrorOnlyDraftStatusCanBeDeletedInMassAction=Only elements in draft status can be deleted in mass action
# Warnings
WarningParamUploadMaxFileSizeHigherThanPostMaxSize=Your PHP parameter upload_max_filesize (%s) is higher than PHP parameter post_max_size (%s). This is not a consistent setup.
diff --git a/htdocs/langs/en_US/trips.lang b/htdocs/langs/en_US/trips.lang
index bba49dfd54a..9b36906da8e 100644
--- a/htdocs/langs/en_US/trips.lang
+++ b/htdocs/langs/en_US/trips.lang
@@ -121,7 +121,6 @@ ValideTrip=Approve expense report
ExpenseReportPayments=Expense report payments
TaxUndefinedForThisCategory = Tax is undefined for this category
errorComputeTtcOnMileageExpense=Error on computing mileage expense
-ErrorOnlyDraftStatusCanBeDeletedInMassAction=Only elements in draft status can be deleted in mass action
## Dictionary
EX_BRE=Breakfast
diff --git a/test/phpunit/NumberingModulesTest.php b/test/phpunit/NumberingModulesTest.php
index 290e8f6ab27..1550f2b8cea 100644
--- a/test/phpunit/NumberingModulesTest.php
+++ b/test/phpunit/NumberingModulesTest.php
@@ -29,6 +29,7 @@ global $conf,$user,$langs,$db;
//define('TEST_DB_FORCE_TYPE','mysql'); // This is to force using mysql driver
//require_once 'PHPUnit/Autoload.php';
require_once dirname(__FILE__).'/../../htdocs/master.inc.php';
+require_once dirname(__FILE__).'/../../htdocs/core/lib/admin.lib.php';
require_once dirname(__FILE__).'/CommonClassTest.class.php';
if (empty($user->id)) {
@@ -71,7 +72,7 @@ class NumberingModulesTest extends CommonClassTest
$conf->global->FACTURE_MERCURE_MASK_CREDIT = '{yyyy}-{0000}';
$conf->global->FACTURE_MERCURE_MASK_DEPOSIT = '{yyyy}-{0000}';
$conf->global->FACTURE_MERCURE_MASK_REPLACEMENT = '{yyyy}-{0000}';
- $conf->global->INVOICE_CAN_ALWAYS_BE_REMOVED = 0;
+ $conf->global->FAC_FORCE_DATE_VALIDATION = 0; // We disable option "Force date on validation", so we can make test on old dates
$localobject = new Facture($db);
$localobject->initAsSpecimen();
@@ -87,16 +88,26 @@ class NumberingModulesTest extends CommonClassTest
$result3 = $localobject->validate($user, $result); // create invoice by forcing ref
print __METHOD__." result3=".$result."\n";
$this->assertEquals(1, $result3, 'Test validation of invoice with forced ref is ok'); // counter must start to 1
+
+ // Force enable of BlockedLog (not possible from application, but required to allow the test with sample data))
+ activateModule('modBlockedLog', 1, 1);
+
$result = $localobject->is_erasable();
print __METHOD__." is_erasable=".$result."\n";
- $this->assertGreaterThanOrEqual(1, $result, 'Test for is_erasable, 1st invoice'); // Can be deleted
+ $this->assertEquals(-7, $result, 'Test for is_erasable, 1st invoice without other invoice'); // Can be deleted
+
+ // Disable module BlockedLog (not possible from application, but required to allow the test with sample data))
+ unActivateModule('modBlockedLog');
+
+ $result = $localobject->is_erasable();
+ print __METHOD__." is_erasable=".$result."\n";
+ $this->assertGreaterThanOrEqual(1, $result, 'Test for is_erasable, 1st invoice without other invoice'); // Can be deleted
// We emulate print on invoice 3 times
$localobject->pos_print_counter = 3;
$result = $localobject->is_erasable();
print __METHOD__." is_erasable=".$result."\n";
- $this->assertGreaterThanOrEqual(-6, $result, 'Test for is_erasable, 1st invoice already printed'); // Can be deleted
-
+ $this->assertGreaterThanOrEqual(-6, $result, 'Test for is_erasable, 1st invoice already printed'); // Can be deleted
$localobject2 = new Facture($db);
$localobject2->initAsSpecimen();
@@ -220,6 +231,7 @@ class NumberingModulesTest extends CommonClassTest
$result = $numbering->getNextValue($mysoc, $localobject2);
$result2 = $localobject2->create($user, 1);
$result3 = $localobject2->validate($user, $result);
+
print __METHOD__." result=".$result."\n";
$this->assertEquals('0125-0002', $result, 'Test for {mm}{yy}-{0000@1} 2nd invoice'); // counter must be now 2
$result = $localobject2->is_erasable();
@@ -227,7 +239,7 @@ class NumberingModulesTest extends CommonClassTest
$this->assertGreaterThanOrEqual(1, $result); // Can be deleted
$result = $localobject->is_erasable();
print __METHOD__." is_erasable=".$result."\n";
- $this->assertLessThanOrEqual(0, $result); // Case 1 can not be deleted (because there is an invoice 2)
+ $this->assertLessThanOrEqual(0, $result, 'Test that invoice '.$localobject->ref.' is not erasable failed'); // Invoice 1 can not be deleted (because there is an invoice 2)
$localobject3 = new Facture($db);
$localobject3->initAsSpecimen();
@@ -609,11 +621,11 @@ class NumberingModulesTest extends CommonClassTest
$localobject->initAsSpecimen();
$localobject->fetch_thirdparty();
- $localobject->date_creation = dol_mktime(12, 0, 0, 1, 1, 1980); // we use year 1915 to be sure to not have existing invoice for this year (useful only if numbering is {0000@1}
+ $localobject->date_creation = dol_mktime(12, 0, 0, 1, 1, 1980); // we use year 1980 to be sure to not have existing invoice for this year (useful only if numbering is {0000@1}
$numbering = new mod_expedition_safor();
$result = $numbering->getNextValue($mysoc, $localobject);
print __METHOD__." result=".$result."\n";
- $this->assertEquals('SH8001-0003', $result); // counter must start to 1
+ $this->assertEquals('SH8001-0003', $result); // SH8001-0003 is valid with dataset demo
}
}