mirror of
https://github.com/Dolibarr/dolibarr.git
synced 2025-12-05 09:08:09 +01:00
Compare commits
4 Commits
5bcd5db58f
...
e2595b5117
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e2595b5117 | ||
|
|
793d846d94 | ||
|
|
10b087e209 | ||
|
|
e60de6525b |
@@ -30,12 +30,6 @@
|
||||
|
||||
// Load Dolibarr environment
|
||||
require '../main.inc.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/defaultvalues.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
|
||||
|
||||
/**
|
||||
* @var Conf $conf
|
||||
* @var DoliDB $db
|
||||
@@ -43,6 +37,11 @@ require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
|
||||
* @var Translate $langs
|
||||
* @var User $user
|
||||
*/
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/agenda.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/html.formactions.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/class/defaultvalues.class.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/comm/action/class/actioncomm.class.php';
|
||||
|
||||
if (!$user->admin) {
|
||||
accessforbidden();
|
||||
|
||||
@@ -34,10 +34,6 @@ if (!defined('NOTOKENRENEWAL')) {
|
||||
|
||||
// Load Dolibarr environment
|
||||
require '../main.inc.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
||||
|
||||
/**
|
||||
* @var Conf $conf
|
||||
* @var DoliDB $db
|
||||
@@ -45,6 +41,9 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
||||
* @var Translate $langs
|
||||
* @var User $user
|
||||
*/
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
|
||||
require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
||||
|
||||
// Load translation files required by the page
|
||||
$langs->loadLangs(array('errors', 'admin', 'modulebuilder', 'exports'));
|
||||
@@ -268,7 +267,7 @@ $head = modulehelp_prepare_head($objMod);
|
||||
|
||||
// Check filters
|
||||
$modulename = $objMod->getName();
|
||||
$moduledesc = $objMod->getDesc();
|
||||
$moduledesc = $objMod->getDesc(1);
|
||||
$moduleauthor = $objMod->getPublisher();
|
||||
$moduledir = strtolower(preg_replace('/^mod/i', '', get_class($objMod)));
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ BLOCKED LOG
|
||||
## Feature
|
||||
|
||||
This module tracks, in real time, some events into a non reversible log (that you can't modify once recorded) into a block chain.
|
||||
This module provides compatibility with requirements of laws of some countries (like France with the law Finance 2016 - Norme NF525).
|
||||
This module provides compatibility with requirements of laws of some countries (like France with the Law Finance or Spain with VeriFactu).
|
||||
|
||||
|
||||
**The tracked events are:**
|
||||
@@ -17,6 +17,3 @@ You can also read and search into this dedicated log.
|
||||
|
||||
All record in the log are linked with the previous one in a blockchain, and content of the record is part of the
|
||||
signature included into the link, so, once the module is activated, it is no more possible to erase or modify a record without corrupting all the chain.
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ require '../../main.inc.php';
|
||||
* @var Conf $conf
|
||||
* @var DoliDB $db
|
||||
* @var HookManager $hookmanager
|
||||
* @var Societe $mysoc
|
||||
* @var Translate $langs
|
||||
* @var User $user
|
||||
*/
|
||||
@@ -90,26 +91,39 @@ $form = new Form($db);
|
||||
$block_static = new BlockedLog($db);
|
||||
$block_static->loadTrackedEvents();
|
||||
|
||||
$title = $langs->trans("BlockedLogSetup");
|
||||
$title = $langs->trans("ModuleSetup").' '.$langs->trans('BlockedLog');
|
||||
$help_url="EN:Module_Unalterable_Archives_-_Logs|FR:Module_Archives_-_Logs_Inaltérable";
|
||||
|
||||
llxHeader('', $title, $help_url, '', 0, 0, '', '', '', 'mod-blockedlog page-admin_blockedlog');
|
||||
|
||||
$linkback = '';
|
||||
if ($withtab) {
|
||||
$linkback = '<a href="'.($backtopage ? $backtopage : DOL_URL_ROOT.'/admin/modules.php').'">'.$langs->trans("BackToModuleList").'</a>';
|
||||
$linkback = '<a href="'.dolBuildUrl($backtopage ? $backtopage : DOL_URL_ROOT.'/admin/modules.php', ['restore_lastsearch_values' => 1]).'">'.img_picto($langs->trans("BackToModuleList"), 'back', 'class="pictofixedwidth"').'<span class="hideonsmartphone">'.$langs->trans("BackToModuleList").'</span></a>';
|
||||
}
|
||||
|
||||
print load_fiche_titre($langs->trans("ModuleSetup").' '.$langs->trans('BlockedLog'), $linkback, 'blockedlog');
|
||||
$morehtmlcenter = '';
|
||||
|
||||
$registrationnumber = getHashUniqueIdOfRegistration();
|
||||
$texttop = '<small class="opacitymedium">'.$langs->trans("RegistrationNumber").':</small> <small>'.dol_trunc($registrationnumber, 10).'</small>';
|
||||
|
||||
print load_fiche_titre($title, $linkback, 'blockedlog', 0, '', '', $morehtmlcenter);
|
||||
|
||||
if ($withtab) {
|
||||
$head = blockedlogadmin_prepare_head(GETPOST('withtab', 'alpha'));
|
||||
print dol_get_fiche_head($head, 'blockedlog', '', -1);
|
||||
}
|
||||
|
||||
print $texttop;
|
||||
print '<br><br>';
|
||||
|
||||
print '<span class="opacitymedium">'.$langs->trans("BlockedLogDesc")."</span><br>\n";
|
||||
|
||||
if ($mysoc->country_code == 'FR') {
|
||||
$htmltext = $langs->trans("UnalterableLogTool1FR").'<br>';
|
||||
}
|
||||
|
||||
print info_admin($htmltext, 0, 0, 'warning');
|
||||
|
||||
print '<br>';
|
||||
|
||||
print '<div class="div-table-responsive">'; // You can use div-table-responsive-no-min if you don't need reserved height for your table
|
||||
|
||||
@@ -426,19 +426,26 @@ if (!is_array($blocks)) {
|
||||
|
||||
$linkback = '';
|
||||
if (GETPOST('withtab', 'alpha')) {
|
||||
$linkback = '<a href="'.($backtopage ? $backtopage : DOL_URL_ROOT.'/admin/modules.php').'">'.$langs->trans("BackToModuleList").'</a>';
|
||||
$linkback = '<a href="'.dolBuildUrl($backtopage ? $backtopage : DOL_URL_ROOT.'/admin/modules.php', ['restore_lastsearch_values' => 1]).'">'.img_picto($langs->trans("BackToModuleList"), 'back', 'class="pictofixedwidth"').'<span class="hideonsmartphone">'.$langs->trans("BackToModuleList").'</span></a>';
|
||||
}
|
||||
|
||||
print load_fiche_titre($title, $linkback, 'blockedlog');
|
||||
$morehtmlcenter = '';
|
||||
|
||||
$registrationnumber = getHashUniqueIdOfRegistration();
|
||||
$texttop = '<small class="opacitymedium">'.$langs->trans("RegistrationNumber").':</small> <small>'.dol_trunc($registrationnumber, 10).'</small>';
|
||||
|
||||
print load_fiche_titre($title, $linkback, 'blockedlog', 0, '', '', $morehtmlcenter);
|
||||
|
||||
$head = blockedlogadmin_prepare_head(GETPOST('withtab', 'alpha'));
|
||||
|
||||
print dol_get_fiche_head($head, 'archives', '', -1);
|
||||
|
||||
print $texttop;
|
||||
print '<br><br>';
|
||||
|
||||
print '<div class="opacitymedium hideonsmartphone justify">';
|
||||
|
||||
print $langs->trans("ArchivesDesc")."<br>";
|
||||
print "<br>\n";
|
||||
|
||||
print "</div>\n";
|
||||
|
||||
@@ -451,7 +458,7 @@ if ($mysoc->country_code == 'FR') {
|
||||
//$htmltext .= $langs->trans("UnalterableLogTool1");
|
||||
//$htmltext .= $langs->trans("UnalterableLogTool3")."<br>";
|
||||
|
||||
print info_admin($htmltext);
|
||||
print info_admin($htmltext, 0, 0, 'warning');
|
||||
|
||||
|
||||
print '<br>';
|
||||
|
||||
@@ -396,15 +396,23 @@ if (!is_array($blocks)) {
|
||||
|
||||
$linkback = '';
|
||||
if (GETPOST('withtab', 'alpha')) {
|
||||
$linkback = '<a href="'.($backtopage ? $backtopage : DOL_URL_ROOT.'/admin/modules.php').'">'.$langs->trans("BackToModuleList").'</a>';
|
||||
$linkback = '<a href="'.dolBuildUrl($backtopage ? $backtopage : DOL_URL_ROOT.'/admin/modules.php', ['restore_lastsearch_values' => 1]).'">'.img_picto($langs->trans("BackToModuleList"), 'back', 'class="pictofixedwidth"').'<span class="hideonsmartphone">'.$langs->trans("BackToModuleList").'</span></a>';
|
||||
}
|
||||
|
||||
print load_fiche_titre($title, $linkback, 'blockedlog');
|
||||
$morehtmlcenter = '';
|
||||
|
||||
$registrationnumber = getHashUniqueIdOfRegistration();
|
||||
$texttop = '<small class="opacitymedium">'.$langs->trans("RegistrationNumber").':</small> <small>'.dol_trunc($registrationnumber, 10).'</small>';
|
||||
|
||||
print load_fiche_titre($title, $linkback, 'blockedlog', 0, '', '', $morehtmlcenter);
|
||||
|
||||
$head = blockedlogadmin_prepare_head(GETPOST('withtab', 'alpha'));
|
||||
|
||||
print dol_get_fiche_head($head, 'fingerprints', '', -1);
|
||||
|
||||
print $texttop;
|
||||
print '<br><br>';
|
||||
|
||||
print '<div class="opacitymedium hideonsmartphone justify">';
|
||||
|
||||
print $langs->trans("FingerprintsDesc")."<br>";
|
||||
|
||||
@@ -82,7 +82,7 @@ function blockedlogadmin_prepare_head($withtabsetup)
|
||||
*
|
||||
* @return boolean True or false
|
||||
*/
|
||||
function isRegistrationRecorded()
|
||||
function isRegistrationDataSaved()
|
||||
{
|
||||
global $mysoc;
|
||||
|
||||
@@ -105,24 +105,41 @@ function isRegistrationRecorded()
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return if the version is a candidate version to get the LNE certification and if the prerequisites are OK.
|
||||
* The difference between isALNEQualifiedVersion() and isALNERunningVersion() is that this one just check if it has a sense or not to
|
||||
* activate the restrictions (it is not a strict check) and the second one is a strict check to say restrictions must be enabled and can't be disabled.
|
||||
* Return a hash unique identifier of the registration
|
||||
*
|
||||
* @return boolean True or false
|
||||
* @return string Hash unique ID (used to idenfiy the registration without disclosing personal data)
|
||||
*/
|
||||
function isALNEQualifiedVersion()
|
||||
function getHashUniqueIdOfRegistration()
|
||||
{
|
||||
global $conf;
|
||||
|
||||
return dol_hash('dolibarr'.$conf->file->instance_unique_id, 'sha256', 1);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Return if the version is a candidate version to get the LNE certification and if the prerequisites are OK in production to be switched to LNE certified mode.
|
||||
* The difference with isALNERunningVersion() is that isALNEQualifiedVersion() just checks if it has a sense or not to activate
|
||||
* the restrictions (it is not a check to say if we are or not in a mode with restrictions activated, but if we are in a context that has a sense to activate them).
|
||||
* It can be used to show warnings or alerts to end users.
|
||||
*
|
||||
* @param int<0,1> $ignoredev Set this to 1 to ignore the fact the version is an alpha or beta version
|
||||
* @param int<0,1> $ignoremodule Set this to 1 to not take into account if module BlockedLog is on, so function can be used during module activation.
|
||||
* @return boolean True or false
|
||||
*/
|
||||
function isALNEQualifiedVersion($ignoredev = 0, $ignoremodule = 0)
|
||||
{
|
||||
global $mysoc;
|
||||
|
||||
// For Debug help: Constant set by developer to force all LNE restrictions even if country is not France so we can test them on any dev instance.
|
||||
// Note that you can force, with this option, to enabling of the LNE restrictions but you can't force the disabling of the LNE restriction.
|
||||
// Note that you can force, with this option, the enabling of the LNE restrictions, but there is no way to force the disabling of the LNE restriction.
|
||||
if (defined('CERTIF_LNE') && (int) constant('CERTIF_LNE') === 2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (preg_match('/\-/', DOL_VERSION)) { // This is not a stable version
|
||||
if (!$ignoredev && preg_match('/\-/', DOL_VERSION)) { // This is not a stable version
|
||||
return false;
|
||||
}
|
||||
if ($mysoc->country_code != 'FR') {
|
||||
@@ -131,7 +148,7 @@ function isALNEQualifiedVersion()
|
||||
if (!defined('CERTIF_LNE') || (int) constant('CERTIF_LNE') === 0) {
|
||||
return false;
|
||||
}
|
||||
if (!isModEnabled('blockedlog')) {
|
||||
if (!$ignoremodule && !isModEnabled('blockedlog')) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -140,16 +157,15 @@ function isALNEQualifiedVersion()
|
||||
|
||||
|
||||
/**
|
||||
* Return if the application is executed with the LNE features on.
|
||||
* This function is used to disabled some features like disabling custom receipts, or showing the mandatory information "Certified LNE"
|
||||
* on tickets when it is not true.
|
||||
* Return if the application is executed with the LNE requirements on.
|
||||
* This function can be used to disable some features like custom receipts, or to enable others like showing the information "Certified LNE".
|
||||
*
|
||||
* @return boolean True or false
|
||||
* @return boolean True or false
|
||||
*/
|
||||
function isALNERunningVersion()
|
||||
{
|
||||
// For Debug help: Constant set by developer to force all LNE restrictions even if country is not France so we can test them on any dev instance.
|
||||
// Note that you can force, with this option, to enabling of the LNE restrictions but you can't force the disabling of the LNE restriction.
|
||||
// Note that you can force, with this option, the enabling of the LNE restrictions, but there is no way to force the disabling of the LNE restriction.
|
||||
if (defined('CERTIF_LNE') && (int) constant('CERTIF_LNE') === 2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -541,22 +541,29 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
|
||||
if (!$error) {
|
||||
$db->begin();
|
||||
|
||||
$dayinyear = dol_print_date($object->datep, '%m%d');
|
||||
$dayinmonth = dol_print_date($object->datep, '%d');
|
||||
$dayinweek = dol_print_date($object->datep, '%w');
|
||||
|
||||
$selectedrecurrulefreq = 'no';
|
||||
$selectedrecurrulebyyearmonthday = '';
|
||||
$selectedrecurrulebymonthday = '';
|
||||
$selectedrecurrulebyday = '';
|
||||
$object->recurrule = GETPOSTISSET('recurrulefreq') ? "FREQ=".GETPOST('recurrulefreq', 'alpha') : "";
|
||||
$object->recurrule .= (GETPOST('recurrulefreq', 'alpha') == 'YEARLY') ? "_BYYEARMONTHDAY".((int) $dayinyear) : "";
|
||||
$object->recurrule .= (GETPOST('recurrulefreq', 'alpha') == 'MONTHLY') ? "_BYMONTHDAY".((int) $dayinmonth) : "";
|
||||
$object->recurrule .= (GETPOST('recurrulefreq', 'alpha') == 'WEEKLY') ? "_BYDAY".((int) $dayinweek) : "";
|
||||
|
||||
$reg1 = [];
|
||||
$reg2 = [];
|
||||
$reg3 = [];
|
||||
$reg4 = [];
|
||||
if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg1)) {
|
||||
$selectedrecurrulefreq = $reg1[1];
|
||||
}
|
||||
if ($object->recurrule && preg_match('/FREQ=YEARLY.*BYYEARMONTHDAY(\d+)/i', $object->recurrule, $reg4)) {
|
||||
$selectedrecurrulebyyearmonthday = (int) $reg4[1];
|
||||
}
|
||||
if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY(\d+)/i', $object->recurrule, $reg2)) {
|
||||
$selectedrecurrulebymonthday = (int) $reg2[1];
|
||||
}
|
||||
@@ -689,10 +696,9 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
|
||||
|
||||
if ($res <= 0) {
|
||||
// If error
|
||||
$db->rollback();
|
||||
$langs->load("errors");
|
||||
$error = $langs->trans('ErrorReminderActionCommCreation');
|
||||
setEventMessages($error, null, 'errors');
|
||||
$error++;
|
||||
setEventMessages($langs->trans('ErrorReminderActionCommCreation'), null, 'errors');
|
||||
$action = 'create';
|
||||
$donotclearsession = 1;
|
||||
break;
|
||||
@@ -707,13 +713,6 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
|
||||
*/
|
||||
$moreparam .= ($moreparam ? '&' : '').'disabledefaultvalues=1';
|
||||
|
||||
if ($error) {
|
||||
$db->rollback();
|
||||
} else {
|
||||
$db->commit();
|
||||
}
|
||||
|
||||
|
||||
// if (!empty($backtopage)) {
|
||||
// dol_syslog("Back to ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
|
||||
// header("Location: ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
|
||||
@@ -725,23 +724,24 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
|
||||
// exit;
|
||||
} else {
|
||||
// If error
|
||||
$db->rollback();
|
||||
$langs->load("errors");
|
||||
$error = $langs->trans($object->error);
|
||||
setEventMessages($error, null, 'errors');
|
||||
$error++;
|
||||
setEventMessages($langs->trans($object->error), null, 'errors');
|
||||
$action = 'create';
|
||||
$donotclearsession = 1;
|
||||
}
|
||||
} else {
|
||||
$db->rollback();
|
||||
$error++;
|
||||
setEventMessages($object->error, $object->errors, 'errors');
|
||||
$action = 'create';
|
||||
$donotclearsession = 1;
|
||||
}
|
||||
|
||||
// Manage other events in case of recurring event
|
||||
if (!$error && $eventisrecurring) {
|
||||
$dayoffset = 0;
|
||||
$monthoffset = 0;
|
||||
$yearoffset = 0;
|
||||
// We set first date of recurrence and offsets
|
||||
if ($selectedrecurrulefreq == 'WEEKLY' && !empty($selectedrecurrulebyday)) {
|
||||
$firstdatearray = dol_get_first_day_week(GETPOSTINT("apday"), GETPOSTINT("apmonth"), GETPOSTINT("apyear"));
|
||||
@@ -749,12 +749,21 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
|
||||
$datep = dol_time_plus_duree($datep, $selectedrecurrulebyday + 6, 'd');//We begin the week after
|
||||
$dayoffset = 7;
|
||||
$monthoffset = 0;
|
||||
$yearoffset = 0;
|
||||
} elseif ($selectedrecurrulefreq == 'MONTHLY' && !empty($selectedrecurrulebymonthday)) {
|
||||
$firstday = $selectedrecurrulebymonthday;
|
||||
$firstmonth = GETPOST("apday") > $selectedrecurrulebymonthday ? GETPOSTINT("apmonth") + 1 : GETPOSTINT("apmonth");//We begin the week after
|
||||
$firstmonth = GETPOST("apday") > $selectedrecurrulebymonthday ? GETPOSTINT("apmonth") + 1 : GETPOSTINT("apmonth");//We begin the month after
|
||||
$datep = dol_mktime($fulldayevent ? 0 : GETPOSTINT("aphour"), $fulldayevent ? 0 : GETPOSTINT("apmin"), $fulldayevent ? 0 : GETPOSTINT("apsec"), $firstmonth, $firstday, GETPOSTINT("apyear"), $tzforfullday ? $tzforfullday : 'tzuserrel');
|
||||
$datep = dol_time_plus_duree($datep, 1, 'm');//We begin the month after
|
||||
$dayoffset = 0;
|
||||
$monthoffset = 1;
|
||||
$yearoffset = 0;
|
||||
} elseif ($selectedrecurrulefreq == 'YEARLY' && !empty($selectedrecurrulebyyearmonthday)) {
|
||||
$datep = dol_mktime($fulldayevent ? 0 : GETPOSTINT("aphour"), $fulldayevent ? 0 : GETPOSTINT("apmin"), $fulldayevent ? 0 : GETPOSTINT("apsec"), GETPOSTINT("apmonth"), GETPOSTINT("apday"), GETPOSTINT("apyear"), $tzforfullday ? $tzforfullday : 'tzuserrel');
|
||||
$datep = dol_time_plus_duree($datep, 1, 'y');//We begin the year after
|
||||
$dayoffset = 0;
|
||||
$monthoffset = 0;
|
||||
$yearoffset = 1;
|
||||
} else {
|
||||
$error++;
|
||||
}
|
||||
@@ -809,10 +818,9 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
|
||||
|
||||
if ($res <= 0) {
|
||||
// If error
|
||||
$db->rollback();
|
||||
$error++;
|
||||
$langs->load("errors");
|
||||
$error = $langs->trans('ErrorReminderActionCommCreation');
|
||||
setEventMessages($error, null, 'errors');
|
||||
setEventMessages($langs->trans('ErrorReminderActionCommCreation'), null, 'errors');
|
||||
$action = 'create';
|
||||
$donotclearsession = 1;
|
||||
break;
|
||||
@@ -826,15 +834,9 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
|
||||
$moreparam .= ($moreparam ? '&' : '').'search_filtert='.$object->userownerid;
|
||||
*/
|
||||
$moreparam .= ($moreparam ? '&' : '').'disabledefaultvalues=1';
|
||||
|
||||
if ($error) {
|
||||
$db->rollback();
|
||||
} else {
|
||||
$db->commit();
|
||||
}
|
||||
} else {
|
||||
// If error
|
||||
$db->rollback();
|
||||
$error++;
|
||||
$langs->load("errors");
|
||||
$error = $langs->trans($finalobject->error);
|
||||
setEventMessages($error, null, 'errors');
|
||||
@@ -842,7 +844,7 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
|
||||
$donotclearsession = 1;
|
||||
}
|
||||
} else {
|
||||
$db->rollback();
|
||||
$error++;
|
||||
setEventMessages($finalobject->error, $finalobject->errors, 'errors');
|
||||
$action = 'create';
|
||||
$donotclearsession = 1;
|
||||
@@ -856,10 +858,19 @@ if (empty($reshook) && $action == 'add' && $usercancreate) {
|
||||
// increment date for recurrent events
|
||||
$datep = dol_time_plus_duree($datep, $dayoffset, 'd');
|
||||
$datep = dol_time_plus_duree($datep, $monthoffset, 'm'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder
|
||||
$datep = dol_time_plus_duree($datep, $yearoffset, 'y'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder
|
||||
$datef = dol_time_plus_duree($datef, $dayoffset, 'd');
|
||||
$datef = dol_time_plus_duree($datef, $monthoffset, 'm'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder
|
||||
$datef = dol_time_plus_duree($datef, $yearoffset, 'y'); // @phan-suppress-current-line PhanPluginSuspiciousParamOrder
|
||||
}
|
||||
}
|
||||
|
||||
if ($error) {
|
||||
$db->rollback();
|
||||
} else {
|
||||
$db->commit();
|
||||
}
|
||||
|
||||
if (!empty($backtopage) && !$error) {
|
||||
dol_syslog("Back to ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
|
||||
header("Location: ".$backtopage.($moreparam ? (preg_match('/\?/', $backtopage) ? '&'.$moreparam : '?'.$moreparam) : ''));
|
||||
@@ -1335,6 +1346,7 @@ $formproject = new FormProjets($db);
|
||||
|
||||
$arrayrecurrulefreq = array(
|
||||
'no' => $langs->trans("OnceOnly"),
|
||||
'YEARLY' => $langs->trans("EveryYear"),
|
||||
'MONTHLY' => $langs->trans("EveryMonth"),
|
||||
'WEEKLY' => $langs->trans("EveryWeek")
|
||||
// 'DAILY'=>$langs->trans("EveryDay")
|
||||
@@ -1521,9 +1533,11 @@ if ($action == 'create') {
|
||||
print '<input type="hidden" name="recurid" value="'.(empty($object->recurid) ? '' : $object->recurid).'">';
|
||||
|
||||
$selectedrecurrulefreq = 'no';
|
||||
$selectedrecurrulebyyearmonthday = '';
|
||||
$selectedrecurrulebymonthday = '';
|
||||
$selectedrecurrulebyday = '';
|
||||
$object->recurrule = GETPOSTISSET('recurrulefreq') ? "FREQ=".GETPOST('recurrulefreq', 'alpha') : "";
|
||||
$object->recurrule .= GETPOSTISSET('BYYEARMONTHDAY') ? "_BYYEARMONTHDAY".GETPOST('BYYEARMONTHDAY', 'alpha') : "";
|
||||
$object->recurrule .= GETPOSTISSET('BYMONTHDAY') ? "_BYMONTHDAY".GETPOST('BYMONTHDAY', 'alpha') : "";
|
||||
$object->recurrule .= GETPOSTISSET('BYDAY') ? "_BYDAY".GETPOST('BYDAY', 'alpha') : "";
|
||||
|
||||
@@ -1532,6 +1546,9 @@ if ($action == 'create') {
|
||||
if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i', $object->recurrule, $reg)) {
|
||||
$selectedrecurrulefreq = $reg[1];
|
||||
}
|
||||
if ($object->recurrule && preg_match('/FREQ=YEARLY.*BYYEARMONTHDAY(\d+)/i', $object->recurrule, $reg)) {
|
||||
$selectedrecurrulebyyearmonthday = (int) $reg[1];
|
||||
}
|
||||
if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY(\d+)/i', $object->recurrule, $reg)) {
|
||||
$selectedrecurrulebymonthday = (int) $reg[1];
|
||||
}
|
||||
@@ -1571,16 +1588,25 @@ if ($action == 'create') {
|
||||
console.log("reg1: " + "<?php echo $selectedrecurrulefreq; ?>");
|
||||
console.log("reg2: " + "<?php echo $selectedrecurrulebymonthday; ?>");
|
||||
console.log("reg3: " + "<?php echo $selectedrecurrulebyday; ?>");
|
||||
console.log("reg4: " + "<?php echo $selectedrecurrulebyyearmonthday; ?>");
|
||||
console.log("selectedrulefreq: " + "<?php echo $selectedrecurrulefreq; ?>");
|
||||
if (jQuery("#recurrulefreq").val() == 'MONTHLY') {
|
||||
if (jQuery("#recurrulefreq").val() == 'YEARLY') {
|
||||
/* jQuery(".repeateventBYYEARMONTHDAY").css("display", "inline-block"); */ /* use this instead of show because we want inline-block and not block */
|
||||
jQuery(".repeateventlimitdate").css("display", "inline-block");
|
||||
jQuery(".repeateventBYMONTHDAY").hide();
|
||||
jQuery(".repeateventBYDAY").hide();
|
||||
} else if (jQuery("#recurrulefreq").val() == 'MONTHLY') {
|
||||
/* jQuery(".repeateventBYMONTHDAY").css("display", "inline-block"); */ /* use this instead of show because we want inline-block and not block */
|
||||
jQuery(".repeateventlimitdate").css("display", "inline-block");
|
||||
jQuery(".repeateventBYYEARMONTHDAY").hide();
|
||||
jQuery(".repeateventBYDAY").hide();
|
||||
} else if (jQuery("#recurrulefreq").val() == 'WEEKLY') {
|
||||
jQuery(".repeateventBYYEARMONTHDAY").hide();
|
||||
jQuery(".repeateventBYMONTHDAY").hide();
|
||||
/* jQuery(".repeateventBYDAY").css("display", "inline-block"); */ /* use this instead of show because we want inline-block and not block */
|
||||
jQuery(".repeateventlimitdate").css("display", "inline-block");
|
||||
} else {
|
||||
jQuery(".repeateventBYYEARMONTHDAY").hide();
|
||||
jQuery(".repeateventBYMONTHDAY").hide();
|
||||
jQuery(".repeateventBYDAY").hide();
|
||||
jQuery(".repeateventlimitdate").hide();
|
||||
@@ -1616,7 +1642,7 @@ if ($action == 'create') {
|
||||
print '<table class="border centpercent nobottom">';
|
||||
|
||||
// Assigned to user
|
||||
print '<tr><td class="tdtop nowrap titlefieldcreate"><span>'.$langs->trans("ActionAffectedTo").'</span></td><td>';
|
||||
print '<tr><td class="nowrap titlefieldcreate"><span>'.$langs->trans("ActionAffectedTo").'</span></td><td>';
|
||||
$listofuserid = [];
|
||||
$listofcontactid = [];
|
||||
$listofotherid = [];
|
||||
@@ -2248,7 +2274,7 @@ if ($id > 0 && $action != 'create') {
|
||||
$listofcontactid = $object->socpeopleassigned; // Contact assigned
|
||||
$listofotherid = $object->otherassigned; // Other undefined email (not used yet)
|
||||
|
||||
print '<tr><td class="tdtop nowrap fieldrequired">'.$langs->trans("ActionAssignedTo").'</td><td>';
|
||||
print '<tr><td class="nowrap fieldrequired">'.$langs->trans("ActionAssignedTo").'</td><td>';
|
||||
print '<div class="assignedtouser">';
|
||||
print $form->select_dolusers_forevent(($action == 'create' ? 'add' : 'update'), 'assignedtouser', 1, [], 0, '', [], '0', 0, 0, 'u.statut:<>:0', 1, $listofuserid, $listofcontactid, $listofotherid, (int) $caneditdateorowner);
|
||||
print '</div>';
|
||||
@@ -2723,6 +2749,9 @@ if ($id > 0 && $action != 'create') {
|
||||
if (preg_match('/FREQ=MONTHLY_BYMONTHDAY(\d+)/', $object->recurrule, $reg)) {
|
||||
print $langs->trans("EveryMonth").' <span class="opacitymedium small">('.$langs->trans("DayOfMonth").' '.$reg[1].' - '.$langs->trans("Until").' '.dol_print_date($object->recurdateend, 'day').')</span>';
|
||||
}
|
||||
if (preg_match('/FREQ=YEARLY_BYYEARMONTHDAY(\d+)/', $object->recurrule, $reg)) {
|
||||
print $langs->trans("EveryYear").' <span class="opacitymedium small">('.$langs->trans("DayOfYear").' '.$reg[1].' - '.$langs->trans("Until").' '.dol_print_date($object->recurdateend, 'day').')</span>';
|
||||
}
|
||||
print '</td></tr>';
|
||||
}
|
||||
|
||||
|
||||
@@ -5588,7 +5588,8 @@ class Facture extends CommonInvoice
|
||||
$this->fk_incoterms = 0;
|
||||
$this->location_incoterms = '';
|
||||
|
||||
$this->pos_print_counter = 3; // Already printed 3 times
|
||||
$this->pos_print_counter = 0; // Already printed 0 times
|
||||
$this->email_sent_counter = 0; // Already sent by email 0 times
|
||||
|
||||
$this->status = 0;
|
||||
|
||||
|
||||
@@ -7124,14 +7124,14 @@ function print_fiche_titre($title, $mesg = '', $picto = 'generic', $pictoisfullp
|
||||
/**
|
||||
* Load a title with picto
|
||||
*
|
||||
* @param string $title Title to show (HTML sanitized content). Can be a string with a <br> as a substring.
|
||||
* @param string $morehtmlright Added message to show on right
|
||||
* @param string $picto Icon to use before title (should be a 32x32 transparent png file)
|
||||
* @param string $title Title to show (HTML sanitized content). Can be a string with a <br> as a second string shown under the fmain title.
|
||||
* @param string $morehtmlright Added message to show on right
|
||||
* @param string $picto Icon to use before title (should be a 32x32 transparent png file)
|
||||
* @param int<0,1> $pictoisfullpath 1=Icon name is a full absolute url of image
|
||||
* @param string $id To force an id on html objects
|
||||
* @param string $morecssontable More css on table
|
||||
* @param string $morehtmlcenter Added message to show on center
|
||||
* @param string $morecssonpicto More css on picto
|
||||
* @param string $id To force an id on html objects
|
||||
* @param string $morecssontable More css on table
|
||||
* @param string $morehtmlcenter Added message to show on center
|
||||
* @param string $morecssonpicto More css on picto
|
||||
* @return string
|
||||
* @see print_barre_liste()
|
||||
*/
|
||||
|
||||
@@ -782,9 +782,10 @@ class DolibarrModules // Can not be abstract, because we need to instantiate it
|
||||
/**
|
||||
* Gives the translated module description if translation exists in admin.lang or the default module description
|
||||
*
|
||||
* @return string Translated module description
|
||||
* @param int<0,1> $foruseinpopupdesc If 1, we return a short description for use into popup window
|
||||
* @return string Translated module description
|
||||
*/
|
||||
public function getDesc()
|
||||
public function getDesc($foruseinpopupdesc = 0)
|
||||
{
|
||||
global $langs;
|
||||
$langs->load("admin");
|
||||
|
||||
@@ -23,6 +23,8 @@
|
||||
* \brief Description and activation file for the module BlockedLog
|
||||
*/
|
||||
include_once DOL_DOCUMENT_ROOT.'/core/modules/DolibarrModules.class.php';
|
||||
include_once DOL_DOCUMENT_ROOT.'/blockedlog/lib/blockedlog.lib.php';
|
||||
|
||||
|
||||
/**
|
||||
* Class to describe a BlockedLog module
|
||||
@@ -51,6 +53,7 @@ class modBlockedLog extends DolibarrModules
|
||||
// Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module)
|
||||
$this->name = preg_replace('/^mod/i', '', get_class($this));
|
||||
$this->description = "Enable a log on some business events into an unalterable log. This module may be mandatory for some countries.";
|
||||
|
||||
// Possible values for version are: 'development', 'experimental', 'dolibarr' or version
|
||||
$this->version = 'dolibarr';
|
||||
// Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase)
|
||||
@@ -173,6 +176,15 @@ class modBlockedLog extends DolibarrModules
|
||||
include_once DOL_DOCUMENT_ROOT.'/core/lib/security.lib.php';
|
||||
include_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php';
|
||||
|
||||
// Check that the HTTPS is forced
|
||||
global $dolibarr_main_force_https;
|
||||
|
||||
if (isALNEQualifiedVersion(0, 1) && empty($dolibarr_main_force_https)) {
|
||||
$this->error = 'Error: The HTTPS must be forced by setting the $dolibarr_main_force_https into Dolibarr conf/conf.php file to allow the use of this module in France.';
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Create HMAC if it does not exists yet
|
||||
$hmac_encoded_secret_key = getDolGlobalString('BLOCKEDLOG_HMAC_KEY');
|
||||
if (empty($hmac_encoded_secret_key)) {
|
||||
@@ -291,4 +303,30 @@ class modBlockedLog extends DolibarrModules
|
||||
|
||||
return $this->_remove($sql, $options);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Overwrite the common getDesc() method
|
||||
*
|
||||
* @param int<0,1> $foruseinpopupdesc If 1, we return a short description for use into popup window
|
||||
* @return string Translated module description
|
||||
*/
|
||||
public function getDesc($foruseinpopupdesc = 0)
|
||||
{
|
||||
global $langs;
|
||||
$langs->load("admin");
|
||||
|
||||
// If module description translation exists
|
||||
$s = $langs->transnoentitiesnoconv("Module".$this->numero."Desc");
|
||||
|
||||
if ($foruseinpopupdesc) {
|
||||
$langs->load("blockedlog");
|
||||
$s .= '<br><br>';
|
||||
if (isALNEQualifiedVersion(1, 1)) {
|
||||
$s .= info_admin($langs->trans("UnalterableLogTool1FR"), 0, 0, 'warning');
|
||||
}
|
||||
}
|
||||
|
||||
return $s;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -171,8 +171,10 @@ OnceOnly=Once only
|
||||
EveryDay=Every day
|
||||
EveryWeek=Every week
|
||||
EveryMonth=Every month
|
||||
EveryYear=Every year
|
||||
DayOfMonth=Day of month
|
||||
DayOfWeek=Day of week
|
||||
DayOfYear=Day of year
|
||||
DateStartPlusOne=Date start + 1 hour
|
||||
SetAllEventsToTodo=Set all events to todo
|
||||
SetAllEventsToInProgress=Set all events to in progress
|
||||
|
||||
@@ -4,7 +4,7 @@ Fingerprints=Archived events and fingerprints
|
||||
FingerprintsDesc=This is the tool to browse or extract the unalterable logs. Unalterable logs are generated and store into a dedicated table of the systel, in real time when a business event appears.
|
||||
ArchivesDesc=You can use this tool to export Unalterable Logs into archive files. They are kept into the system but you should download and copy them into external supports.
|
||||
UnalterableLogTool1=The law of some countries (like in France when doing B2C), ask that you do it on a regular basis.
|
||||
UnalterableLogTool1FR=In france, you MUST do it at least, once every year, we recommand to do it once per month.
|
||||
UnalterableLogTool1FR=In France, you MUST generate archives, at least, once every year, we recommand to do it once per month. Also, you MUST keep these archives for at least 7 years. According to the law, It is the user's responsibility to store their archives on media that guarantee their preservation, including in the event of hardware failure, so we recommand to store them on at least 2 different physical supports.
|
||||
UnalterableLogTool2=This unalterable Logs contains the history of unalterable data. It is the responsibility of the application user to ensure system backups, in order to comply with legal obligations. If you decide to secure your unalterable logs by exporting and storing archives files instead of a full database backup (tab <b>%s</b>), it is recommended to store the exported archive files in different places (Secured cloud, External USB drive, ...).
|
||||
UnalterableLogTool3=Note that, there is no feature to purge this log and every change tried to be done directly into this log (by a hacker for example) will be reported with a non-valid fingerprint.
|
||||
FingerprintsDesc2=If you really need to purge this table because you used your application for a demo/test purpose and want to clean your data to start your production, you can ask your reseller or integrator to reset your database (all your data will be removed).
|
||||
@@ -50,6 +50,7 @@ TypeOfEvent=Type of event
|
||||
TotalForAction=Total for event %s
|
||||
SecretKey=Secret key
|
||||
ErrorPeriodMustBePastToAllowExport=Export into archives is allowed only if period is completely past
|
||||
RegistrationNumber=Registration number
|
||||
|
||||
## logTypes
|
||||
logBILL_DELETE=Customer invoice logically deleted
|
||||
|
||||
@@ -3731,18 +3731,18 @@ if (!function_exists("llxFooter")) {
|
||||
$forceping = GETPOSTINT('forceping');
|
||||
|
||||
if (($_SERVER["PHP_SELF"] == DOL_URL_ROOT.'/index.php') || $forceping) {
|
||||
$hash_unique_id = dol_hash('dolibarr'.$conf->file->instance_unique_id, 'sha256'); // Note: if the global salt changes, this hash changes too so ping may be counted twice. We don't mind. It is for statistics purpose only.
|
||||
$hash_unique_id_ping = dol_hash('dolibarr'.$conf->file->instance_unique_id, 'sha256', 1);
|
||||
$constanttosavelastko = 'MAIN_LAST_PING_KO_DATE';
|
||||
$constanttosavefirstok = 'MAIN_FIRST_PING_OK_DATE';
|
||||
$constanttosavefirstokid = 'MAIN_FIRST_PING_OK_ID';
|
||||
|
||||
if (!getDolGlobalString($constanttosavefirstok)
|
||||
|| (!empty($conf->file->instance_unique_id) && (($hash_unique_id.' - '.DOL_VERSION) != getDolGlobalString($constanttosavefirstokid)) && (getDolGlobalString($constanttosavefirstokid) != 'disabled'))
|
||||
|| (!empty($conf->file->instance_unique_id) && (($hash_unique_id_ping.' - '.DOL_VERSION) != getDolGlobalString($constanttosavefirstokid)) && (getDolGlobalString($constanttosavefirstokid) != 'disabled'))
|
||||
|| $forceping) {
|
||||
// No ping done if we are into an alpha version
|
||||
if (strpos('alpha', DOL_VERSION) > 0 && !$forceping) {
|
||||
print "\n<!-- NO JS CODE TO ENABLE the anonymous Ping. It is an alpha version -->\n";
|
||||
} elseif (empty($_COOKIE['DOLINSTALLNOPING_'.$hash_unique_id]) || $forceping) { // Cookie is set when we uncheck the checkbox in the installation wizard.
|
||||
} elseif (empty($_COOKIE['DOLINSTALLNOPING_'.$hash_unique_id_ping]) || $forceping) { // Cookie is set when we uncheck the checkbox in the installation wizard.
|
||||
// Output code for ping
|
||||
include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
||||
|
||||
@@ -3760,28 +3760,29 @@ if (!function_exists("llxFooter")) {
|
||||
}
|
||||
}
|
||||
|
||||
// Add code to force the registration if not yet done but ready (in case past submission failed)
|
||||
// You can use &forceregistration=1 in parameters to force the call if the call was already sent.
|
||||
// Add code to force the registration of the use of the BlockedLog module if not yet done but ready (in case past submission failed)
|
||||
// You can use &forceregistration=1 in parameters to force also the recall if the call was already sent.
|
||||
$forceregistration = GETPOSTINT('forceregistration');
|
||||
|
||||
if (isModEnabled('blockedlog') && (($_SERVER["PHP_SELF"] == DOL_URL_ROOT.'/index.php') || $forceregistration)) {
|
||||
include_once DOL_DOCUMENT_ROOT.'/blockedlog/lib/blockedlog.lib.php';
|
||||
if (!isALNEQualifiedVersion()) {
|
||||
print "\n<!-- NO JS CODE TO ENABLE the registration. Not a LNE qualified version -->\n";
|
||||
} elseif (!isRegistrationRecorded()) {
|
||||
} elseif (!isRegistrationDataSaved()) {
|
||||
print "\n<!-- NO JS CODE TO ENABLE the registration. Registration data not saved -->\n";
|
||||
} else {
|
||||
$hash_unique_id = dol_hash('dolibarr'.$conf->file->instance_unique_id, 'sha256'); // Note: if the global salt changes, this hash changes too so ping may be counted twice. We don't mind. It is for statistics purpose only.
|
||||
$hash_unique_id_registration = dol_hash('dolibarr'.$conf->file->instance_unique_id, 'sha256', 1); // Same than getHashUniqueIdOfRegistration()
|
||||
$constanttosavelastko = 'MAIN_LAST_REGISTRATION_KO_DATE';
|
||||
$constanttosavefirstok = 'MAIN_FIRST_REGISTRATION_OK_DATE';
|
||||
$constanttosavefirstokid = 'MAIN_FIRST_REGISTRATION_OK_ID';
|
||||
|
||||
if (!getDolGlobalString($constanttosavefirstok)
|
||||
|| (!empty($conf->file->instance_unique_id) && ($hash_unique_id.' - '.DOL_VERSION != getDolGlobalString($constanttosavefirstokid)) && (getDolGlobalString($constanttosavefirstokid) != 'disabled'))
|
||||
|| (!empty($conf->file->instance_unique_id) && ($hash_unique_id_registration.' - '.DOL_VERSION != getDolGlobalString($constanttosavefirstokid)) && (getDolGlobalString($constanttosavefirstokid) != 'disabled'))
|
||||
|| $forceregistration) {
|
||||
// No ping done if we are into an alpha version
|
||||
if (strpos('alpha', DOL_VERSION) > 0 && !$forceregistration) {
|
||||
print "\n<!-- NO JS CODE TO ENABLE the registration. It is an alpha version -->\n";
|
||||
} elseif (empty($_COOKIE['DOLINSTALLNOPING_'.$hash_unique_id]) || $forceregistration) { // Cookie is set when we uncheck the checkbox in the installation wizard.
|
||||
// No registration done if we are into an alpha or beta version
|
||||
if ((strpos('alpha', DOL_VERSION) > 0 || strpos('beta', DOL_VERSION) > 0) && !$forceregistration) {
|
||||
print "\n<!-- NO JS CODE TO ENABLE the registration. It is an alpha or beta version -->\n";
|
||||
} elseif (empty($_COOKIE['DOLINSTALLNOPING_'.$hash_unique_id_registration]) || $forceregistration) { // Cookie is set when we uncheck the checkbox in the installation wizard.
|
||||
// Output code for ping
|
||||
include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php';
|
||||
|
||||
|
||||
@@ -42,6 +42,6 @@ define('DOL_MAJOR_VERSION', '23');
|
||||
define('DOL_VERSION', constant('DOL_MAJOR_VERSION').'.'.constant('DOL_MINOR_VERSION'));
|
||||
// DOL_VERSION is now a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c
|
||||
|
||||
if (!defined('CERTIF_LNE')) {
|
||||
define('CERTIF_LNE', '1'); // Set to 1 if the beta version is a candidate for certification or if the stable version has been certified. Use 2 for debug to force LNE features.
|
||||
}
|
||||
// Set to 1 if the beta version is a just a candidate for certification (not yet certified) or if the stable version has been certified.
|
||||
// Use 2 to force LNE featuresfro debug purposes
|
||||
define('CERTIF_LNE', '1');
|
||||
|
||||
@@ -91,6 +91,13 @@ class NumberingModulesTest extends CommonClassTest
|
||||
print __METHOD__." is_erasable=".$result."\n";
|
||||
$this->assertGreaterThanOrEqual(1, $result, 'Test for is_erasable, 1st 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
|
||||
|
||||
|
||||
$localobject2 = new Facture($db);
|
||||
$localobject2->initAsSpecimen();
|
||||
$localobject2->fetch_thirdparty();
|
||||
|
||||
Reference in New Issue
Block a user