diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index e7b36b77ad9..6f9123c0a0e 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -644,19 +644,27 @@ if (empty($reshook)) $msg = $arraydefaultmessage->content; } - $substitutionarray=getCommonSubstitutionArray($outputlangs, 0, null, $object); - complete_substitutions_array($substitutionarray, $outputlangs, $object); - $subjecttosend = make_substitutions($subject, $substitutionarray, $outputlangs); - $texttosend = make_substitutions(dol_concatdesc($msg, $adht->getMailOnValid()), $substitutionarray, $outputlangs); + if (empty($labeltouse) || (int)$labeltouse === -1) { + //fallback on the old configuration. + setEventMessages('WarningMandatorySetupNotComplete', [], 'errors'); + $error++; + }else{ + $substitutionarray=getCommonSubstitutionArray($outputlangs, 0, null, $object); + complete_substitutions_array($substitutionarray, $outputlangs, $object); + $subjecttosend = make_substitutions($subject, $substitutionarray, $outputlangs); + $texttosend = make_substitutions(dol_concatdesc($msg, $adht->getMailOnValid()), $substitutionarray, $outputlangs); + + $moreinheader='X-Dolibarr-Info: send_an_email by adherents/card.php'."\r\n"; + + $result=$object->send_an_email($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader); + if ($result < 0) + { + $error++; + setEventMessages($object->error, $object->errors, 'errors'); + } + } - $moreinheader='X-Dolibarr-Info: send_an_email by adherents/card.php'."\r\n"; - $result=$object->send_an_email($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader); - if ($result < 0) - { - $error++; - setEventMessages($object->error, $object->errors, 'errors'); - } } } else @@ -718,20 +726,28 @@ if (empty($reshook)) $msg = $arraydefaultmessage->content; } - $substitutionarray=getCommonSubstitutionArray($outputlangs, 0, null, $object); - complete_substitutions_array($substitutionarray, $outputlangs, $object); - $subjecttosend = make_substitutions($subject, $substitutionarray, $outputlangs); - $texttosend = make_substitutions(dol_concatdesc($msg, $adht->getMailOnResiliate()), $substitutionarray, $outputlangs); + if (empty($labeltouse) || (int)$labeltouse === -1) { + //fallback on the old configuration. + setEventMessages('WarningMandatorySetupNotComplete', [], 'errors'); + $error++; + }else{ + $substitutionarray=getCommonSubstitutionArray($outputlangs, 0, null, $object); + complete_substitutions_array($substitutionarray, $outputlangs, $object); + $subjecttosend = make_substitutions($subject, $substitutionarray, $outputlangs); + $texttosend = make_substitutions(dol_concatdesc($msg, $adht->getMailOnResiliate()), $substitutionarray, $outputlangs); + + $moreinheader='X-Dolibarr-Info: send_an_email by adherents/card.php'."\r\n"; + + $result=$object->send_an_email($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader); + if ($result < 0) + { + $error++; + setEventMessages($object->error, $object->errors, 'errors'); + } + } + } - $moreinheader='X-Dolibarr-Info: send_an_email by adherents/card.php'."\r\n"; - $result=$object->send_an_email($texttosend, $subjecttosend, array(), array(), array(), "", "", 0, -1, '', $moreinheader); - } - if ($result < 0) - { - $error++; - setEventMessages($object->error, $object->errors, 'errors'); - } } else { diff --git a/htdocs/adherents/subscription/list.php b/htdocs/adherents/subscription/list.php index 91e5b2f8837..474082b1cfa 100644 --- a/htdocs/adherents/subscription/list.php +++ b/htdocs/adherents/subscription/list.php @@ -40,7 +40,7 @@ $search_account=GETPOST('search_account','int'); $search_amount=GETPOST('search_amount','alpha'); $optioncss = GETPOST('optioncss','alpha'); -$date_select=isset($_GET["date_select"])?$_GET["date_select"]:$_POST["date_select"]; +$date_select=GETPOST("date_select",'alpha'); $limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; $sortfield = GETPOST("sortfield",'alpha'); @@ -126,7 +126,8 @@ $sql.= " WHERE d.rowid = c.fk_adherent"; $sql.= " AND d.entity IN (".getEntity('adherent').")"; if (isset($date_select) && $date_select != '') { - $sql.= " AND c.dateadh LIKE '".$date_select."%'"; + $sql.= " AND c.dateadh >= '".$date_select."-01-01 00:00:00'"; + $sql.= " AND c.dateadh < '".($date_select+1)."-01-01 00:00:00'"; } if ($search_ref) { diff --git a/htdocs/commande/class/commande.class.php b/htdocs/commande/class/commande.class.php index 2428e6052eb..4402735e188 100644 --- a/htdocs/commande/class/commande.class.php +++ b/htdocs/commande/class/commande.class.php @@ -108,8 +108,11 @@ class Commande extends CommonOrder */ public $billed; // billed or not - public $brouillon; - public $cond_reglement_code; + /** + * @var int Draft Status of the order + */ + public $brouillon; + public $cond_reglement_code; /** * @var int ID @@ -155,7 +158,7 @@ class Commande extends CommonOrder public $demand_reason_id; // Source reason. Why we receive order (after a phone campaign, ...) public $demand_reason_code; public $date; // Date commande - + /** * @deprecated * @see date @@ -274,11 +277,11 @@ class Commande extends CommonOrder $mybool|=@include_once $dir.$file; } - if (! $mybool) - { - dol_print_error('',"Failed to include file ".$file); - return ''; - } + if ($mybool === false) + { + dol_print_error('',"Failed to include file ".$file); + return ''; + } $obj = new $classname(); $numref = $obj->getNextValue($soc,$this); @@ -448,6 +451,7 @@ class Commande extends CommonOrder { $this->ref = $num; $this->statut = self::STATUS_VALIDATED; + $this->brouillon = 0; } if (! $error) @@ -3774,7 +3778,7 @@ class Commande extends CommonOrder * @param int $hidedetails Hide details of lines * @param int $hidedesc Hide description * @param int $hideref Hide ref - * @param null|array $moreparams Array to provide more information + * @param null|array $moreparams Array to provide more information * @return int 0 if KO, 1 if OK */ public function generateDocument($modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0, $moreparams=null) diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index 050f8786c3a..727d5b7c2bd 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -93,11 +93,6 @@ $hidedetails = (GETPOST('hidedetails', 'int') ? GETPOST('hidedetails', 'int') : $hidedesc = (GETPOST('hidedesc', 'int') ? GETPOST('hidedesc', 'int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0)); $hideref = (GETPOST('hideref', 'int') ? GETPOST('hideref', 'int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0)); -// Security check -$fieldid = (! empty($ref) ? 'facnumber' : 'rowid'); -if ($user->societe_id) $socid = $user->societe_id; -$result = restrictedArea($user, 'facture', $id, '', '', 'fk_soc', $fieldid); - // Nombre de ligne pour choix de produit/service predefinis $NBLINES = 4; @@ -118,6 +113,12 @@ $permissionnote = $user->rights->facture->creer; // Used by the include of actio $permissiondellink=$user->rights->facture->creer; // Used by the include of actions_dellink.inc.php $permissiontoedit = $user->rights->facture->creer; // Used by the include of actions_lineupdonw.inc.php +// Security check +$fieldid = (! empty($ref) ? 'facnumber' : 'rowid'); +if ($user->societe_id) $socid = $user->societe_id; +$isdraft = (($object->statut == Facture::STATUS_DRAFT) ? 1 : 0); +$result = restrictedArea($user, 'facture', $id, '', '', 'fk_soc', $fieldid, $isdraft); + /* * Actions @@ -178,7 +179,7 @@ if (empty($reshook)) } // Delete invoice - else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->facture->supprimer) { + else if ($action == 'confirm_delete' && $confirm == 'yes') { $result = $object->fetch($id); $object->fetch_thirdparty(); @@ -191,7 +192,10 @@ if (empty($reshook)) $qualified_for_stock_change = $object->hasProductsOrServices(1); } - if ($object->is_erasable()) + $isErasable=$object->is_erasable(); + + if (($user->rights->facture->supprimer && $isErasable > 0) + || ($user->rights->facture->creer && $isErasable == 1)) { $result = $object->delete($user, 0, $idwarehouse); if ($result > 0) { @@ -2981,8 +2985,8 @@ if ($action == 'create') print $desc; print ''; } - - + + if (empty($origin)) { if ($socid > 0) @@ -3057,7 +3061,7 @@ if ($action == 'create') print ''; - + if(!empty($conf->global->INVOICE_USE_DEFAULT_DOCUMENT)) // Hidden conf { // Add auto select default document model @@ -3069,7 +3073,7 @@ if ($action == 'create') $curent = !empty($conf->global->{$thisTypeConfName})?$conf->global->{$thisTypeConfName}:$conf->global->FACTURE_ADDON_PDF; $jsListType.=(!empty($jsListType)?',':'').'"'.$type.'":"'.$curent.'"'; } - + print ''; } - - - + + + print ''; if ($socid > 0) @@ -4847,9 +4851,9 @@ else if ($id > 0 || ! empty($ref)) } // Delete - if ($user->rights->facture->supprimer) + $isErasable = $object->is_erasable(); + if ($user->rights->facture->supprimer || ($user->rights->facture->creer && $isErasable == 1)) // isErasable = 1 means draft with temporary ref (draft can always be deleted with no need of permissions) { - $isErasable = $object->is_erasable(); //var_dump($isErasable); if ($isErasable == -4) { print '
' . $langs->trans('Delete') . '
'; diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 3d98271bb26..a27b559105f 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -251,7 +251,7 @@ class Facture extends CommonInvoice * If paid partially, $this->close_code can be: * - CLOSECODE_DISCOUNTVAT * - CLOSECODE_BADDEBT - * If paid completelly, this->close_code will be null + * If paid completely, this->close_code will be null */ const STATUS_CLOSED = 2; @@ -2442,7 +2442,7 @@ class Facture extends CommonInvoice } } - // Set new ref and define current statut + // Set new ref and define current status if (! $error) { $this->ref = $num; @@ -4950,7 +4950,7 @@ class FactureLigne extends CommonInvoiceLine if (is_null($this->fk_prev_id) || empty($this->fk_prev_id) || $this->fk_prev_id == "") { return 0; } else { - // If invoice is a not a situation invoice, this->fk_prev_id is used for something else + // If invoice is not a situation invoice, this->fk_prev_id is used for something else $tmpinvoice=new Facture($this->db); $tmpinvoice->fetch($invoiceid); if ($tmpinvoice->type != Facture::TYPE_SITUATION) return 0; diff --git a/htdocs/core/class/commoninvoice.class.php b/htdocs/core/class/commoninvoice.class.php index b5b363db923..7174d48a5ee 100644 --- a/htdocs/core/class/commoninvoice.class.php +++ b/htdocs/core/class/commoninvoice.class.php @@ -329,12 +329,13 @@ abstract class CommonInvoice extends CommonObject /** * Return if an invoice can be deleted * Rule is: - * If invoice is draft and has a temporary ref -> yes + * If invoice is draft and has a temporary ref -> yes (1) * If hidden option INVOICE_CAN_NEVER_BE_REMOVED is on -> no (0) * If invoice is dispatched in bookkeeping -> no (-1) * If invoice has a definitive ref, is not last and INVOICE_CAN_ALWAYS_BE_REMOVED off -> no (-2) * If invoice not last in a cycle -> no (-3) * If there is payment -> no (-4) + * Otherwise -> yes (2) * * @return int <=0 if no, >0 if yes */ @@ -383,7 +384,7 @@ abstract class CommonInvoice extends CommonObject // Test if there is at least one payment. If yes, refuse to delete. if (empty($conf->global->INVOICE_CAN_ALWAYS_BE_REMOVED) && $this->getSommePaiement() > 0) return -4; - return 1; + return 2; } /** diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 10aa25c86ba..1f19e5094d7 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -6572,7 +6572,7 @@ function get_htmloutput_mesg($mesgstring='',$mesgarray='', $style='ok', $keepemb /** * Get formated error messages to output (Used to show messages on html output). * - * @param string $mesgstring Error message + * @param string $mesgstring Error message * @param array $mesgarray Error messages array * @param int $keepembedded Set to 1 in error message must be kept embedded into its html place (this disable jnotify) * @return string Return html output @@ -6580,7 +6580,7 @@ function get_htmloutput_mesg($mesgstring='',$mesgarray='', $style='ok', $keepemb * @see dol_print_error * @see dol_htmloutput_mesg */ -function get_htmloutput_errors($mesgstring='', $mesgarray='', $keepembedded=0) +function get_htmloutput_errors($mesgstring='', $mesgarray=array(), $keepembedded=0) { return get_htmloutput_mesg($mesgstring, $mesgarray,'error',$keepembedded); } @@ -6590,15 +6590,15 @@ function get_htmloutput_errors($mesgstring='', $mesgarray='', $keepembedded=0) * * @param string $mesgstring Message string or message key * @param string[] $mesgarray Array of message strings or message keys - * @param string $style Which style to use ('ok', 'warning', 'error') - * @param int $keepembedded Set to 1 if message must be kept embedded into its html place (this disable jnotify) - * @return void + * @param string $style Which style to use ('ok', 'warning', 'error') + * @param int $keepembedded Set to 1 if message must be kept embedded into its html place (this disable jnotify) + * @return void * - * @see dol_print_error - * @see dol_htmloutput_errors - * @see setEventMessages + * @see dol_print_error + * @see dol_htmloutput_errors + * @see setEventMessages */ -function dol_htmloutput_mesg($mesgstring='',$mesgarray='', $style='ok', $keepembedded=0) +function dol_htmloutput_mesg($mesgstring = '',$mesgarray = array(), $style = 'ok', $keepembedded=0) { if (empty($mesgstring) && (! is_array($mesgarray) || count($mesgarray) == 0)) return; @@ -6652,7 +6652,7 @@ function dol_htmloutput_mesg($mesgstring='',$mesgarray='', $style='ok', $keepemb * @see dol_print_error * @see dol_htmloutput_mesg */ -function dol_htmloutput_errors($mesgstring='', $mesgarray='', $keepembedded=0) +function dol_htmloutput_errors($mesgstring='', $mesgarray=array(), $keepembedded=0) { dol_htmloutput_mesg($mesgstring, $mesgarray, 'error', $keepembedded); } diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 235421a598e..69ca0ca5a67 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -39,7 +39,7 @@ function dol_encode($chain, $key='1') if (is_numeric($key) && $key == '1') // rule 1 is offset of 17 for char { $output_tab=array(); - $strlength=dol_strlen($chain); + $strlength=dol_strlen($chain); for ($i=0; $i < $strlength; $i++) { $output_tab[$i] = chr(ord(substr($chain,$i,1))+17); @@ -174,18 +174,19 @@ function dol_verifyHash($chain, $hash, $type='0') * @param string $feature2 Feature to check, second level of permission (optional). Can be a 'or' check with 'level1|level2'. * @param string $dbt_keyfield Field name for socid foreign key if not fk_soc. Not used if objectid is null (optional) * @param string $dbt_select Field name for select if not rowid. Not used if objectid is null (optional) + * @param int $isdraft 1=The object with id=$objectid is a draft * @return int Always 1, die process if not allowed * @see dol_check_secure_access_document */ -function restrictedArea($user, $features, $objectid=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid') +function restrictedArea($user, $features, $objectid=0, $tableandshare='', $feature2='', $dbt_keyfield='fk_soc', $dbt_select='rowid', $isdraft=0) { global $db, $conf; global $hookmanager; - //dol_syslog("functions.lib:restrictedArea $feature, $objectid, $dbtablename,$feature2,$dbt_socfield,$dbt_select"); - //print "user_id=".$user->id.", features=".$features.", feature2=".$feature2.", objectid=".$objectid; - //print ", dbtablename=".$dbtablename.", dbt_socfield=".$dbt_keyfield.", dbt_select=".$dbt_select; - //print ", perm: ".$features."->".$feature2."=".($user->rights->$features->$feature2->lire)."
"; + //dol_syslog("functions.lib:restrictedArea $feature, $objectid, $dbtablename,$feature2,$dbt_socfield,$dbt_select"); + //print "user_id=".$user->id.", features=".$features.", feature2=".$feature2.", objectid=".$objectid; + //print ", dbtablename=".$dbtablename.", dbt_socfield=".$dbt_keyfield.", dbt_select=".$dbt_select; + //print ", perm: ".$features."->".$feature2."=".($user->rights->$features->$feature2->lire)."
"; // Get more permissions checks from hooks $parameters=array('features'=>$features, 'objectid'=>$objectid, 'idtype'=>$dbt_select); @@ -196,225 +197,225 @@ function restrictedArea($user, $features, $objectid=0, $tableandshare='', $featu if ($dbt_select != 'rowid' && $dbt_select != 'id') $objectid = "'".$objectid."'"; // Features/modules to check - $featuresarray = array($features); - if (preg_match('/&/', $features)) $featuresarray = explode("&", $features); - else if (preg_match('/\|/', $features)) $featuresarray = explode("|", $features); + $featuresarray = array($features); + if (preg_match('/&/', $features)) $featuresarray = explode("&", $features); + else if (preg_match('/\|/', $features)) $featuresarray = explode("|", $features); - // More subfeatures to check - if (! empty($feature2)) $feature2 = explode("|", $feature2); + // More subfeatures to check + if (! empty($feature2)) $feature2 = explode("|", $feature2); - // More parameters - $params = explode('&', $tableandshare); - $dbtablename=(! empty($params[0]) ? $params[0] : ''); - $sharedelement=(! empty($params[1]) ? $params[1] : $dbtablename); + // More parameters + $params = explode('&', $tableandshare); + $dbtablename=(! empty($params[0]) ? $params[0] : ''); + $sharedelement=(! empty($params[1]) ? $params[1] : $dbtablename); $listofmodules=explode(',',$conf->global->MAIN_MODULES_FOR_EXTERNAL); // Check read permission from module - $readok=1; $nbko=0; - foreach ($featuresarray as $feature) // first we check nb of test ko - { - $featureforlistofmodule=$feature; - if ($featureforlistofmodule == 'produit') $featureforlistofmodule='product'; - if (! empty($user->societe_id) && ! empty($conf->global->MAIN_MODULES_FOR_EXTERNAL) && ! in_array($featureforlistofmodule,$listofmodules)) // If limits on modules for external users, module must be into list of modules for external users - { - $readok=0; $nbko++; - continue; - } + $readok=1; $nbko=0; + foreach ($featuresarray as $feature) // first we check nb of test ko + { + $featureforlistofmodule=$feature; + if ($featureforlistofmodule == 'produit') $featureforlistofmodule='product'; + if (! empty($user->societe_id) && ! empty($conf->global->MAIN_MODULES_FOR_EXTERNAL) && ! in_array($featureforlistofmodule,$listofmodules)) // If limits on modules for external users, module must be into list of modules for external users + { + $readok=0; $nbko++; + continue; + } - if ($feature == 'societe') - { - if (! $user->rights->societe->lire && ! $user->rights->fournisseur->lire) { $readok=0; $nbko++; } - } - else if ($feature == 'contact') - { - if (! $user->rights->societe->contact->lire) { $readok=0; $nbko++; } - } - else if ($feature == 'produit|service') - { - if (! $user->rights->produit->lire && ! $user->rights->service->lire) { $readok=0; $nbko++; } - } - else if ($feature == 'prelevement') - { - if (! $user->rights->prelevement->bons->lire) { $readok=0; $nbko++; } - } - else if ($feature == 'cheque') - { - if (! $user->rights->banque->cheque) { $readok=0; $nbko++; } - } - else if ($feature == 'projet') - { - if (! $user->rights->projet->lire && ! $user->rights->projet->all->lire) { $readok=0; $nbko++; } - } - else if (! empty($feature2)) // This should be used for future changes - { - $tmpreadok=1; - foreach($feature2 as $subfeature) - { - if (! empty($subfeature) && empty($user->rights->$feature->$subfeature->lire) && empty($user->rights->$feature->$subfeature->read)) { $tmpreadok=0; } - else if (empty($subfeature) && empty($user->rights->$feature->lire) && empty($user->rights->$feature->read)) { $tmpreadok=0; } - else { $tmpreadok=1; break; } // Break is to bypass second test if the first is ok - } - if (! $tmpreadok) // We found a test on feature that is ko - { - $readok=0; // All tests are ko (we manage here the and, the or will be managed later using $nbko). - $nbko++; - } - } - else if (! empty($feature) && ($feature!='user' && $feature!='usergroup')) // This is for old permissions - { - if (empty($user->rights->$feature->lire) - && empty($user->rights->$feature->read) - && empty($user->rights->$feature->run)) { $readok=0; $nbko++; } - } - } + if ($feature == 'societe') + { + if (! $user->rights->societe->lire && ! $user->rights->fournisseur->lire) { $readok=0; $nbko++; } + } + else if ($feature == 'contact') + { + if (! $user->rights->societe->contact->lire) { $readok=0; $nbko++; } + } + else if ($feature == 'produit|service') + { + if (! $user->rights->produit->lire && ! $user->rights->service->lire) { $readok=0; $nbko++; } + } + else if ($feature == 'prelevement') + { + if (! $user->rights->prelevement->bons->lire) { $readok=0; $nbko++; } + } + else if ($feature == 'cheque') + { + if (! $user->rights->banque->cheque) { $readok=0; $nbko++; } + } + else if ($feature == 'projet') + { + if (! $user->rights->projet->lire && ! $user->rights->projet->all->lire) { $readok=0; $nbko++; } + } + else if (! empty($feature2)) // This should be used for future changes + { + $tmpreadok=1; + foreach($feature2 as $subfeature) + { + if (! empty($subfeature) && empty($user->rights->$feature->$subfeature->lire) && empty($user->rights->$feature->$subfeature->read)) { $tmpreadok=0; } + else if (empty($subfeature) && empty($user->rights->$feature->lire) && empty($user->rights->$feature->read)) { $tmpreadok=0; } + else { $tmpreadok=1; break; } // Break is to bypass second test if the first is ok + } + if (! $tmpreadok) // We found a test on feature that is ko + { + $readok=0; // All tests are ko (we manage here the and, the or will be managed later using $nbko). + $nbko++; + } + } + else if (! empty($feature) && ($feature!='user' && $feature!='usergroup')) // This is for old permissions + { + if (empty($user->rights->$feature->lire) + && empty($user->rights->$feature->read) + && empty($user->rights->$feature->run)) { $readok=0; $nbko++; } + } + } - // If a or and at least one ok - if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) $readok=1; + // If a or and at least one ok + if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) $readok=1; - if (! $readok) accessforbidden(); - //print "Read access is ok"; + if (! $readok) accessforbidden(); + //print "Read access is ok"; - // Check write permission from module - $createok=1; $nbko=0; - if (GETPOST('action','aZ09') == 'create') - { - foreach ($featuresarray as $feature) - { - if ($feature == 'contact') - { - if (! $user->rights->societe->contact->creer) { $createok=0; $nbko++; } - } - else if ($feature == 'produit|service') - { - if (! $user->rights->produit->creer && ! $user->rights->service->creer) { $createok=0; $nbko++; } - } - else if ($feature == 'prelevement') - { - if (! $user->rights->prelevement->bons->creer) { $createok=0; $nbko++; } - } - else if ($feature == 'commande_fournisseur') - { - if (! $user->rights->fournisseur->commande->creer) { $createok=0; $nbko++; } - } - else if ($feature == 'banque') - { - if (! $user->rights->banque->modifier) { $createok=0; $nbko++; } - } - else if ($feature == 'cheque') - { - if (! $user->rights->banque->cheque) { $createok=0; $nbko++; } - } - else if (! empty($feature2)) // This should be used - { - foreach($feature2 as $subfeature) - { - if (empty($user->rights->$feature->$subfeature->creer) - && empty($user->rights->$feature->$subfeature->write) - && empty($user->rights->$feature->$subfeature->create)) { $createok=0; $nbko++; } - else { $createok=1; break; } // Break to bypass second test if the first is ok - } - } - else if (! empty($feature)) // This is for old permissions ('creer' or 'write') - { - //print '
feature='.$feature.' creer='.$user->rights->$feature->creer.' write='.$user->rights->$feature->write; - if (empty($user->rights->$feature->creer) - && empty($user->rights->$feature->write) - && empty($user->rights->$feature->create)) { $createok=0; $nbko++; } - } - } + // Check write permission from module (we need to know write permission to create but also to delete drafts record) + $createok=1; $nbko=0; + if (GETPOST('action','aZ09') == 'create' || ((GETPOST("action","aZ09") == 'confirm_delete' && GETPOST("confirm","aZ09") == 'yes') || GETPOST("action","aZ09") == 'delete')) + { + foreach ($featuresarray as $feature) + { + if ($feature == 'contact') + { + if (! $user->rights->societe->contact->creer) { $createok=0; $nbko++; } + } + else if ($feature == 'produit|service') + { + if (! $user->rights->produit->creer && ! $user->rights->service->creer) { $createok=0; $nbko++; } + } + else if ($feature == 'prelevement') + { + if (! $user->rights->prelevement->bons->creer) { $createok=0; $nbko++; } + } + else if ($feature == 'commande_fournisseur') + { + if (! $user->rights->fournisseur->commande->creer) { $createok=0; $nbko++; } + } + else if ($feature == 'banque') + { + if (! $user->rights->banque->modifier) { $createok=0; $nbko++; } + } + else if ($feature == 'cheque') + { + if (! $user->rights->banque->cheque) { $createok=0; $nbko++; } + } + else if (! empty($feature2)) // This should be used + { + foreach($feature2 as $subfeature) + { + if (empty($user->rights->$feature->$subfeature->creer) + && empty($user->rights->$feature->$subfeature->write) + && empty($user->rights->$feature->$subfeature->create)) { $createok=0; $nbko++; } + else { $createok=1; break; } // Break to bypass second test if the first is ok + } + } + else if (! empty($feature)) // This is for old permissions ('creer' or 'write') + { + //print '
feature='.$feature.' creer='.$user->rights->$feature->creer.' write='.$user->rights->$feature->write; + if (empty($user->rights->$feature->creer) + && empty($user->rights->$feature->write) + && empty($user->rights->$feature->create)) { $createok=0; $nbko++; } + } + } - // If a or and at least one ok - if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) $createok=1; + // If a or and at least one ok + if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) $createok=1; - if (! $createok) accessforbidden(); - //print "Write access is ok"; - } + if (GETPOST('action','aZ09') == 'create' && ! $createok) accessforbidden(); + //print "Write access is ok"; + } - // Check create user permission - $createuserok=1; - if (GETPOST('action','aZ09') == 'confirm_create_user' && GETPOST("confirm",'aZ09') == 'yes') - { - if (! $user->rights->user->user->creer) $createuserok=0; + // Check create user permission + $createuserok=1; + if (GETPOST('action','aZ09') == 'confirm_create_user' && GETPOST("confirm",'aZ09') == 'yes') + { + if (! $user->rights->user->user->creer) $createuserok=0; - if (! $createuserok) accessforbidden(); - //print "Create user access is ok"; - } + if (! $createuserok) accessforbidden(); + //print "Create user access is ok"; + } - // Check delete permission from module - $deleteok=1; $nbko=0; - if ((GETPOST("action","aZ09") == 'confirm_delete' && GETPOST("confirm","aZ09") == 'yes') || GETPOST("action","aZ09") == 'delete') - { - foreach ($featuresarray as $feature) - { - if ($feature == 'contact') - { - if (! $user->rights->societe->contact->supprimer) $deleteok=0; - } - else if ($feature == 'produit|service') - { - if (! $user->rights->produit->supprimer && ! $user->rights->service->supprimer) $deleteok=0; - } - else if ($feature == 'commande_fournisseur') - { - if (! $user->rights->fournisseur->commande->supprimer) $deleteok=0; - } - else if ($feature == 'banque') - { - if (! $user->rights->banque->modifier) $deleteok=0; - } - else if ($feature == 'cheque') - { - if (! $user->rights->banque->cheque) $deleteok=0; - } - else if ($feature == 'ecm') - { - if (! $user->rights->ecm->upload) $deleteok=0; - } - else if ($feature == 'ftp') - { - if (! $user->rights->ftp->write) $deleteok=0; - }else if ($feature == 'salaries') - { - if (! $user->rights->salaries->delete) $deleteok=0; - } - else if ($feature == 'salaries') - { - if (! $user->rights->salaries->delete) $deleteok=0; - } - else if (! empty($feature2)) // This should be used for future changes - { - foreach($feature2 as $subfeature) - { - if (empty($user->rights->$feature->$subfeature->supprimer) && empty($user->rights->$feature->$subfeature->delete)) $deleteok=0; - else { $deleteok=1; break; } // For bypass the second test if the first is ok - } - } - else if (! empty($feature)) // This is for old permissions - { - //print '
feature='.$feature.' creer='.$user->rights->$feature->supprimer.' write='.$user->rights->$feature->delete; - if (empty($user->rights->$feature->supprimer) - && empty($user->rights->$feature->delete) - && empty($user->rights->$feature->run)) $deleteok=0; - } - } + // Check delete permission from module + $deleteok=1; $nbko=0; + if ((GETPOST("action","aZ09") == 'confirm_delete' && GETPOST("confirm","aZ09") == 'yes') || GETPOST("action","aZ09") == 'delete') + { + foreach ($featuresarray as $feature) + { + if ($feature == 'contact') + { + if (! $user->rights->societe->contact->supprimer) $deleteok=0; + } + else if ($feature == 'produit|service') + { + if (! $user->rights->produit->supprimer && ! $user->rights->service->supprimer) $deleteok=0; + } + else if ($feature == 'commande_fournisseur') + { + if (! $user->rights->fournisseur->commande->supprimer) $deleteok=0; + } + else if ($feature == 'banque') + { + if (! $user->rights->banque->modifier) $deleteok=0; + } + else if ($feature == 'cheque') + { + if (! $user->rights->banque->cheque) $deleteok=0; + } + else if ($feature == 'ecm') + { + if (! $user->rights->ecm->upload) $deleteok=0; + } + else if ($feature == 'ftp') + { + if (! $user->rights->ftp->write) $deleteok=0; + }else if ($feature == 'salaries') + { + if (! $user->rights->salaries->delete) $deleteok=0; + } + else if ($feature == 'salaries') + { + if (! $user->rights->salaries->delete) $deleteok=0; + } + else if (! empty($feature2)) // This should be used for permissions on 2 levels + { + foreach($feature2 as $subfeature) + { + if (empty($user->rights->$feature->$subfeature->supprimer) && empty($user->rights->$feature->$subfeature->delete)) $deleteok=0; + else { $deleteok=1; break; } // For bypass the second test if the first is ok + } + } + else if (! empty($feature)) // This is used for permissions on 1 level + { + //print '
feature='.$feature.' creer='.$user->rights->$feature->supprimer.' write='.$user->rights->$feature->delete; + if (empty($user->rights->$feature->supprimer) + && empty($user->rights->$feature->delete) + && empty($user->rights->$feature->run)) $deleteok=0; + } + } - // If a or and at least one ok - if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) $deleteok=1; + // If a or and at least one ok + if (preg_match('/\|/', $features) && $nbko < count($featuresarray)) $deleteok=1; - if (! $deleteok) accessforbidden(); - //print "Delete access is ok"; - } + if (! $deleteok && ! ($isdraft && $createok)) accessforbidden(); + //print "Delete access is ok"; + } - // If we have a particular object to check permissions on, we check this object - // is linked to a company allowed to $user. - if (! empty($objectid) && $objectid > 0) - { - $ok = checkUserAccessToObject($user, $featuresarray, $objectid, $tableandshare, $feature2, $dbt_keyfield, $dbt_select); - return $ok ? 1 : accessforbidden(); - } + // If we have a particular object to check permissions on, we check this object + // is linked to a company allowed to $user. + if (! empty($objectid) && $objectid > 0) + { + $ok = checkUserAccessToObject($user, $featuresarray, $objectid, $tableandshare, $feature2, $dbt_keyfield, $dbt_select); + return $ok ? 1 : accessforbidden(); + } - return 1; + return 1; } /** @@ -576,8 +577,8 @@ function checkUserAccessToObject($user, $featuresarray, $objectid=0, $tableandsh { if (! empty($conf->projet->enabled) && empty($user->rights->projet->all->lire)) { - $task = new Task($db); - $task->fetch($objectid); + $task = new Task($db); + $task->fetch($objectid); include_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; $projectstatic=new Project($db); @@ -665,30 +666,30 @@ function accessforbidden($message='',$printheader=1,$printfooter=1,$showonlymess $langs->setDefaultLang(); } - $langs->load("errors"); + $langs->load("errors"); - if ($printheader) - { - if (function_exists("llxHeader")) llxHeader(''); - else if (function_exists("llxHeaderVierge")) llxHeaderVierge(''); - } - print '
'; - if (! $message) print $langs->trans("ErrorForbidden"); - else print $message; - print '
'; - print '
'; - if (empty($showonlymessage)) - { - if ($user->login) - { - print $langs->trans("CurrentLogin").': '.$user->login.'
'; - print $langs->trans("ErrorForbidden2",$langs->trans("Home"),$langs->trans("Users")); - } - else - { - print $langs->trans("ErrorForbidden3"); - } - } - if ($printfooter && function_exists("llxFooter")) llxFooter(); - exit(0); + if ($printheader) + { + if (function_exists("llxHeader")) llxHeader(''); + else if (function_exists("llxHeaderVierge")) llxHeaderVierge(''); + } + print '
'; + if (! $message) print $langs->trans("ErrorForbidden"); + else print $message; + print '
'; + print '
'; + if (empty($showonlymessage)) + { + if ($user->login) + { + print $langs->trans("CurrentLogin").': '.$user->login.'
'; + print $langs->trans("ErrorForbidden2",$langs->trans("Home"),$langs->trans("Users")); + } + else + { + print $langs->trans("ErrorForbidden3"); + } + } + if ($printfooter && function_exists("llxFooter")) llxFooter(); + exit(0); } diff --git a/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php b/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php index 4793ebe7b27..43150031d7b 100644 --- a/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php +++ b/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php @@ -808,43 +808,6 @@ class pdf_typhon extends ModelePDFDeliveryOrder $posy+=2; - // Add list of linked orders on shipment - // Currently not supported by pdf_writeLinkedObjects, link for delivery to order is done through shipment) - if ($object->origin == 'expedition' || $object->origin == 'shipping') - { - $Yoff=$posy-5; - - include_once DOL_DOCUMENT_ROOT.'/expedition/class/expedition.class.php'; - $shipment = new Expedition($this->db); - $shipment->fetch($object->origin_id); - - $origin = $shipment->origin; - $origin_id = $shipment->origin_id; - - if ($conf->$origin->enabled) - { - $outputlangs->load('orders'); - - $classname = ucfirst($origin); - $linkedobject = new $classname($this->db); - $result=$linkedobject->fetch($origin_id); - if ($result >= 0) - { - $pdf->SetFont('','', $default_font_size - 2); - $text=$linkedobject->ref; - if ($linkedobject->ref_client) $text.=' ('.$linkedobject->ref_client.')'; - $Yoff = $Yoff+8; - $pdf->SetXY($this->page_largeur - $this->marge_droite - 100,$Yoff); - $pdf->MultiCell(100, 2, $outputlangs->transnoentities("RefOrder") ." : ".$outputlangs->transnoentities($text), 0, 'R'); - $Yoff = $Yoff+3; - $pdf->SetXY($this->page_largeur - $this->marge_droite - 60,$Yoff); - $pdf->MultiCell(60, 2, $outputlangs->transnoentities("OrderDate")." : ".dol_print_date($linkedobject->date,"day",false,$outputlangs,true), 0, 'R'); - } - } - - $posy=$Yoff; - } - // Show list of linked objects $posy = pdf_writeLinkedObjects($pdf, $object, $outputlangs, $posx, $posy, 100, 3, 'R', $default_font_size); diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 9df540da197..0ad2c407ec2 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -73,11 +73,6 @@ $hidedetails = (GETPOST('hidedetails','int') ? GETPOST('hidedetails','int') : (! $hidedesc = (GETPOST('hidedesc','int') ? GETPOST('hidedesc','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_DESC) ? 1 : 0)); $hideref = (GETPOST('hideref','int') ? GETPOST('hideref','int') : (! empty($conf->global->MAIN_GENERATE_DOCUMENTS_HIDE_REF) ? 1 : 0)); -// Security check -$socid=''; -if (! empty($user->societe_id)) $socid=$user->societe_id; -$result = restrictedArea($user, 'fournisseur', $id, 'facture_fourn', 'facture'); - // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $hookmanager->initHooks(array('invoicesuppliercard','globalcard')); @@ -96,6 +91,12 @@ if ($id > 0 || ! empty($ref)) if ($ret < 0) dol_print_error($db,$object->error); } +// Security check +$socid=''; +if (! empty($user->societe_id)) $socid=$user->societe_id; +$isdraft = (($object->statut == FactureFournisseur::STATUS_DRAFT) ? 1 : 0); +$result = restrictedArea($user, 'fournisseur', $id, 'facture_fourn', 'facture', 'fk_soc', 'rowid', $isdraft); + $permissionnote=$user->rights->fournisseur->facture->creer; // Used by the include of actions_setnotes.inc.php $permissiondellink=$user->rights->fournisseur->facture->creer; // Used by the include of actions_dellink.inc.php $permissionedit=$user->rights->fournisseur->facture->creer; // Used by the include of actions_lineupdown.inc.php @@ -219,19 +220,26 @@ if (empty($reshook)) } } - elseif ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->fournisseur->facture->supprimer) + elseif ($action == 'confirm_delete' && $confirm == 'yes') { $object->fetch($id); $object->fetch_thirdparty(); - $result=$object->delete($user); - if ($result > 0) + + $isErasable=$object->is_erasable(); + + if (($user->rights->fournisseur->facture->supprimer && $isErasable > 0) + || ($user->rights->fournisseur->facture->creer && $isErasable == 1)) { - header('Location: list.php?restore_lastsearch_values=1'); - exit; - } - else - { - setEventMessages($object->error, $object->errors, 'errors'); + $result=$object->delete($user); + if ($result > 0) + { + header('Location: list.php?restore_lastsearch_values=1'); + exit; + } + else + { + setEventMessages($object->error, $object->errors, 'errors'); + } } } @@ -3114,9 +3122,9 @@ else } // Delete - if ($action != 'confirm_edit' && $user->rights->fournisseur->facture->supprimer) + $isErasable=$object->is_erasable(); + if ($action != 'confirm_edit' && ($user->rights->fournisseur->facture->supprimer || ($user->rights->fournisseur->facture->creer && $isErasable == 1))) // isErasable = 1 means draft with temporary ref (draft can always be deleted with no need of permissions) { - $isErasable=$object->is_erasable(); //var_dump($isErasable); if ($isErasable == -4) { print '
' . $langs->trans('Delete') . '
'; diff --git a/htdocs/langs/en_US/errors.lang b/htdocs/langs/en_US/errors.lang index 29dbf4b4287..3c806156c7c 100644 --- a/htdocs/langs/en_US/errors.lang +++ b/htdocs/langs/en_US/errors.lang @@ -89,6 +89,7 @@ ErrorFileIsInfectedWithAVirus=The antivirus program was not able to validate the ErrorSpecialCharNotAllowedForField=Special characters are not allowed for field "%s" ErrorNumRefModel=A reference exists into database (%s) and is not compatible with this numbering rule. Remove record or renamed reference to activate this module. ErrorQtyTooLowForThisSupplier=Quantity too low for this vendor or no price defined on this product for this supplier +ErrorOrdersNotCreatedQtyTooLow=Some orders haven't been created beacuse of too low quantity ErrorModuleSetupNotComplete=Setup of module looks to be uncomplete. Go on Home - Setup - Modules to complete. ErrorBadMask=Error on mask ErrorBadMaskFailedToLocatePosOfSequence=Error, mask without sequence number diff --git a/htdocs/loan/card.php b/htdocs/loan/card.php index 25651ac842a..e2491167ed8 100644 --- a/htdocs/loan/card.php +++ b/htdocs/loan/card.php @@ -340,19 +340,19 @@ if ($action == 'create') // Accountancy_account_capital print ''.$langs->trans("LoanAccountancyCapitalCode").''; print ''; - print $formaccounting->select_account($object->accountancy_account_capital, 'accountancy_account_capital', 1, '', 0, 1); + print $formaccounting->select_account(GETPOST('accountancy_account_capital')?GETPOST('accountancy_account_capital'):$conf->global->LOAN_ACCOUNTING_ACCOUNT_CAPITAL, 'accountancy_account_capital', 1, '', 1, 1); print ''; // Accountancy_account_insurance print ''.$langs->trans("LoanAccountancyInsuranceCode").''; print ''; - print $formaccounting->select_account($object->accountancy_account_insurance, 'accountancy_account_insurance', 1, '', 0, 1); + print $formaccounting->select_account(GETPOST('accountancy_account_insurance')?GETPOST('accountancy_account_insurance'):$conf->global->LOAN_ACCOUNTING_ACCOUNT_INSURANCE, 'accountancy_account_insurance', 1, '', 1, 1); print ''; // Accountancy_account_interest print ''.$langs->trans("LoanAccountancyInterestCode").''; print ''; - print $formaccounting->select_account($object->accountancy_account_interest, 'accountancy_account_interest', 1, '', 0, 1); + print $formaccounting->select_account(GETPOST('accountancy_account_interest')?GETPOST('accountancy_account_interest'):$conf->global->LOAN_ACCOUNTING_ACCOUNT_INTEREST, 'accountancy_account_interest', 1, '', 1, 1); print ''; } else // For external software diff --git a/htdocs/modulebuilder/template/myobject_card.php b/htdocs/modulebuilder/template/myobject_card.php index 26643bd7c33..81715228033 100644 --- a/htdocs/modulebuilder/template/myobject_card.php +++ b/htdocs/modulebuilder/template/myobject_card.php @@ -99,7 +99,8 @@ include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be inclu // Security check - Protection if external user //if ($user->societe_id > 0) access_forbidden(); //if ($user->societe_id > 0) $socid = $user->societe_id; -//$result = restrictedArea($user, 'mymodule', $object->id); +//$isdraft = (($object->statut == MyObject::STATUS_DRAFT) ? 1 : 0); +//$result = restrictedArea($user, 'mymodule', $object->id, '', '', 'fk_soc', 'rowid', $isdraft); /* diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php index 994edfa823e..ef1d89e5fa5 100644 --- a/htdocs/product/stock/replenish.php +++ b/htdocs/product/stock/replenish.php @@ -112,12 +112,15 @@ if ($action == 'order' && isset($_POST['valid'])) { $linecount = GETPOST('linecount', 'int'); $box = 0; + $errorQty = 0; unset($_POST['linecount']); if ($linecount > 0) { $db->begin(); $suppliers = array(); + require_once DOL_DOCUMENT_ROOT . '/fourn/class/fournisseur.product.class.php'; + $productsupplier = new ProductFournisseur($db); for ($i = 0; $i < $linecount; $i++) { if (GETPOST('choose' . $i, 'alpha') === 'on' && GETPOST('fourn' . $i, 'int') > 0) @@ -127,13 +130,9 @@ if ($action == 'order' && isset($_POST['valid'])) $supplierpriceid = GETPOST('fourn'.$i, 'int'); //get all the parameters needed to create a line $qty = GETPOST('tobuy'.$i, 'int'); - //$desc = GETPOST('desc'.$i, 'alpha'); - $sql = 'SELECT fk_product, fk_soc, ref_fourn'; - $sql .= ', tva_tx, unitprice, remise_percent FROM '; - $sql .= MAIN_DB_PREFIX . 'product_fournisseur_price'; - $sql .= ' WHERE rowid = ' . $supplierpriceid; - $resql = $db->query($sql); - if ($resql && $db->num_rows($resql) > 0) + $idprod=$productsupplier->get_buyprice($supplierpriceid, $qty); + $res=$productsupplier->fetch($idprod); + if ($res && $idprod > 0) { if ($qty) { @@ -141,33 +140,37 @@ if ($action == 'order' && isset($_POST['valid'])) $obj = $db->fetch_object($resql); $line = new CommandeFournisseurLigne($db); $line->qty = $qty; - $line->fk_product = $obj->fk_product; + $line->fk_product = $idprod; - $product = new Product($db); - $product->fetch($obj->fk_product); + //$product = new Product($db); + //$product->fetch($obj->fk_product); if (! empty($conf->global->MAIN_MULTILANGS)) { - $product->getMultiLangs(); + $productsupplier->getMultiLangs(); } - $line->desc = $product->description; + $line->desc = $productsupplier->description; if (! empty($conf->global->MAIN_MULTILANGS)) { // TODO Get desc in language of thirdparty } - $line->tva_tx = $obj->tva_tx; - $line->subprice = $obj->unitprice; - $line->total_ht = $obj->unitprice * $qty; + $line->tva_tx = $productsupplier->vatrate_supplier; + $line->subprice = $productsupplier->fourn_pu; + $line->total_ht = $productsupplier->fourn_pu * $qty; $tva = $line->tva_tx / 100; $line->total_tva = $line->total_ht * $tva; $line->total_ttc = $line->total_ht + $line->total_tva; - $line->remise_percent = $obj->remise_percent; - $line->ref_fourn = $obj->ref_fourn; - $line->type = $product->type; - $line->fk_unit = $product->fk_unit; - $suppliers[$obj->fk_soc]['lines'][] = $line; + $line->remise_percent = $productsupplier->remise_percent; + $line->ref_fourn = $productsupplier->ref_supplier; + $line->type = $productsupplier->type; + $line->fk_unit = $productsupplier->fk_unit; + $suppliers[$productsupplier->fourn_socid]['lines'][] = $line; } } + elseif ($idprod == -1) + { + $errorQty++; + } else { $error=$db->lasterror(); @@ -248,6 +251,8 @@ if ($action == 'order' && isset($_POST['valid'])) } } + if($errorQty) setEventMessages($langs->trans('ErrorOrdersNotCreatedQtyTooLow'), null, 'warnings'); + if (! $fail && $id) { $db->commit(); diff --git a/htdocs/resource/element_resource.php b/htdocs/resource/element_resource.php index a83e37bc0b4..44a993929a7 100644 --- a/htdocs/resource/element_resource.php +++ b/htdocs/resource/element_resource.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2013-2018 Jean-François Ferry * Copyright (C) 2016 Gilles Poirier * * This program is free software: you can redistribute it and/or modify @@ -90,7 +90,7 @@ if ($action == 'add_element_resource' && ! $cancel) else { $objstat = fetchObjectByElement($element_id, $element); - + $objstat->element = $element; // For externals module, we need to keep @xx $res = $objstat->add_element_resource($resource_id, $resource_type, $busy, $mandatory); } if (! $error && $res > 0)