Debug blockedlog:

- Add a track into log when we disable/enable module
- Add a protection to avoid disable of module when recording was started
- Better compatibility with multicompany
- Can filter on ref and amount
- Add a permission to read the blockedlog
- Add more information on payments/invoice/thirdparty into log
- Reset of module data after a migration from v6 (not compatible)
This commit is contained in:
Laurent Destailleur 2017-12-15 15:15:14 +01:00
parent fb0169cbb8
commit 5af153550d
22 changed files with 519 additions and 162 deletions

View File

@ -79,9 +79,9 @@ $familyinfo=array(
$param='';
if ($search_keyword) $param.='&search_keyword='.urlencode($search_keyword);
if ($search_status) $param.='&search_status='.urlencode($search_status);
if ($search_nature) $param.='&search_nature='.urlencode($search_nature);
if ($search_version) $param.='&search_version='.urlencode($search_version);
if ($search_status > -1) $param.='&search_status='.urlencode($search_status);
if ($search_nature > -1) $param.='&search_nature='.urlencode($search_nature);
if ($search_version > -1) $param.='&search_version='.urlencode($search_version);
$dirins=DOL_DOCUMENT_ROOT.'/custom';
$urldolibarrmodules='https://www.dolistore.com/';
@ -691,7 +691,8 @@ if ($mode == 'common')
}
else if (! empty($objMod->always_enabled) || ((! empty($conf->multicompany->enabled) && $objMod->core_enabled) && ($user->entity || $conf->entity!=1)))
{
print $langs->trans("Required");
if ($objMod->alreadyUsed()) print $langs->trans("Used");
else print $langs->trans("Required");
if (! empty($conf->multicompany->enabled) && $user->entity) $disableSetup++;
}
else

View File

@ -30,7 +30,7 @@ $langs->load("admin");
$langs->load("other");
$langs->load("blockedlog");
if (! $user->admin) accessforbidden();
if (! $user->admin || empty($conf->blockedlog->enabled)) accessforbidden();
$action = GETPOST('action','alpha');
$backtopage = GETPOST('backtopage', 'alpha');
@ -76,9 +76,8 @@ if (preg_match('/del_(.*)/',$action,$reg))
* View
*/
$block_static = new BlockedLog($db);
$form=new Form($db);
$block_static = new BlockedLog($db);
llxHeader('',$langs->trans("BlockedLogSetup"));
@ -107,8 +106,7 @@ print '</td></tr>';
if (!empty($conf->global->BLOCKEDLOG_USE_REMOTE_AUTHORITY)) {
// Example with a yes / no select
$var=!$var;
print '<tr '.$bc[$var].'>';
print '<tr class="oddeven">';
print '<td>'.$langs->trans("BlockedLogAuthorityUrl").img_info($langs->trans('BlockedLogAuthorityNeededToStoreYouFingerprintsInNonAlterableRemote')).'</td>';
print '<td align="right" width="300">';
print '<form method="POST" action="'.$_SERVER['PHP_SELF'].'">';

View File

@ -59,12 +59,12 @@ $pagenext = $page + 1;
if (empty($sortfield)) $sortfield='rowid';
if (empty($sortorder)) $sortorder='DESC';
$block_static = new BlockedLog($db);
$result = restrictedArea($user, 'blockedlog', 0, '');
/*
* Actions
*/
@ -335,8 +335,10 @@ jQuery(document).ready(function () {
for(x in data) {
value = data[x];
$("#pop-info table tbody").append("<tr><td>"+prefix+x+"</td><td class=\"wordwrap\">"+value+"</td></tr>");
if( (typeof value === "object") && (value !== null) ) {
if (typeof value != "object") {
$("#pop-info table tbody").append("<tr><td>"+prefix+x+"</td><td class=\"wordwrap\">"+value+"</td></tr>");
}
if ((typeof value === "object") && (value !== null)) {
drawData(value, prefix+x+" &gt;&gt; ");
}
}

View File

@ -19,7 +19,7 @@
/**
* \file htdocs/blockedlog/ajax/block-add.php
* \ingroup blockedlog
* \brief Block-add
* \brief block-add
*/

View File

@ -39,7 +39,7 @@ require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php';
$id = GETPOST('id');
$block = new BlockedLog($db);
if($block->fetch($id)>0) {
if ($block->fetch($id)>0) {
echo json_encode($block->object_data);
}
else {

View File

@ -29,6 +29,11 @@ class BlockedLog
* @var int
*/
public $id;
/**
* Entity
* @var int
*/
public $entity;
public $error = '';
public $errors = array();
@ -147,6 +152,21 @@ class BlockedLog
$this->error++;
}
}
else if ($this->action == 'MODULE_SET')
{
return '<i class="opacitymedium">System to track events into unalterable logs were enabled</i>';
}
else if ($this->action == 'MODULE_RESET')
{
if ($this->signature == '0000000000')
{
return '<i class="opacitymedium">System to track events into unalterable logs were disabled after some recording were done. We saved a special Fingerprint to track the chain as broken.</i>';
}
else
{
return '<i class="opacitymedium">System to track events into unalterable logs were disabled. This is possible because no record were done yet.</i>';
}
}
return '<i class="opacitymedium">'.$langs->trans('ImpossibleToReloadObject', $this->element, $this->fk_object).'</i>';
@ -178,9 +198,10 @@ class BlockedLog
/**
* Populate properties of log from object data
*
* @param Object $object object to store
* @param string $action action
* @param string $amounts amounts
* @param Object $object object to store
* @param string $action action
* @param string $amounts amounts
* @return int >0 if OK, <0 if KO
*/
public function setObjectData(&$object, $action, $amounts)
{
@ -214,9 +235,7 @@ class BlockedLog
$this->object_data=new stdClass();
// Add thirdparty info
if (empty($object->thirdparty) && method_exists($object, 'fetch_thirdparty')) $object->fetch_thirdparty();
if (! empty($object->thirdparty))
{
$this->object_data->thirdparty = new stdClass();
@ -249,7 +268,6 @@ class BlockedLog
}
// Add user info
$this->fk_user = $user->id;
$this->user_fullname = $user->getFullName($langs);
@ -257,42 +275,97 @@ class BlockedLog
if ($this->element == 'facture')
{
$this->object_data->total_ht = (double) $object->total_ht;
$this->object_data->total_tva = (double) $object->total_tva;
$this->object_data->total_ttc = (double) $object->total_ttc;
$this->object_data->total_localtax1 = (double) $object->total_localtax1;
$this->object_data->total_localtax2 = (double) $object->total_localtax2;
$this->object_data->revenue_stamp = (double) $object->revenue_stamp;
$this->object_data->date_pointoftax = (double) $object->date_pointoftax;
$this->object_data->note_public = (double) $object->note_public;
}
if($this->element == 'invoice_supplier') {
if(empty($object->thirdparty))$object->fetch_thirdparty();
$this->object_data->thirdparty = new stdClass();
foreach($object->thirdparty as $key=>$value) {
if(!is_object($value)) $this->object_data->thirdparty->{$key} = $value;
foreach($object as $key=>$value)
{
if (in_array($key, array('fields'))) continue; // Discard some properties
if (! in_array($key, array(
'ref','facnumber','ref_client','ref_supplier','datef','type','total_ht','total_tva','total_ttc','localtax1','localtax2','revenuestamp','datepointoftax','note_public'
))) continue; // Discard if not into a dedicated list
if (!is_object($value)) $this->object_data->{$key} = $value;
}
}
elseif ($this->element == 'invoice_supplier')
{
foreach($object as $key=>$value)
{
if (in_array($key, array('fields'))) continue; // Discard some properties
if (! in_array($key, array(
'ref','facnumber','ref_client','ref_supplier','datef','type','total_ht','total_tva','total_ttc','localtax1','localtax2','revenuestamp','datepointoftax','note_public'
))) continue; // Discard if not into a dedicated list
if (!is_object($value)) $this->object_data->{$key} = $value;
}
$this->object_data->total_ht = (double) $object->total_ht;
$this->object_data->total_tva = (double) $object->total_tva;
$this->object_data->total_ttc = (double) $object->total_ttc;
$this->object_data->total_localtax1 = (double) $object->total_localtax1;
$this->object_data->total_localtax2 = (double) $object->total_localtax2;
$this->object_data->revenue_stamp = (double) $object->revenue_stamp;
$this->object_data->date_pointoftax = (double) $object->date_pointoftax;
$this->object_data->note_public = (double) $object->note_public;
}
elseif ($this->element == 'payment'|| $object->element == 'payment_supplier')
{
$this->object_data->amounts = $object->amounts;
//var_dump($object);
$this->object_data->ref = $object->ref;
$this->object_data->date = $object->datepaye;
$this->object_data->type_code = dol_getIdFromCode($this->db, $object->paiementid, 'c_paiement', 'id', 'code');
$this->object_data->payment_num = $object->num_paiement;
//$this->object_data->fk_account = $object->fk_account;
$this->object_data->note = $object->note;
//var_dump($this->object_data);exit;
$paymentpartnumber=0;
foreach($object->amounts as $invoiceid => $amount)
{
if ($this->element == 'payment_supplier')
{
$tmpinvoice = new FactureFournisseur($this->db);
}
else
{
$tmpinvoice = new Facture($this->db);
}
$result = $tmpinvoice->fetch($invoiceid);
if ($result <= 0)
{
$this->error = $tmpinvoice->error;
$this->errors = $tmpinvoice->errors;
return -1;
}
$result = $tmpinvoice->fetch_thirdparty();
if ($result <= 0)
{
$this->error = $tmpinvoice->error;
$this->errors = $tmpinvoice->errors;
return -1;
}
$paymentpart = new stdClass();
$paymentpart->amount = $amount;
$paymentpart->thirdparty = new stdClass();
foreach($tmpinvoice->thirdparty as $key=>$value)
{
if (in_array($key, array('fields'))) continue; // Discard some properties
if (! in_array($key, array(
'name','name_alias','ref_ext','address','zip','town','state_code','country_code','idprof1','idprof2','idprof3','idprof4','idprof5','idprof6','phone','fax','email','barcode',
'tva_intra', 'localtax1_assuj', 'localtax1_value', 'localtax2_assuj', 'localtax2_value', 'managers', 'capital', 'typent_code', 'forme_juridique_code', 'code_client', 'code_fournisseur'
))) continue; // Discard if not into a dedicated list
if (!is_object($value)) $paymentpart->thirdparty->{$key} = $value;
}
$paymentpart->invoice = new stdClass();
foreach($tmpinvoice as $key=>$value)
{
if (in_array($key, array('fields'))) continue; // Discard some properties
if (! in_array($key, array(
'ref','facnumber','ref_client','ref_supplier','datef','type','total_ht','total_tva','total_ttc','localtax1','localtax2','revenuestamp','datepointoftax','note_public'
))) continue; // Discard if not into a dedicated list
if (!is_object($value)) $paymentpart->invoice->{$key} = $value;
}
$paymentpartnumber++;
$this->object_data->payment_part[$paymentpartnumber] = $paymentpart;
}
}
elseif($this->element == 'payment_salary')
{
$this->object_data->amounts = array($object->amount);
}
return 1;
}
/**
@ -315,7 +388,8 @@ class BlockedLog
$langs->load("blockedlog");
$sql = "SELECT b.rowid, b.date_creation, b.signature, b.signature_line, b.amounts, b.action, b.element, b.fk_object, b.certified, b.tms, b.fk_user, b.user_fullname, b.date_object, b.ref_object, b.object_data";
$sql = "SELECT b.rowid, b.date_creation, b.signature, b.signature_line, b.amounts, b.action, b.element, b.fk_object, b.entity,";
$sql.= " b.certified, b.tms, b.fk_user, b.user_fullname, b.date_object, b.ref_object, b.object_data";
$sql.= " FROM ".MAIN_DB_PREFIX."blockedlog as b";
if ($id) $sql.= " WHERE b.rowid = ". $id;
@ -327,6 +401,7 @@ class BlockedLog
$obj = $this->db->fetch_object($resql);
$this->id = $obj->rowid;
$this->entity = $obj->entity;
$this->ref = $obj->rowid;
$this->date_creation = $this->db->jdate($obj->date_creation);
@ -383,10 +458,11 @@ class BlockedLog
/**
* Create blocked log in database.
*
* @param User $user Object user that create
* @return int <0 if KO, >0 if OK
* @param User $user Object user that create
* @param int $forcesignature Force signature (for example '0000000000' when we disabled the module)
* @return int <0 if KO, >0 if OK
*/
public function create($user) {
public function create($user, $forcesignature='') {
global $conf,$langs,$hookmanager;
@ -400,14 +476,14 @@ class BlockedLog
dol_syslog(get_class($this).'::create action='.$this->action.' fk_user='.$this->fk_user.' user_fullname='.$this->user_fullname, LOG_DEBUG);
// Check parameters/properties
if (is_null($this->amounts))
if (! isset($this->amounts)) // amount can be 0 for some events (like when module is disabled)
{
$this->error=$langs->trans("BlockLogNeedAmountsValue");
dol_syslog($this->error, LOG_WARNING);
return -1;
}
if(empty($this->element)) {
if (empty($this->element)) {
$this->error=$langs->trans("BlockLogNeedElement");
dol_syslog($this->error, LOG_WARNING);
return -2;
@ -429,6 +505,7 @@ class BlockedLog
$this->signature_line = dol_hash($keyforsignature, '5'); // Not really usefull
$this->signature = dol_hash($previoushash . $keyforsignature, '5');
if ($forcesignature) $this->signature = $forcesignature;
//var_dump($keyforsignature);var_dump($previoushash);var_dump($this->signature_line);var_dump($this->signature);
$sql = "INSERT INTO ".MAIN_DB_PREFIX."blockedlog (";
@ -460,7 +537,7 @@ class BlockedLog
$sql.= "0,";
$sql.= $this->fk_user.",";
$sql.= "'".$this->db->escape($this->user_fullname)."',";
$sql.= $conf->entity;
$sql.= ($this->entity ? $this->entity : $conf->entity);
$sql.= ")";
$res = $this->db->query($sql);
@ -544,7 +621,8 @@ class BlockedLog
$previoussignature='';
$sql="SELECT rowid, signature FROM ".MAIN_DB_PREFIX."blockedlog WHERE entity=".$conf->entity;
$sql = "SELECT rowid, signature FROM ".MAIN_DB_PREFIX."blockedlog";
$sql.= " WHERE entity=".$conf->entity;
if ($beforeid) $sql.= " AND rowid < ".(int) $beforeid;
$sql.=" ORDER BY rowid DESC LIMIT 1";
$sql.=($withlock ? " FOR UPDATE ": "");
@ -611,7 +689,7 @@ class BlockedLog
}
else{
$sql="SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog
WHERE element='".$element."' AND fk_object=".(int) $fk_object;
WHERE entity=".$conf->entity." AND element='".$element."' AND fk_object=".(int) $fk_object;
}
if ($search_start > 0) $sql.=" AND date_creation >= '".$this->db->idate($search_start)."'";
@ -649,7 +727,7 @@ class BlockedLog
}
/**
* Return the signature (hash) of the "genesis-block" (Block 0)
* Return the signature (hash) of the "genesis-block" (Block 0).
*
* @return string Signature of genesis-block for current conf->entity
*/
@ -671,5 +749,35 @@ class BlockedLog
return $conf->global->BLOCKEDLOG_ENTITY_FINGERPRINT;
}
/**
* Check if module was already used or not for at least one recording.
*
* @param int $ignoresystem Ignore system events for the test
*/
function alreadyUsed($ignoresystem=0)
{
global $conf;
$result = false;
$sql = "SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog";
$sql.= " WHERE entity = ".$conf->entity;
if ($ignoresystem) $sql.=" AND action not in ('MODULE_SET','MODULE_RESET')";
$sql.= $this->db->plimit(1);
$res = $this->db->query($sql);
if ($res!==false)
{
$obj = $this->db->fetch_object($res);
if ($obj) $result = true;
}
else dol_print_error($this->db);
dol_syslog("Module Blockedlog alreadyUsed with ignoresystem=".$ignoresystem." is ".$result);
return $result;
}
}

View File

@ -28,7 +28,7 @@
*/
function blockedlogadmin_prepare_head()
{
global $langs, $conf;
global $db, $langs, $conf;
$h = 0;
$head = array();
@ -40,6 +40,13 @@ function blockedlogadmin_prepare_head()
$head[$h][0] = DOL_URL_ROOT."/blockedlog/admin/blockedlog_list.php";
$head[$h][1] = $langs->trans("Fingerprints");
require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php';
$b=new BlockedLog($db);
if ($b->alreadyUsed())
{
$head[$h][1].=' <span class="badge">...</span>';
}
$head[$h][2] = 'fingerprints';
$h++;

View File

@ -6127,15 +6127,15 @@ function dol_osencode($str)
* Store also Code-Id into a cache to speed up next request on same key.
*
* @param DoliDB $db Database handler
* @param string $key Code or Id to get Id or Code
* @param string $key Code or Id to get Id or Code
* @param string $tablename Table name without prefix
* @param string $fieldkey Field for code
* @param string $fieldid Field for id
* @param string $fieldkey Field to search the key into
* @param string $fieldid Field to get
* @param int $entityfilter Filter by entity
* @return int <0 if KO, Id of code if OK
* @see $langs->getLabelFromKey
*/
function dol_getIdFromCode($db,$key,$tablename,$fieldkey='code',$fieldid='id',$entityfilter=0)
function dol_getIdFromCode($db, $key, $tablename, $fieldkey='code', $fieldid='id', $entityfilter=0)
{
global $cache_codes;

View File

@ -224,7 +224,7 @@ function group_prepare_head($object)
if ($canreadperms)
{
$head[$h][0] = DOL_URL_ROOT.'/user/group/perms.php?id='.$object->id;
$head[$h][1] = $langs->trans("GroupRights");
$head[$h][1] = $langs->trans("GroupRights"). ' <span class="badge">'.($object->nb_rights).'</span>';
$head[$h][2] = 'rights';
$h++;
}
@ -267,7 +267,7 @@ function user_admin_prepare_head()
$head[$h][2] = 'attributes';
$h++;
$head[$h][0] = DOL_URL_ROOT.'/user/admin/group_extrafields.php';
$head[$h][0] = DOL_URL_ROOT.'/user/admin/group_extrafields.php';
$head[$h][1] = $langs->trans("ExtraFields")." ".$langs->trans("Groups");
$head[$h][2] = 'attributes_group';
$h++;

View File

@ -1666,7 +1666,7 @@ class DolibarrModules // Can not be abstract, because we need to insta
$r_def = $this->rights[$key][3];
$r_perms = $this->rights[$key][4];
$r_subperms = isset($this->rights[$key][5])?$this->rights[$key][5]:'';
$r_modul = $this->rights_class;
$r_modul = empty($this->rights_class)?strtolower($this->name):$this->rights_class;
if (empty($r_type)) $r_type='w';

View File

@ -36,10 +36,12 @@ class modBlockedLog extends DolibarrModules
*/
function __construct($db)
{
global $langs,$conf,$mysoc;
global $langs, $conf, $mysoc;
$this->db = $db;
$this->numero = 3200;
// Key text used to identify module (for permissions, menus, etc...)
$this->rights_class = 'blockedlog';
// Family can be 'crm','financial','hr','projects','products','ecm','technic','other'
// It is used to group modules in module setup page
@ -77,17 +79,27 @@ class modBlockedLog extends DolibarrModules
// Currently, activation is not automatic because only companies (in France) making invoices to non business customers must
// enable this module.
// It is automatic only if $conf->global->BLOCKEDLOG_DISABLE_NOT_ALLOWED_FOR_COUNTRY is on.
if (! empty($conf->global->BLOCKEDLOG_DISABLE_NOT_ALLOWED_FOR_COUNTRY))
/*if (! empty($conf->global->BLOCKEDLOG_DISABLE_NOT_ALLOWED_FOR_COUNTRY))
{
$this->automatic_activation = array('FR'=>'BlockedLogActivatedBecauseRequiredByYourCountryLegislation');
}
$tmp=explode(',', $conf->global->BLOCKEDLOG_DISABLE_NOT_ALLOWED_FOR_COUNTRY);
$this->automatic_activation = array();
foreach($tmp as $key)
{
$this->automatic_activation[$key]='BlockedLogActivatedBecauseRequiredByYourCountryLegislation';
}
}*/
//var_dump($this->automatic_activation);
$this->always_enabled = !empty($conf->blockedlog->enabled) && !empty($conf->global->BLOCKEDLOG_DISABLE_NOT_ALLOWED_FOR_COUNTRY) && in_array($mysoc->country_code, explode(',', $conf->global->BLOCKEDLOG_DISABLE_NOT_ALLOWED_FOR_COUNTRY));
$this->always_enabled = (!empty($conf->blockedlog->enabled)
&& !empty($conf->global->BLOCKEDLOG_DISABLE_NOT_ALLOWED_FOR_COUNTRY)
&& in_array($mysoc->country_code, explode(',', $conf->global->BLOCKEDLOG_DISABLE_NOT_ALLOWED_FOR_COUNTRY))
&& $this->alreadyUsed(1));
// Constants
//-----------
$this->const = array();
$this->const = array(
1=>array('BLOCKEDLOG_DISABLE_NOT_ALLOWED_FOR_COUNTRY', 'chaine', 'FR', 'This is list of country code where the module may be mandatory', 0, 'current', 0)
);
// New pages on tabs
// -----------------
@ -97,23 +109,76 @@ class modBlockedLog extends DolibarrModules
//------
$this->boxes = array();
// Permissions
$this->rights = array(); // Permission array used by this module
$r=0;
$this->rights[$r][0] = $this->numero + $r; // Permission id (must not be already used)
$this->rights[$r][1] = 'Read archived events and fingerprints'; // Permission label
$this->rights[$r][3] = 0; // Permission by default for new user (0/1)
$this->rights[$r][4] = 'read'; // In php code, permission will be checked by test if ($user->rights->mymodule->level1->level2)
$this->rights[$r][5] = '';
// Main menu entries
//------------------
$this->menu = array();
}
/**
* Check if module was already used before unactivation linked to warnings_unactivation property
*
* @return boolean True if already used, otherwise False
*/
function alreadyUsed() {
$res = $this->db->query("SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."blockedlog");
if($res!==false) {
$obj = $this->db->fetch_object($res);
return ($obj->nb > 0);
require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php';
$b=new BlockedLog($this->db);
return $b->alreadyUsed(1);
}
/**
* Function called when module is enabled.
* The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
* It also creates data directories.
*
* @param string $options Options when enabling module ('', 'noboxes')
* @return int 1 if OK, 0 if KO
*/
function init($options='')
{
global $conf, $user;
$sql = array();
// If already used, we add an entry to show we enable module
require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php';
$object=new stdClass;
$object->id = 1;
$object->element = 'module';
$object->ref = 'systemevent';
$object->entity = $conf->entity;
$object->date = dol_now();
$b=new BlockedLog($this->db);
$result = $b->setObjectData($object, 'MODULE_SET', 0);
if ($result < 0)
{
$this->error = $b->error;
$this->errors = $b->erros;
return 0;
}
return false;
$res = $b->create($user);
if ($res<=0) {
$this->error = $b->error;
$this->errors = $b->errors;
return $res;
}
return $this->_init($sql, $options);
}
/**
@ -126,26 +191,43 @@ class modBlockedLog extends DolibarrModules
*/
function remove($options = '') {
global $user;
global $conf, $user;
require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php';
$sql = array();
$object=new stdClass;
// If already used, we add an entry to show we enable module
require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php';
$object=new stdClass;
$object->id = 1;
$object->element = 'module';
$object->ref = 'module';
$object->ref = 'systemevent';
$object->entity = $conf->entity;
$object->date = dol_now();
$b=new BlockedLog($this->db);
$b->setObjectData($object, 'MODULE_RESET', -1);
$res = $b->create($user);
if($res<=0) {
$result = $b->setObjectData($object, 'MODULE_RESET', 0);
if ($result < 0)
{
$this->error = $b->error;
return $res;
$this->errors = $b->erros;
return 0;
}
return $this->_remove(array(), $options);
if ($b->alreadyUsed(1))
{
$res = $b->create($user, '0000000000'); // If already used for something else than SET or UNSET, we log with error
}
else
{
$res = $b->create($user);
}
if ($res<=0) {
$this->error = $b->error;
$this->errors = $b->errors;
return $res;
}
return $this->_remove($sql, $options);
}
}

View File

@ -56,15 +56,24 @@ class InterfaceActionsBlockedLog extends DolibarrTriggers
dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id);
// Event/record is qualified
if ($action==='BILL_VALIDATE' || $action === 'BILL_PAYED' || $action==='BILL_UNPAYED' || $action==='BILL_DELETE'
|| $action === 'BILL_SENTBYMAIL' || $action === 'DOC_DOWNLOAD' || $action === 'DOC_PREVIEW'
|| $action === 'BILL_SUPPLIER_PAYED')
$qualified = 0;
if ($action==='BILL_VALIDATE' || $action==='BILL_DELETE' || $action === 'BILL_SENTBYMAIL'
|| (in_array($object->element, array('facture','suplier_invoice')) && $action === 'DOC_DOWNLOAD') || (in_array($object->element, array('facture','suplier_invoice')) && $action === 'DOC_PREVIEW')
)
{
$qualified++;
$amounts= (double) $object->total_ttc;
}
else if ($action === 'PAYMENT_CUSTOMER_CREATE' || $action === 'PAYMENT_SUPPLIER_CREATE'
/*if ($action === 'BILL_PAYED' || $action==='BILL_UNPAYED'
|| $action === 'BILL_SUPPLIER_PAYED' || $action === 'BILL_SUPPLIER_UNPAYED')
{
$qualified++;
$amounts= (double) $object->total_ttc;
}*/
if ($action === 'PAYMENT_CUSTOMER_CREATE' || $action === 'PAYMENT_SUPPLIER_CREATE'
|| $action === 'PAYMENT_CUSTOMER_DELETE' || $action === 'PAYMENT_SUPPLIER_DELETE') // 'PAYMENT_ADD_TO_BANK'
{
$qualified++;
$amounts = 0;
if(!empty($object->amounts)) {
foreach($object->amounts as $amount) {
@ -72,22 +81,32 @@ class InterfaceActionsBlockedLog extends DolibarrTriggers
}
}
}
else if (strpos($action,'PAYMENT')!==false && ! in_array($action, array('PAYMENT_ADD_TO_BANK'))) {
if (strpos($action,'PAYMENT')!==false && ! in_array($action, array('PAYMENT_ADD_TO_BANK')))
{
$qualified++;
$amounts= (double) $object->amount;
}
else {
if (! $qualified)
{
return 0; // not implemented action log
}
$b=new BlockedLog($this->db);
$b->setObjectData($object, $action, $amounts); // Set field date_object, ref_object, fk_object, element, object_data
$result = $b->setObjectData($object, $action, $amounts); // Set field date_object, ref_object, fk_object, element, object_data
if ($result < 0)
{
$this->error = $b->error;
$this->errors = $b->erros;
return -1;
}
$res = $b->create($user);
if ($res<0)
{
setEventMessage($b->error,'errors');
setEventMessages($b->error, $b->errors, 'errors');
return -1;
}
else

View File

@ -380,7 +380,9 @@ if (! GETPOST('action','aZ09') || preg_match('/upgrade/i',GETPOST('action','aZ09
if (versioncompare($versiontoarray,$afterversionarray) >= 0 && versioncompare($versiontoarray,$beforeversionarray) <= 0)
{
// Migrate contact association
migrate_event_assignement_contact($db,$langs,$conf);
migrate_event_assignement_contact($db,$langs,$conf);
migrate_reset_blocked_log($db,$langs,$conf);
}
}
@ -3872,6 +3874,125 @@ function migrate_event_assignement_contact($db,$langs,$conf)
print '</td></tr>';
}
/**
* Migrate to reset the blocked log for V7+ algorithm
*
* @param DoliDB $db Database handler
* @param Translate $langs Object langs
* @param Conf $conf Object conf
* @return void
*/
function migrate_reset_blocked_log($db,$langs,$conf)
{
require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php';
print '<tr><td colspan="4">';
print '<br>';
print '<b>'.$langs->trans('MigrationResetBlockedLog')."</b><br>\n";
$error = 0;
dolibarr_install_syslog("upgrade2::migrate_reset_blocked_log");
$db->begin();
$sqlSelect = "SELECT DISTINCT entity";
$sqlSelect.= " FROM ".MAIN_DB_PREFIX."blockedlog";
//print $sqlSelect;
$resql = $db->query($sqlSelect);
if ($resql)
{
$i = 0;
$num = $db->num_rows($resql);
if ($num)
{
while ($i < $num)
{
$obj = $db->fetch_object($resql);
print 'Process entity '.$obj->entity;
$sqlSearch = "SELECT count(rowid) as nb FROM ".MAIN_DB_PREFIX."blockedlog WHERE action = 'MODULE_SET' and entity = ".$obj->entity;
$resqlSearch = $db->query($sqlSearch);
if ($resqlSearch)
{
$objSearch = $db->fetch_object($resqlSearch);
//var_dump($objSearch);
if ($objSearch && $objSearch->nb == 0)
{
print ' - Record for entity must be reset...';
$sqlUpdate = "DELETE FROM ".MAIN_DB_PREFIX."blockedlog";
$sqlUpdate.= " WHERE entity = " . $obj->entity;
$resqlUpdate=$db->query($sqlUpdate);
if (! $resqlUpdate)
{
$error++;
dol_print_error($db);
}
else
{
// Add set line
$object=new stdClass;
$object->id = 1;
$object->element = 'module';
$object->ref = 'systemevent';
$object->entity = $obj->entity;
$object->date = dol_now();
$b=new BlockedLog($this->db);
$b->setObjectData($object, 'MODULE_SET', 0);
$res = $b->create($user);
if ($res<=0) {
$this->error = $b->error;
$this->errors = $b->errors;
$error++;
}
}
}
else
{
print ' - '.$langs->trans('AlreadyInV7');
}
}
else
{
dol_print_error($db);
}
$i++;
}
}
else
{
print $langs->trans('NothingToDo')."<br>\n";
}
if (! $error)
{
$db->commit();
}
else
{
$db->rollback();
}
}
else
{
dol_print_error($db);
$db->rollback();
}
print '</td></tr>';
}
/**
* Migrate to add entity value into llx_societe_remise
*
@ -3946,7 +4067,6 @@ function migrate_remise_entity($db,$langs,$conf)
$db->rollback();
}
print '</td></tr>';
}

View File

@ -2,7 +2,7 @@ BlockedLog=Unalterable Logs
Field=Field
BlockedLogDesc=This module tracks some events into an unalterable log (that you can't modify once recorded) into a block chain, in real time. This module provides compatibility with requirements of laws of some countries (like France with the law Fincance 2016 - Norme NF535).
Fingerprints=Archived events and fingerprints
FingerprintsDesc=Archived business events and fingerprints
FingerprintsDesc=This is the tool to browser the unalterable logs
CompanyInitialKey=Company initial key (hash of genesis block)
ShowAllFingerPrintsMightBeTooLong=Show all archived logs (might be long)
ShowAllFingerPrintsErrorsMightBeTooLong=Show all archive logs with error (might be long)
@ -21,6 +21,8 @@ logBILL_UNPAYED=Customer bill set unpayed
logBILL_VALIDATE=Customer bill validated
logBILL_SENTBYMAIL=Customer bill send by mail
logBILL_DELETE=Customer bill deleted
logMODULE_RESET=Module BlockedLog was disabled
logMODULE_SET=Module BlockedLog was enabled
BlockedlogInfoDialog=Log Details
Fingerprint=Fingerprint
DownloadLogCSV=Download archive logs (CSV)
@ -30,4 +32,4 @@ DataOfArchivedEvent=Full datas of archived event
ImpossibleToReloadObject=Object (type %s, id %s) removed (see 'Full data' link for unerasable saved data)
BlockedLogAreRequiredByYourCountryLegislation=Unalterable Logs module may be required by the legislation of your country. Disabling this module may render any future transactions invalid with respect to the law and the use of legal software as they can not be validated by a tax audit.
BlockedLogActivatedBecauseRequiredByYourCountryLegislation=Unalterable Logs module was activated because of the legislation of your country. Disabling this module may render any future transactions invalid with respect to the law and the use of legal software as they can not be validated by a tax audit.
BlockedLogDisableNotAllowedForCountry=Disable not allowed for this countries (just to prevent to disable the module by error, if your country is...)
BlockedLogDisableNotAllowedForCountry=List of countries where usage of this module is mandatory (just to prevent to disable the module by error, if your country is in this list, disable of module is not possible without editing this list first)

View File

@ -141,6 +141,7 @@ KeepDefaultValuesProxmox=You use the Dolibarr setup wizard from a Proxmox virtua
UpgradeExternalModule=Run dedicated upgrade process of external modules
SetAtLeastOneOptionAsUrlParameter=Set at least one option as a parameter in URL. For example: '...repair.php?standard=confirmed'
NothingToDelete=Nothing to clean/delete
NothingToDo=Nothing to do
#########
# upgrade
MigrationFixData=Fix for denormalized data
@ -196,6 +197,7 @@ MigrationEventsContact=Migration of events to add event contact into assignement
MigrationRemiseEntity=Update entity field value of llx_societe_remise
MigrationRemiseExceptEntity=Update entity field value of llx_societe_remise_except
MigrationReloadModule=Reload module %s
MigrationResetBlockedLog=Reset module BlockedLog for v7 algorithm
ShowNotAvailableOptions=Show not available options
HideNotAvailableOptions=Hide not available options
ErrorFoundDuringMigration=Error were reported during migration process so next step is not available. To ignore errors, you can <a href="%s">click here</a>, but application or some features may not work correctly until fixed.

View File

@ -299,12 +299,12 @@ class modMyModule extends DolibarrModules
}
/**
* Function called when module is enabled.
* The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
* It also creates data directories
* Function called when module is enabled.
* The init function add constants, boxes, permissions and menus (defined in constructor) into Dolibarr database.
* It also creates data directories
*
* @param string $options Options when enabling module ('', 'noboxes')
* @return int 1 if OK, 0 if KO
* @param string $options Options when enabling module ('', 'noboxes')
* @return int 1 if OK, 0 if KO
*/
public function init($options='')
{
@ -326,12 +326,12 @@ class modMyModule extends DolibarrModules
}
/**
* Function called when module is disabled.
* Remove from database constants, boxes and permissions from Dolibarr database.
* Data directories are not deleted
* Function called when module is disabled.
* Remove from database constants, boxes and permissions from Dolibarr database.
* Data directories are not deleted
*
* @param string $options Options when enabling module ('', 'noboxes')
* @return int 1 if OK, 0 if KO
* @param string $options Options when enabling module ('', 'noboxes')
* @return int 1 if OK, 0 if KO
*/
public function remove($options = '')
{

View File

@ -102,6 +102,7 @@ if ($user->societe_id > 0)
//$socid = $user->societe_id;
accessforbidden();
}
//$result = restrictedArea($user, 'mymodule', $id,'');
// Initialize array of search criterias
$search_all=trim(GETPOST("search_all",'alpha'));

View File

@ -727,19 +727,21 @@ class User extends CommonObject
if ($perms)
{
if (! isset($this->rights) || ! is_object($this->rights)) $this->rights = new stdClass(); // For avoid error
if (! isset($this->rights->$module) || ! is_object($this->rights->$module)) $this->rights->$module = new stdClass();
if ($subperms)
if ($module)
{
if (! isset($this->rights->$module->$perms) || ! is_object($this->rights->$module->$perms)) $this->rights->$module->$perms = new stdClass();
if(empty($this->rights->$module->$perms->$subperms)) $this->nb_rights++;
$this->rights->$module->$perms->$subperms = 1;
if (! isset($this->rights->$module) || ! is_object($this->rights->$module)) $this->rights->$module = new stdClass();
if ($subperms)
{
if (! isset($this->rights->$module->$perms) || ! is_object($this->rights->$module->$perms)) $this->rights->$module->$perms = new stdClass();
if(empty($this->rights->$module->$perms->$subperms)) $this->nb_rights++;
$this->rights->$module->$perms->$subperms = 1;
}
else
{
if(empty($this->rights->$module->$perms)) $this->nb_rights++;
$this->rights->$module->$perms = 1;
}
}
else
{
if(empty($this->rights->$module->$perms)) $this->nb_rights++;
$this->rights->$module->$perms = 1;
}
}
$i++;
}

View File

@ -50,6 +50,8 @@ class UserGroup extends CommonObject
public $datem; // Modification date of group
public $members=array(); // Array of users
public $nb_rights; // Number of rights granted to the user
private $_tab_loaded=array(); // Array of cache of already loaded permissions
public $oldcopy; // To contains a clone of this when we need to save old properties of object
@ -63,6 +65,7 @@ class UserGroup extends CommonObject
function __construct($db)
{
$this->db = $db;
$this->nb_rights = 0;
return 0;
}
@ -536,10 +539,12 @@ class UserGroup extends CommonObject
if ($subperms)
{
if (! isset($this->rights->$module->$perms) || ! is_object($this->rights->$module->$perms)) $this->rights->$module->$perms = new stdClass();
if(empty($this->rights->$module->$perms->$subperms)) $this->nb_rights++;
$this->rights->$module->$perms->$subperms = 1;
}
else
{
if(empty($this->rights->$module->$perms)) $this->nb_rights++;
$this->rights->$module->$perms = 1;
}
}

View File

@ -60,6 +60,11 @@ if (! empty($conf->multicompany->enabled) && $conf->entity > 1 && $conf->global-
}
$object = new Usergroup($db);
if ($id > 0)
{
$object->fetch($id);
$object->getrights();
}
$extrafields = new ExtraFields($db);
// fetch optionals attributes and labels

View File

@ -56,7 +56,6 @@ if (! $canreadperms) accessforbidden();
$object = new Usergroup($db);
$object->fetch($id);
$object->getrights();
$entity=$conf->entity;
@ -73,19 +72,26 @@ $parameters=array();
$reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks
if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors');
if (empty($reshook)) {
if (empty($reshook))
{
if ($action == 'addrights' && $caneditperms)
{
$editgroup = new Usergroup($db);
$result=$editgroup->fetch($id);
if ($result > 0) $editgroup->addrights($rights, $module, '', $entity);
if ($result > 0)
{
$editgroup->addrights($rights, $module, '', $entity);
}
}
if ($action == 'delrights' && $caneditperms)
{
$editgroup = new Usergroup($db);
$result=$editgroup->fetch($id);
if ($result > 0) $editgroup->delrights($rights, $module, '', $entity);
if ($result > 0)
{
$editgroup->delrights($rights, $module, '', $entity);
}
}
}
@ -98,11 +104,13 @@ $form = new Form($db);
llxHeader('',$langs->trans("Permissions"));
if ($object->id)
if ($object->id > 0)
{
/*
/*
* Affichage onglets
*/
$object->getrights(); // Reload permission
$head = group_prepare_head($object);
$title = $langs->trans("Group");
dol_fiche_head($head, 'rights', $title, -1, 'group');
@ -239,7 +247,6 @@ if ($object->id)
if ($result)
{
$i = 0;
$var = true;
$oldmod = '';
$num = $db->num_rows($result);
@ -258,31 +265,30 @@ if ($object->id)
if ($oldmod <> $obj->module)
{
$oldmod = $obj->module;
$var = !$var;
// Rupture detectee, on recupere objMod
$objMod = $modules[$obj->module];
$picto=($objMod->picto?$objMod->picto:'generic');
print '<tr class="oddeven trforbreak">';
print '<td class="nowrap">'.img_object('', $picto, 'class="inline-block pictoobjectwidth"').' '.$objMod->getName();
print '<a name="'.$objMod->getName().'">&nbsp;</a></td>';
print '<td align="center" class="nowrap">';
if ($caneditperms)
{
print '<tr '. $bc[$var].'>';
print '<td class="nowrap">'.img_object('',$picto).' '.$objMod->getName();
print '<a name="'.$objMod->getName().'">&nbsp;</a></td>';
print '<td align="center" class="nowrap">';
print '<a title='.$langs->trans("All").' alt='.$langs->trans("All").' href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=addrights&amp;entity='.$entity.'&amp;module='.$obj->module.'#'.$objMod->getName().'">'.$langs->trans("All")."</a>";
print '<a title='.$langs->trans("All").' alt='.$langs->trans("All").' href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=addrights&amp;entity='.$entity.'&amp;module='.$obj->module.'#'.$objMod->getName().'">'.$langs->trans("All")."</a>";
print '/';
print '<a title='.$langs->trans("None").' alt='.$langs->trans("None").' href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=delrights&amp;entity='.$entity.'&amp;module='.$obj->module.'#'.$objMod->getName().'">'.$langs->trans("None")."</a>";
print '</td>';
print '<td colspan="2">&nbsp;</td>';
print '</tr>';
}
print '</td>';
print '<td colspan="2">&nbsp;</td>';
print '</tr>';
}
print '<tr '. $bc[$var].'>';
print '<tr class="oddeven">';
// Module
print '<td class="nowrap">'.img_object('',$picto).' '.$objMod->getName().'</td>';
print '<td class="nowrap">'.img_object('', $picto, 'class="inline-block pictoobjectwidth"').' '.$objMod->getName().'</td>';
if (is_array($permsgroupbyentity[$entity]))
{

View File

@ -282,7 +282,6 @@ if ($result)
{
$num = $db->num_rows($result);
$i = 0;
$var = True;
$oldmod='';
while ($i < $num)
@ -295,39 +294,37 @@ if ($result)
$i++;
continue;
}
if (isset($obj->module) && ($oldmod <> $obj->module))
{
$oldmod = $obj->module;
$var = !$var;
// Rupture detectee, on recupere objMod
// Break detected, we get objMod
$objMod=$modules[$obj->module];
$picto=($objMod->picto?$objMod->picto:'generic');
if ($caneditperms && (empty($objMod->rights_admin_allowed) || empty($object->admin)))
{
// On affiche ligne pour modifier droits
print '<tr '. $bc[$var].'>';
print '<td class="maxwidthonsmartphone tdoverflowonsmartphone">'.img_object('',$picto,'class="pictoobjectwidth"').' '.$objMod->getName();
print '<a name="'.$objMod->getName().'"></a></td>';
print '<td align="center" class="nowrap">';
print '<a class="reposition" title="'.dol_escape_htmltag($langs->trans("All")).'" alt="'.dol_escape_htmltag($langs->trans("All")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=addrights&amp;entity='.$entity.'&amp;module='.$obj->module.'">'.$langs->trans("All")."</a>";
print '/';
print '<a class="reposition" title="'.dol_escape_htmltag($langs->trans("None")).'" alt="'.dol_escape_htmltag($langs->trans("None")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=delrights&amp;entity='.$entity.'&amp;module='.$obj->module.'">'.$langs->trans("None")."</a>";
print '</td>';
print '<td colspan="2">&nbsp;</td>';
print '</tr>'."\n";
}
// Show break line
print '<tr class="oddeven trforbreak">';
print '<td class="maxwidthonsmartphone tdoverflowonsmartphone">'.img_object('',$picto,'class="pictoobjectwidth"').' '.$objMod->getName();
print '<a name="'.$objMod->getName().'"></a></td>';
print '<td align="center" class="nowrap">';
if ($caneditperms && empty($objMod->rights_admin_allowed) || empty($object->admin))
{
print '<a class="reposition" title="'.dol_escape_htmltag($langs->trans("All")).'" alt="'.dol_escape_htmltag($langs->trans("All")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=addrights&amp;entity='.$entity.'&amp;module='.$obj->module.'">'.$langs->trans("All")."</a>";
print '/';
print '<a class="reposition" title="'.dol_escape_htmltag($langs->trans("None")).'" alt="'.dol_escape_htmltag($langs->trans("None")).'" href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&amp;action=delrights&amp;entity='.$entity.'&amp;module='.$obj->module.'">'.$langs->trans("None")."</a>";
}
print '</td>';
print '<td colspan="2">&nbsp;</td>';
print '</tr>'."\n";
}
print '<tr '. $bc[$var].'>';
print '<tr class="oddeven">';
// Picto and label of permission
print '<td class="maxwidthonsmartphone tdoverflowonsmartphone">'.img_object('',$picto,'class="pictoobjectwidth"').' '.$objMod->getName().'</td>';
// Permission and tick
if (! empty($object->admin) && ! empty($objMod->rights_admin_allowed)) // Permission own because admin
if (! empty($object->admin) && ! empty($objMod->rights_admin_allowed)) // Permission granted because admin
{
if ($caneditperms)
{
@ -337,7 +334,7 @@ if ($result)
print img_picto($langs->trans("Active"),'tick');
print '</td>';
}
else if (in_array($obj->id, $permsuser)) // Permission own by user
else if (in_array($obj->id, $permsuser)) // Permission granted by user
{
if ($caneditperms)
{
@ -350,7 +347,7 @@ if ($result)
else if (is_array($permsgroupbyentity[$entity]))
{
if (in_array($obj->id, $permsgroupbyentity[$entity])) // Permission own by group
if (in_array($obj->id, $permsgroupbyentity[$entity])) // Permission granted by group
{
if ($caneditperms)
{