'.$form->textwithpicto($langs->trans("LogoSquarred"), 'png, jpg').' ';
print '';
print ' ';
print ' ';
diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php
index 79d152fb7bf..61fb0448c8b 100644
--- a/htdocs/admin/mails.php
+++ b/htdocs/admin/mails.php
@@ -65,27 +65,27 @@ complete_substitutions_array($substitutionarrayfortest, $langs);
if ($action == 'update' && empty($_POST["cancel"]))
{
- dolibarr_set_const($db, "MAIN_DISABLE_ALL_MAILS", GETPOST("MAIN_DISABLE_ALL_MAILS"), 'chaine', 0, '', $conf->entity);
- dolibarr_set_const($db, "MAIN_MAIL_FORCE_SENDTO", GETPOST("MAIN_MAIL_FORCE_SENDTO"), 'chaine', 0, '', $conf->entity);
- dolibarr_set_const($db, "MAIN_MAIL_ENABLED_USER_DEST_SELECT", GETPOST("MAIN_MAIL_ENABLED_USER_DEST_SELECT"), 'chaine', 0, '', $conf->entity);
+ dolibarr_set_const($db, "MAIN_DISABLE_ALL_MAILS", GETPOST("MAIN_DISABLE_ALL_MAILS", 'int'), 'chaine', 0, '', $conf->entity);
+ dolibarr_set_const($db, "MAIN_MAIL_FORCE_SENDTO", GETPOST("MAIN_MAIL_FORCE_SENDTO", 'alphanohtml'), 'chaine', 0, '', $conf->entity);
+ dolibarr_set_const($db, "MAIN_MAIL_ENABLED_USER_DEST_SELECT", GETPOST("MAIN_MAIL_ENABLED_USER_DEST_SELECT", 'int'), 'chaine', 0, '', $conf->entity);
// Send mode parameters
- dolibarr_set_const($db, "MAIN_MAIL_SENDMODE", GETPOST("MAIN_MAIL_SENDMODE"), 'chaine', 0, '', $conf->entity);
- dolibarr_set_const($db, "MAIN_MAIL_SMTP_PORT", GETPOST("MAIN_MAIL_SMTP_PORT"), 'chaine', 0, '', $conf->entity);
- dolibarr_set_const($db, "MAIN_MAIL_SMTP_SERVER", GETPOST("MAIN_MAIL_SMTP_SERVER"), 'chaine', 0, '', $conf->entity);
- dolibarr_set_const($db, "MAIN_MAIL_SMTPS_ID", GETPOST("MAIN_MAIL_SMTPS_ID"), 'chaine', 0, '', $conf->entity);
- dolibarr_set_const($db, "MAIN_MAIL_SMTPS_PW", GETPOST("MAIN_MAIL_SMTPS_PW"), 'chaine', 0, '', $conf->entity);
- dolibarr_set_const($db, "MAIN_MAIL_EMAIL_TLS", GETPOST("MAIN_MAIL_EMAIL_TLS"), 'chaine', 0, '', $conf->entity);
- dolibarr_set_const($db, "MAIN_MAIL_EMAIL_STARTTLS", GETPOST("MAIN_MAIL_EMAIL_STARTTLS"), 'chaine', 0, '', $conf->entity);
+ dolibarr_set_const($db, "MAIN_MAIL_SENDMODE", GETPOST("MAIN_MAIL_SENDMODE", 'aZ09'), 'chaine', 0, '', $conf->entity);
+ dolibarr_set_const($db, "MAIN_MAIL_SMTP_PORT", GETPOST("MAIN_MAIL_SMTP_PORT", 'int'), 'chaine', 0, '', $conf->entity);
+ dolibarr_set_const($db, "MAIN_MAIL_SMTP_SERVER", GETPOST("MAIN_MAIL_SMTP_SERVER", 'alphanohtml'), 'chaine', 0, '', $conf->entity);
+ dolibarr_set_const($db, "MAIN_MAIL_SMTPS_ID", GETPOST("MAIN_MAIL_SMTPS_ID", 'alphanohtml'), 'chaine', 0, '', $conf->entity);
+ dolibarr_set_const($db, "MAIN_MAIL_SMTPS_PW", GETPOST("MAIN_MAIL_SMTPS_PW", 'none'), 'chaine', 0, '', $conf->entity);
+ dolibarr_set_const($db, "MAIN_MAIL_EMAIL_TLS", GETPOST("MAIN_MAIL_EMAIL_TLS", 'int'), 'chaine', 0, '', $conf->entity);
+ dolibarr_set_const($db, "MAIN_MAIL_EMAIL_STARTTLS", GETPOST("MAIN_MAIL_EMAIL_STARTTLS", 'int'), 'chaine', 0, '', $conf->entity);
- dolibarr_set_const($db, "MAIN_MAIL_EMAIL_DKIM_ENABLED", GETPOST("MAIN_MAIL_EMAIL_DKIM_ENABLED"), 'chaine', 0, '', $conf->entity);
- dolibarr_set_const($db, "MAIN_MAIL_EMAIL_DKIM_DOMAIN", GETPOST("MAIN_MAIL_EMAIL_DKIM_DOMAIN"), 'chaine', 0, '', $conf->entity);
- dolibarr_set_const($db, "MAIN_MAIL_EMAIL_DKIM_SELECTOR", GETPOST("MAIN_MAIL_EMAIL_DKIM_SELECTOR"), 'chaine', 0, '', $conf->entity);
- dolibarr_set_const($db, "MAIN_MAIL_EMAIL_DKIM_PRIVATE_KEY", GETPOST("MAIN_MAIL_EMAIL_DKIM_PRIVATE_KEY"), 'chaine', 0, '', $conf->entity);
+ dolibarr_set_const($db, "MAIN_MAIL_EMAIL_DKIM_ENABLED", GETPOST("MAIN_MAIL_EMAIL_DKIM_ENABLED", 'int'), 'chaine', 0, '', $conf->entity);
+ dolibarr_set_const($db, "MAIN_MAIL_EMAIL_DKIM_DOMAIN", GETPOST("MAIN_MAIL_EMAIL_DKIM_DOMAIN", 'alphanohtml'), 'chaine', 0, '', $conf->entity);
+ dolibarr_set_const($db, "MAIN_MAIL_EMAIL_DKIM_SELECTOR", GETPOST("MAIN_MAIL_EMAIL_DKIM_SELECTOR", 'alphanohtml'), 'chaine', 0, '', $conf->entity);
+ dolibarr_set_const($db, "MAIN_MAIL_EMAIL_DKIM_PRIVATE_KEY", GETPOST("MAIN_MAIL_EMAIL_DKIM_PRIVATE_KEY", 'alphanohtml'), 'chaine', 0, '', $conf->entity);
// Content parameters
- dolibarr_set_const($db, "MAIN_MAIL_EMAIL_FROM", GETPOST("MAIN_MAIL_EMAIL_FROM"), 'chaine', 0, '', $conf->entity);
- dolibarr_set_const($db, "MAIN_MAIL_ERRORS_TO", GETPOST("MAIN_MAIL_ERRORS_TO"), 'chaine', 0, '', $conf->entity);
- dolibarr_set_const($db, "MAIN_MAIL_AUTOCOPY_TO", GETPOST("MAIN_MAIL_AUTOCOPY_TO"), 'chaine', 0, '', $conf->entity);
- dolibarr_set_const($db, 'MAIN_MAIL_DEFAULT_FROMTYPE', GETPOST('MAIN_MAIL_DEFAULT_FROMTYPE'), 'chaine', 0, '', $conf->entity);
+ dolibarr_set_const($db, "MAIN_MAIL_EMAIL_FROM", GETPOST("MAIN_MAIL_EMAIL_FROM", 'alphanohtml'), 'chaine', 0, '', $conf->entity);
+ dolibarr_set_const($db, "MAIN_MAIL_ERRORS_TO", GETPOST("MAIN_MAIL_ERRORS_TO", 'alphanohtml'), 'chaine', 0, '', $conf->entity);
+ dolibarr_set_const($db, "MAIN_MAIL_AUTOCOPY_TO", GETPOST("MAIN_MAIL_AUTOCOPY_TO", 'alphanohtml'), 'chaine', 0, '', $conf->entity);
+ dolibarr_set_const($db, 'MAIN_MAIL_DEFAULT_FROMTYPE', GETPOST('MAIN_MAIL_DEFAULT_FROMTYPE', 'alphanohtml'), 'chaine', 0, '', $conf->entity);
header("Location: ".$_SERVER["PHP_SELF"]."?mainmenu=home&leftmenu=setup");
exit;
@@ -101,8 +101,8 @@ $mode='emailfortest';
$trackid=(($action == 'testhtml')?"testhtml":"test");
include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
-if ($action == 'presend' && GETPOST('trackid') == 'test') $action='test';
-if ($action == 'presend' && GETPOST('trackid') == 'testhtml') $action='testhtml';
+if ($action == 'presend' && GETPOST('trackid', 'alphanohtml') == 'test') $action='test';
+if ($action == 'presend' && GETPOST('trackid', 'alphanohtml') == 'testhtml') $action='testhtml';
@@ -821,7 +821,7 @@ else
$formmail->frommail = (isset($_POST['frommail'])?$_POST['frommail']:$conf->global->MAIN_MAIL_EMAIL_FROM);
$formmail->fromid=$user->id;
$formmail->fromalsorobot=1;
- $formmail->fromtype=(GETPOST('fromtype')?GETPOST('fromtype'):(!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE)?$conf->global->MAIN_MAIL_DEFAULT_FROMTYPE:'user'));
+ $formmail->fromtype=(GETPOSTISSET('fromtype')?GETPOST('fromtype', 'aZ09'):(!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE)?$conf->global->MAIN_MAIL_DEFAULT_FROMTYPE:'user'));
$formmail->withfromreadonly=1;
$formmail->withsubstit=1;
$formmail->withfrom=1;
@@ -847,7 +847,7 @@ else
$formmail->param["returnurl"]=$_SERVER["PHP_SELF"];
// Init list of files
- if (GETPOST("mode")=='init')
+ if (GETPOST("mode", "aZ09")=='init')
{
$formmail->clear_attached_files();
}
diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php
index 7660144f7ca..0247514b2a4 100644
--- a/htdocs/api/class/api.class.php
+++ b/htdocs/api/class/api.class.php
@@ -290,6 +290,7 @@ class DolibarrApi
if (count($tmp) < 3) return '';
$tmpescaped=$tmp[2];
+ $regbis = array();
if (preg_match('/^\'(.*)\'$/', $tmpescaped, $regbis))
{
$tmpescaped = "'".$db->escape($regbis[1])."'";
diff --git a/htdocs/bom/bom_card.php b/htdocs/bom/bom_card.php
index 0949fa1a334..17fae31ef7d 100644
--- a/htdocs/bom/bom_card.php
+++ b/htdocs/bom/bom_card.php
@@ -79,6 +79,7 @@ $permissionnote=$user->rights->bom->write; // Used by the include of actions_set
$permissiondellink=$user->rights->bom->write; // Used by the include of actions_dellink.inc.php
$permissionedit=$user->rights->bom->write; // Used by the include of actions_lineupdown.inc.php
$permissiontoadd=$user->rights->bom->write; // Used by the include of actions_addupdatedelete.inc.php
+$permissiontodelete = $user->rights->bom->delete || ($permissiontoadd && $object->status == 0);
/*
@@ -93,11 +94,11 @@ if (empty($reshook))
{
$error=0;
- $permissiontoadd = $user->rights->bom->write;
- $permissiontodelete = $user->rights->bom->delete || ($permissiontoadd && $object->status == 0);
$backurlforlist = DOL_URL_ROOT.'/bom/bom_list.php';
- if (empty($backtopage)) {
- if (empty($id) && $action != 'add' && $action != 'create') $backtopage = $backurlforlist;
+
+ if (empty($backtopage) || ($cancel && empty($id))) {
+ //var_dump($backurlforlist);exit;
+ if (empty($id) && (($action != 'add' && $action != 'create') || $cancel)) $backtopage = $backurlforlist;
else $backtopage = DOL_URL_ROOT.'/bom/bom_card.php?id='.($id > 0 ? $id : '__ID__');
}
$triggermodname = 'BOM_MODIFY'; // Name of trigger action code to execute when we modify record
@@ -218,7 +219,7 @@ if ($action == 'create')
dol_fiche_head(array(), '');
- print ''."\n";
+ print ''."\n";
// Common attributes
include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_add.tpl.php';
@@ -252,7 +253,9 @@ if (($id || $ref) && $action == 'edit')
dol_fiche_head();
- print ''."\n";
+ //$object->fields['keyfield']['disabled'] = 1;
+
+ print ''."\n";
// Common attributes
include DOL_DOCUMENT_ROOT . '/core/tpl/commonfields_edit.tpl.php';
diff --git a/htdocs/bom/bom_list.php b/htdocs/bom/bom_list.php
index 46473d52ddb..6e192a06545 100644
--- a/htdocs/bom/bom_list.php
+++ b/htdocs/bom/bom_list.php
@@ -454,12 +454,12 @@ while ($i < min($num, $limit))
$cssforfield=(empty($val['css'])?'':$val['css']);
if (in_array($val['type'], array('date','datetime','timestamp'))) $cssforfield.=($cssforfield?' ':'').'center';
elseif ($key == 'status') $cssforfield.=($cssforfield?' ':'').'center';
-
+
if (in_array($val['type'], array('timestamp'))) $cssforfield.=($cssforfield?' ':'').'nowrap';
elseif ($key == 'ref') $cssforfield.=($cssforfield?' ':'').'nowrap';
-
+
if (in_array($val['type'], array('double(24,8)', 'double(6,3)', 'integer', 'real', 'price')) && $key != 'status') $cssforfield.=($cssforfield?' ':'').'right';
-
+
if (! empty($arrayfields['t.'.$key]['checked']))
{
print '';
diff --git a/htdocs/bom/class/api_boms.class.php b/htdocs/bom/class/api_boms.class.php
index f6b25d0cca7..471fb4f2cce 100644
--- a/htdocs/bom/class/api_boms.class.php
+++ b/htdocs/bom/class/api_boms.class.php
@@ -100,7 +100,7 @@ class Boms extends DolibarrApi
$obj_ret = array();
$tmpobject = new BOM($db);
-
+
$socid = DolibarrApiAccess::$user->socid ? DolibarrApiAccess::$user->socid : '';
$restrictonsocid = 0; // Set to 1 if there is a field socid in table of object
diff --git a/htdocs/bom/class/bom.class.php b/htdocs/bom/class/bom.class.php
index 07ae81e2994..02e39149364 100644
--- a/htdocs/bom/class/bom.class.php
+++ b/htdocs/bom/class/bom.class.php
@@ -91,7 +91,7 @@ class BOM extends CommonObject
'ref' => array('type'=>'varchar(128)', 'label'=>'Ref', 'enabled'=>1, 'noteditable'=>1, 'visible'=>4, 'position'=>10, 'notnull'=>1, 'default'=>'(PROV)', 'index'=>1, 'searchall'=>1, 'comment'=>"Reference of BOM", 'showoncombobox'=>'1',),
'label' => array('type'=>'varchar(255)', 'label'=>'Label', 'enabled'=>1, 'visible'=>1, 'position'=>30, 'notnull'=>1, 'searchall'=>1, 'showoncombobox'=>'1',),
'description' => array('type'=>'text', 'label'=>'Description', 'enabled'=>1, 'visible'=>-1, 'position'=>60, 'notnull'=>-1,),
- 'fk_product' => array('type'=>'integer:Product:product/class/product.class.php', 'label'=>'Product', 'enabled'=>1, 'visible'=>1, 'position'=>35, 'notnull'=>1, 'index'=>1, 'help'=>'ProductBOMHelp'),
+ 'fk_product' => array('type'=>'integer:Product:product/class/product.class.php:1', 'label'=>'Product', 'enabled'=>1, 'visible'=>1, 'position'=>35, 'notnull'=>1, 'index'=>1, 'help'=>'ProductBOMHelp'),
'qty' => array('type'=>'real', 'label'=>'Quantity', 'enabled'=>1, 'visible'=>1, 'default'=>1, 'position'=>55, 'notnull'=>1, 'isameasure'=>'1', 'css'=>'maxwidth75imp'),
'efficiency' => array('type'=>'real', 'label'=>'ManufacturingEfficiency', 'enabled'=>1, 'visible'=>-1, 'default'=>1, 'position'=>100, 'notnull'=>0, 'css'=>'maxwidth50imp', 'help'=>'ValueOfMeansLoss'),
'duration' => array('type'=>'real', 'label'=>'EstimatedDuration', 'enabled'=>1, 'visible'=>-1, 'position'=>101, 'notnull'=>-1, 'css'=>'maxwidth50imp', 'help'=>'EstimatedDurationDesc'),
diff --git a/htdocs/bom/tpl/objectline_view.tpl.php b/htdocs/bom/tpl/objectline_view.tpl.php
index f569516e535..f68372c721d 100644
--- a/htdocs/bom/tpl/objectline_view.tpl.php
+++ b/htdocs/bom/tpl/objectline_view.tpl.php
@@ -92,9 +92,9 @@ $coldisplay++;
echo $line->efficiency;
print ' ';
-if ($this->statut == 0 && ($object_rights->write) && $action != 'selectlines' ) {
- print '';
- $coldisplay++;
+if ($this->status == 0 && ($object_rights->write) && $action != 'selectlines' ) {
+ print ' ';
+ $coldisplay++;
if (($line->info_bits & 2) == 2 || ! empty($disableedit)) {
} else {
print 'id.'&action=editline&lineid='.$line->id.'#line_'.$line->id.'">'.img_edit().' ';
diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php
index 1314463cd2a..871ec6b9ed2 100644
--- a/htdocs/comm/action/class/actioncomm.class.php
+++ b/htdocs/comm/action/class/actioncomm.class.php
@@ -1543,7 +1543,7 @@ class ActionComm extends CommonObject
$event['uid']='dolibarragenda-'.$this->db->database_name.'-'.$obj->id."@".$_SERVER["SERVER_NAME"];
$event['type']=$type;
$datestart=$this->db->jdate($obj->datep)-(empty($conf->global->AGENDA_EXPORT_FIX_TZ)?0:($conf->global->AGENDA_EXPORT_FIX_TZ*3600));
-
+
// fix for -> Warning: A non-numeric value encountered
if(is_numeric($this->db->jdate($obj->datep2)))
{
diff --git a/htdocs/comm/mailing/info.php b/htdocs/comm/mailing/info.php
index 0dbc6fc07ab..7b270e460c8 100644
--- a/htdocs/comm/mailing/info.php
+++ b/htdocs/comm/mailing/info.php
@@ -58,11 +58,11 @@ if ($object->fetch($id) >= 0)
$morehtmlright='';
if ($object->statut == 2) $morehtmlright.=' ('.$object->countNbOfTargets('alreadysent').'/'.$object->nbemail.') ';
-
+
dol_banner_tab($object, 'id', $linkback, 1, 'rowid', 'ref', '', '', 0, '', $morehtmlright);
-
+
print '
';
-
+
//print '';
$object->user_creation=$object->user_creat;
$object->date_creation=$object->date_creat;
@@ -70,7 +70,7 @@ if ($object->fetch($id) >= 0)
$object->date_validation=$object->date_valid;
dol_print_object_info($object, 0);
//print '
';
-
+
dol_fiche_end();
}
diff --git a/htdocs/compta/deplacement/info.php b/htdocs/compta/deplacement/info.php
index a0accd11a87..510675265a0 100644
--- a/htdocs/compta/deplacement/info.php
+++ b/htdocs/compta/deplacement/info.php
@@ -47,15 +47,15 @@ if ($id)
$object = new Deplacement($db);
$object->fetch($id);
$object->info($id);
-
+
$head = trip_prepare_head($object);
-
+
dol_fiche_head($head, 'info', $langs->trans("TripCard"), 0, 'trip');
print '';
dol_print_object_info($object);
print '
';
-
+
print '';
}
diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php
index f264bb074b3..fe88c9ec717 100644
--- a/htdocs/compta/facture/card.php
+++ b/htdocs/compta/facture/card.php
@@ -278,8 +278,11 @@ if (empty($reshook))
$action = '';
}
} else {
- // Si non avoir, le signe doit etre positif
- if (empty($conf->global->FACTURE_ENABLE_NEGATIVE) && $object->total_ht < 0) {
+ // If not a credit note, amount with tax must be positive or nul.
+ // Note that amount excluding tax can be negative because you can have a invoice of 100 with vat of 20 that
+ // consumes a credit note of 100 with vat 0 (total with tax is 0 but without tax is -20).
+ // For some cases, credit notes can have a vat of 0 (for example when selling goods in France).
+ if (empty($conf->global->FACTURE_ENABLE_NEGATIVE) && $object->total_ttc < 0) {
setEventMessages($langs->trans("ErrorInvoiceOfThisTypeMustBePositive"), null, 'errors');
$action = '';
}
@@ -2563,6 +2566,7 @@ $form = new Form($db);
$formother = new FormOther($db);
$formfile = new FormFile($db);
$formmargin = new FormMargin($db);
+$soc = new Societe($db);
$paymentstatic=new Paiement($db);
$bankaccountstatic = new Account($db);
if (! empty($conf->projet->enabled)) { $formproject = new FormProjets($db); }
@@ -2583,7 +2587,6 @@ if ($action == 'create')
print load_fiche_titre($langs->trans('NewBill'), '', 'invoicing');
- $soc = new Societe($db);
if ($socid > 0)
$res = $soc->fetch($socid);
@@ -3462,7 +3465,6 @@ elseif ($id > 0 || ! empty($ref))
$result = $object->fetch_thirdparty();
- $soc = new Societe($db);
$result=$soc->fetch($object->socid);
if ($result < 0) dol_print_error($db);
$selleruserevenustamp = $mysoc->useRevenueStamp();
diff --git a/htdocs/compta/paiement/class/cpaiement.class.php b/htdocs/compta/paiement/class/cpaiement.class.php
index a4e115dfdb0..37614f7e36e 100644
--- a/htdocs/compta/paiement/class/cpaiement.class.php
+++ b/htdocs/compta/paiement/class/cpaiement.class.php
@@ -34,7 +34,7 @@ class Cpaiement
* @var string Id to identify managed objects
*/
public $element = 'cpaiement';
-
+
/**
* @var string Name of table without prefix where object is stored
*/
diff --git a/htdocs/compta/tva/document.php b/htdocs/compta/tva/document.php
index 46cd0e281a5..d26d8954cc4 100644
--- a/htdocs/compta/tva/document.php
+++ b/htdocs/compta/tva/document.php
@@ -114,7 +114,7 @@ if ($object->id)
$morehtmlref.=$form->editfieldval("Label", 'lib', $object->label, $object, $user->rights->tax->charges->creer, 'string', '', null, null, '', 1);
$morehtmlref.='';
- $linkback = '' . $langs->trans("BackToList") . ' ';
+ $linkback = '' . $langs->trans("BackToList") . ' ';
$object->totalpaye = $totalpaye; // To give a chance to dol_banner_tab to use already paid amount to show correct status
diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php
index a17f6f27259..3465b3478a0 100644
--- a/htdocs/contact/class/contact.class.php
+++ b/htdocs/contact/class/contact.class.php
@@ -628,7 +628,7 @@ class Contact extends CommonObject
if ($this->birthday_alert)
{
//check existing
- $sql_check = "SELECT * FROM ".MAIN_DB_PREFIX."user_alert WHERE type=1 AND fk_contact=".$this->db->escape($id)." AND fk_user=".$user->id;
+ $sql_check = "SELECT rowid FROM ".MAIN_DB_PREFIX."user_alert WHERE type=1 AND fk_contact=".$this->db->escape($id)." AND fk_user=".$user->id;
$result_check = $this->db->query($sql_check);
if (! $result_check || ($this->db->num_rows($result_check)<1))
{
diff --git a/htdocs/core/actions_addupdatedelete.inc.php b/htdocs/core/actions_addupdatedelete.inc.php
index e87333e4c01..d618a0702c8 100644
--- a/htdocs/core/actions_addupdatedelete.inc.php
+++ b/htdocs/core/actions_addupdatedelete.inc.php
@@ -32,6 +32,8 @@
if ($cancel)
{
+ /*var_dump($cancel);
+ var_dump($backtopage);exit;*/
if (! empty($backtopage))
{
header("Location: ".$backtopage);
@@ -80,7 +82,8 @@ if ($action == 'add' && ! empty($permissiontoadd))
if ($result > 0)
{
// Creation OK
- $urltogo=$backtopage?str_replace('__ID__', $result, $backtopage):$backurlforlist;
+ $urltogo = $backtopage ? str_replace('__ID__', $result, $backtopage) : $backurlforlist;
+ $urltogo = preg_replace('/--IDFORBACKTOPAGE--/', $object->id, $urltogo); // New method to autoselect project after a New on another form object creation
header("Location: ".$urltogo);
exit;
}
diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php
index c81c013bc08..7d8d621ff92 100644
--- a/htdocs/core/actions_massactions.inc.php
+++ b/htdocs/core/actions_massactions.inc.php
@@ -71,7 +71,9 @@ if (! $error && $massaction == 'confirm_presend')
$listofobjectid=array();
$listofobjectthirdparties=array();
+ $listofobjectcontacts = array();
$listofobjectref=array();
+ $contactidtosend=array();
$attachedfilesThirdpartyObj=array();
$oneemailperrecipient=(GETPOST('oneemailperrecipient')=='on'?1:0);
@@ -97,11 +99,21 @@ if (! $error && $massaction == 'confirm_presend')
if ($objecttmp->element == 'holiday') $thirdpartyid=$objecttmp->fk_user;
if (empty($thirdpartyid)) $thirdpartyid=0;
- $listofobjectthirdparties[$thirdpartyid]=$thirdpartyid;
- $listofobjectref[$thirdpartyid][$toselectid]=$objecttmp;
- }
- }
- }
+ if ($objectclass == 'Facture') {
+ $tmparraycontact = array();
+ $tmparraycontact = $objecttmp->liste_contact(-1, 'external', 0, 'BILLING');
+ if (is_array($tmparraycontact) && count($tmparraycontact) > 0) {
+ foreach ($tmparraycontact as $data_email) {
+ $listofobjectcontacts[$toselectid][$data_email['id']] = $data_email['email'];
+ }
+ }
+ }
+
+ $listofobjectthirdparties[$thirdpartyid]=$thirdpartyid;
+ $listofobjectref[$thirdpartyid][$toselectid]=$objecttmp;
+ }
+ }
+ }
// Check mandatory parameters
if (GETPOST('fromtype', 'alpha') === 'user' && empty($user->email))
@@ -248,6 +260,21 @@ if (! $error && $massaction == 'confirm_presend')
$fuser->fetch($objectobj->fk_user);
$sendto = $fuser->email;
}
+ elseif ($objectobj->element == 'facture' && !empty($listofobjectcontacts[$objectid]))
+ {
+ $emails_to_sends = array();
+ $objectobj->fetch_thirdparty();
+ $contactidtosend=array();
+ foreach ($listofobjectcontacts[$objectid] as $contactemailid => $contactemailemail) {
+ $emails_to_sends[] = $objectobj->thirdparty->contact_get_property($contactemailid, 'email');
+ if (!in_array($contactemailid, $contactidtosend)) {
+ $contactidtosend[] = $contactemailid;
+ }
+ }
+ if (count($emails_to_sends) > 0) {
+ $sendto = implode(',', $emails_to_sends);
+ }
+ }
else
{
$objectobj->fetch_thirdparty();
@@ -498,8 +525,8 @@ if (! $error && $massaction == 'confirm_presend')
}
$actionmsg2='';
- // Initialisation donnees
- $objectobj2->sendtoid = 0;
+ // Initialisation donnees
+ $objectobj2->sendtoid = (empty($contactidtosend)?0:$contactidtosend);
$objectobj2->actionmsg = $actionmsg; // Long text
$objectobj2->actionmsg2 = $actionmsg2; // Short text
$objectobj2->fk_element = $objid2;
diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php
index cc8ae3238c0..abd8e38ce97 100644
--- a/htdocs/core/class/commonobject.class.php
+++ b/htdocs/core/class/commonobject.class.php
@@ -5556,16 +5556,20 @@ abstract class CommonObject
$type='';
$param = array();
$param['options']=array();
- $size =$this->fields[$key]['size'];
+ $reg=array();
+ $size = $this->fields[$key]['size'];
// Because we work on extrafields
- if(preg_match('/^integer:(.*):(.*)/i', $val['type'], $reg)){
- $param['options']=array($reg[1].':'.$reg[2]=>'N');
- $type ='link';
- } elseif(preg_match('/^link:(.*):(.*)/i', $val['type'], $reg)) {
- $param['options']=array($reg[1].':'.$reg[2]=>'N');
+ if (preg_match('/^(integer|link):(.*):(.*):(.*):(.*)/i', $val['type'], $reg)){
+ $param['options']=array($reg[2].':'.$reg[3].':'.$reg[4].':'.$reg[5] => 'N');
+ $type ='link';
+ } elseif (preg_match('/^(integer|link):(.*):(.*):(.*)/i', $val['type'], $reg)){
+ $param['options']=array($reg[2].':'.$reg[3].':'.$reg[4] => 'N');
+ $type ='link';
+ } elseif (preg_match('/^(integer|link):(.*):(.*)/i', $val['type'], $reg)){
+ $param['options']=array($reg[2].':'.$reg[3] => 'N');
$type ='link';
} elseif(preg_match('/^sellist:(.*):(.*):(.*):(.*)/i', $val['type'], $reg)) {
- $param['options']=array($reg[1].':'.$reg[2].':'.$reg[3].':'.$reg[4]=>'N');
+ $param['options']=array($reg[1].':'.$reg[2].':'.$reg[3].':'.$reg[4] => 'N');
$type ='sellist';
} elseif(preg_match('/varchar\((\d+)\)/', $val['type'], $reg)) {
$param['options']=array();
@@ -6078,16 +6082,26 @@ abstract class CommonObject
}
elseif ($type == 'link')
{
- $param_list=array_keys($param['options']); // $param_list='ObjectName:classPath'
+ $param_list=array_keys($param['options']); // $param_list='ObjectName:classPath[:AddCreateButtonOrNot[:Filter]]'
+ $param_list_array = explode(':', $param_list[0]);
$showempty=(($required && $default != '')?0:1);
- $out=$form->selectForForms($param_list[0], $keyprefix.$key.$keysuffix, $value, $showempty);
- if ($conf->global->MAIN_FEATURES_LEVEL >= 2)
+
+ $out=$form->selectForForms($param_list[0], $keyprefix.$key.$keysuffix, $value, $showempty, '', '', '', '', 0, empty($val['disabled'])?0:1);
+
+ if (! empty($param_list_array[2])) // If we set to add a create button
{
- list($class,$classfile)=explode(':', $param_list[0]);
- if (file_exists(dol_buildpath(dirname(dirname($classfile)).'/card.php'))) $url_path=dol_buildpath(dirname(dirname($classfile)).'/card.php', 1);
- else $url_path=dol_buildpath(dirname(dirname($classfile)).'/'.$class.'_card.php', 1);
- $out.=' ';
- // TODO Add Javascript code to add input fields contents to new elements urls
+ if (! GETPOSTISSET('backtopage') && empty($val['disabled'])) // To avoid to open several infinitely the 'Create Object' button and to avoid to have button if field is protected by a "disabled".
+ {
+ list($class,$classfile)=explode(':', $param_list[0]);
+ if (file_exists(dol_buildpath(dirname(dirname($classfile)).'/card.php'))) $url_path=dol_buildpath(dirname(dirname($classfile)).'/card.php', 1);
+ else $url_path=dol_buildpath(dirname(dirname($classfile)).'/'.strtolower($class).'_card.php', 1);
+ $paramforthenewlink = '';
+ $paramforthenewlink .= (GETPOSTISSET('action')?'&action='.GETPOST('action', 'aZ09'):'');
+ $paramforthenewlink .= (GETPOSTISSET('id')?'&id='.GETPOST('id', 'int'):'');
+ $paramforthenewlink .= '&fk_'.strtolower($class).'=--IDFORBACKTOPAGE--';
+ // TODO Add Javascript code to add input fields already filled into $paramforthenewlink so we won't loose them when going back to main page
+ $out.=' ';
+ }
}
}
elseif ($type == 'password')
@@ -6167,6 +6181,7 @@ abstract class CommonObject
$label = $val['label'];
$type = $val['type'];
$size = $val['css'];
+ $reg = array();
// Convert var to be able to share same code than showOutputField of extrafields
if (preg_match('/varchar\((\d+)\)/', $type, $reg))
@@ -6182,7 +6197,9 @@ abstract class CommonObject
$computed=$val['computed'];
$unique=$val['unique'];
$required=$val['required'];
- $param=$val['param'];
+ $param=array();
+ $param['options']=array();
+
if (is_array($val['arrayofkeyval'])) $param['options'] = $val['arrayofkeyval'];
if (preg_match('/^integer:(.*):(.*)/i', $val['type'], $reg))
{
diff --git a/htdocs/core/class/cunits.class.php b/htdocs/core/class/cunits.class.php
index 1837f82a2a4..07cd778d3a0 100644
--- a/htdocs/core/class/cunits.class.php
+++ b/htdocs/core/class/cunits.class.php
@@ -234,8 +234,6 @@ class CUnits // extends CommonObject
dol_syslog(__METHOD__, LOG_DEBUG);
- $records=array();
-
$sql = 'SELECT';
$sql.= " t.rowid,";
$sql.= " t.code,";
@@ -273,6 +271,7 @@ class CUnits // extends CommonObject
if (!empty($limit)) {
$sql .= ' ' . $this->db->plimit($limit, $offset);
}
+
$resql = $this->db->query($sql);
if ($resql) {
$this->records=array();
diff --git a/htdocs/core/class/discount.class.php b/htdocs/core/class/discount.class.php
index ab1448bc412..71c0566f352 100644
--- a/htdocs/core/class/discount.class.php
+++ b/htdocs/core/class/discount.class.php
@@ -91,13 +91,15 @@ class DiscountAbsolute
public $fk_facture;
/**
- * @var int ID credit note having caused the discount
+ * @var int ID credit note or deposit used to create the discount
*/
public $fk_facture_source;
+ public $ref_facture_source; // Ref credit note or deposit used to create the discount
+ public $type_facture_source;
- public $ref_facture_source; // Ref credit note having caused the discount
-
- public $ref_invoice_supplier_source;
+ public $fk_invoice_supplier_source;
+ public $ref_invoice_supplier_source; // Ref credit note or deposit used to create the discount
+ public $type_invoice_supplier_source;
/**
* Constructor
@@ -135,11 +137,12 @@ class DiscountAbsolute
$sql.= " sr.multicurrency_amount_ht, sr.multicurrency_amount_tva, sr.multicurrency_amount_ttc,";
$sql.= " sr.fk_facture_line, sr.fk_facture, sr.fk_facture_source, sr.fk_invoice_supplier_line, sr.fk_invoice_supplier, sr.fk_invoice_supplier_source, sr.description,";
$sql.= " sr.datec,";
- $sql.= " f.ref as ref_facture_source, fsup.ref as ref_invoice_supplier_source";
+ $sql.= " f.ref as ref_facture_source, f.type as type_facture_source,";
+ $sql.= " fsup.ref as ref_invoice_supplier_source, fsup.type as type_invoice_supplier_source";
$sql.= " FROM ".MAIN_DB_PREFIX."societe_remise_except as sr";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON sr.fk_facture_source = f.rowid";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as fsup ON sr.fk_invoice_supplier_source = fsup.rowid";
- $sql.= " WHERE sr.entity IN (".getEntity('invoice').")";
+ $sql.= " WHERE sr.entity IN (".getEntity('invoice').")";
if ($rowid) $sql.= " AND sr.rowid=".$rowid;
if ($fk_facture_source) $sql.= " AND sr.fk_facture_source=".$fk_facture_source;
if ($fk_invoice_supplier_source) $sql.= " AND sr.fk_invoice_supplier_source=".$fk_invoice_supplier_source;
@@ -168,12 +171,14 @@ class DiscountAbsolute
$this->fk_user = $obj->fk_user;
$this->fk_facture_line = $obj->fk_facture_line;
$this->fk_facture = $obj->fk_facture;
- $this->fk_facture_source = $obj->fk_facture_source; // Id avoir source
- $this->ref_facture_source = $obj->ref_facture_source; // Ref avoir source
+ $this->fk_facture_source = $obj->fk_facture_source; // Id credit note or deposit source
+ $this->ref_facture_source = $obj->ref_facture_source; // Ref credit note or deposit source
+ $this->type_facture_source = $obj->type_facture_source; // Type credit note or deposit source
$this->fk_invoice_supplier_line = $obj->fk_invoice_supplier_line;
$this->fk_invoice_supplier = $obj->fk_invoice_supplier;
- $this->fk_invoice_supplier_source = $obj->fk_invoice_supplier_source; // Id avoir source
- $this->ref_invoice_supplier_source = $obj->ref_invoice_supplier_source; // Ref avoir source
+ $this->fk_invoice_supplier_source = $obj->fk_invoice_supplier_source; // Id credit note or deposit source
+ $this->ref_invoice_supplier_source = $obj->ref_invoice_supplier_source; // Ref credit note or deposit source
+ $this->type_invoice_supplier_source = $obj->type_invoice_supplier_source; // Type credit note or deposit source
$this->description = $obj->description;
$this->datec = $this->db->jdate($obj->datec);
@@ -688,7 +693,7 @@ class DiscountAbsolute
if ($option == 'invoice') {
$facid=! empty($this->discount_type)?$this->fk_invoice_supplier_source:$this->fk_facture_source;
$link=! empty($this->discount_type)?'/fourn/facture/card.php':'/compta/facture/card.php';
- $label=$langs->trans("ShowDiscount").': '.$this->ref_facture_source;
+ $label=$langs->trans("ShowSourceInvoice").': '.$this->ref_facture_source;
$link = '';
$linkend=' ';
$ref=! empty($this->discount_type)?$this->ref_invoice_supplier_source:$this->ref_facture_source;
diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
index 61558434105..b4c52117ea9 100644
--- a/htdocs/core/class/html.form.class.php
+++ b/htdocs/core/class/html.form.class.php
@@ -5614,7 +5614,7 @@ class Form
};
var d = new Date();";
}
-
+
// Generate the date part, depending on the use or not of the javascript calendar
if($addnowlink==1) // server time expressed in user time setup
{
@@ -5815,7 +5815,7 @@ class Form
* Generic method to select a component from a combo list.
* This is the generic method that will replace all specific existing methods.
*
- * @param string $objectdesc Objectclassname:Objectclasspath
+ * @param string $objectdesc ObjectClass:PathToClass[:AddCreateButtonOrNot[:Filter]]
* @param string $htmlname Name of HTML select component
* @param int $preselectedvalue Preselected value (ID of element)
* @param string $showempty ''=empty values not allowed, 'string'=value show if we allow empty values (for example 'All', ...)
@@ -5824,10 +5824,11 @@ class Form
* @param string $morecss More CSS
* @param string $moreparams More params provided to ajax call
* @param int $forcecombo Force to load all values and output a standard combobox (with no beautification)
+ * @param int $disabled 1=Html component is disabled
* @return string Return HTML string
* @see selectForFormsList() select_thirdparty
*/
- public function selectForForms($objectdesc, $htmlname, $preselectedvalue, $showempty = '', $searchkey = '', $placeholder = '', $morecss = '', $moreparams = '', $forcecombo = 0)
+ public function selectForForms($objectdesc, $htmlname, $preselectedvalue, $showempty = '', $searchkey = '', $placeholder = '', $morecss = '', $moreparams = '', $forcecombo = 0, $disabled = 0)
{
global $conf, $user;
@@ -5836,12 +5837,16 @@ class Form
$InfoFieldList = explode(":", $objectdesc);
$classname=$InfoFieldList[0];
$classpath=$InfoFieldList[1];
+ $addcreatebuttonornot=empty($InfoFieldList[2])?0:$InfoFieldList[2];
+ $filter=empty($InfoFieldList[3])?'':$InfoFieldList[3];
+
if (! empty($classpath))
{
dol_include_once($classpath);
if ($classname && class_exists($classname))
{
$objecttmp = new $classname($this->db);
+ $objecttmp->filter = $filter;
}
}
if (! is_object($objecttmp))
@@ -5854,12 +5859,12 @@ class Form
if ($prefixforautocompletemode == 'societe') $prefixforautocompletemode='company';
$confkeyforautocompletemode=strtoupper($prefixforautocompletemode).'_USE_SEARCH_TO_SELECT'; // For example COMPANY_USE_SEARCH_TO_SELECT
- dol_syslog(get_class($this)."::selectForForms", LOG_DEBUG);
+ dol_syslog(get_class($this)."::selectForForms object->filter=".$objecttmp->filter, LOG_DEBUG);
$out='';
if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->$confkeyforautocompletemode) && ! $forcecombo)
{
- $objectdesc=$classname.':'.$classpath;
+ $objectdesc=$classname.':'.$classpath.':'.$addcreatebuttonornot.':'.$filter;
$urlforajaxcall = DOL_URL_ROOT.'/core/ajax/selectobject.php';
// No immediate load of all database
@@ -5868,22 +5873,50 @@ class Form
$out.= ajax_autocompleter($preselectedvalue, $htmlname, $urlforajaxcall, $urloption, $conf->global->$confkeyforautocompletemode, 0, array());
$out.= '';
if ($placeholder) $placeholder=' placeholder="'.$placeholder.'"';
- $out.= ' ';
+ $out.= ' ';
}
else
{
- // Immediate load of all database
- $out.=$this->selectForFormsList($objecttmp, $htmlname, $preselectedvalue, $showempty, $searchkey, $placeholder, $morecss, $moreparams, $forcecombo);
+ // Immediate load of table record. Note: filter is inside $objecttmp->filter
+ $out.=$this->selectForFormsList($objecttmp, $htmlname, $preselectedvalue, $showempty, $searchkey, $placeholder, $morecss, $moreparams, $forcecombo, 0, $disabled);
}
return $out;
}
+ /**
+ * Function to forge a SQL criteria
+ *
+ * @param array $matches Array of found string by regex search. Example: "t.ref:like:'SO-%'" or "t.date_creation:<:'20160101'" or "t.nature:is:NULL"
+ * @return string Forged criteria. Example: "t.field like 'abc%'"
+ */
+ protected static function forgeCriteriaCallback($matches)
+ {
+ global $db;
+
+ //dol_syslog("Convert matches ".$matches[1]);
+ if (empty($matches[1])) return '';
+ $tmp=explode(':', $matches[1]);
+ if (count($tmp) < 3) return '';
+
+ $tmpescaped=$tmp[2];
+ $regbis = array();
+ if (preg_match('/^\'(.*)\'$/', $tmpescaped, $regbis))
+ {
+ $tmpescaped = "'".$db->escape($regbis[1])."'";
+ }
+ else
+ {
+ $tmpescaped = $db->escape($tmpescaped);
+ }
+ return $db->escape($tmp[0]).' '.strtoupper($db->escape($tmp[1]))." ".$tmpescaped;
+ }
+
/**
* Output html form to select an object.
* Note, this function is called by selectForForms or by ajax selectobject.php
*
- * @param Object $objecttmp Object
+ * @param Object $objecttmp Object to knwo the table to scan for combo.
* @param string $htmlname Name of HTML select component
* @param int $preselectedvalue Preselected value (ID of element)
* @param string $showempty ''=empty values not allowed, 'string'=value show if we allow empty values (for example 'All', ...)
@@ -5893,13 +5926,16 @@ class Form
* @param string $moreparams More params provided to ajax call
* @param int $forcecombo Force to load all values and output a standard combobox (with no beautification)
* @param int $outputmode 0=HTML select string, 1=Array
+ * @param int $disabled 1=Html component is disabled
* @return string Return HTML string
* @see selectForForms()
*/
- public function selectForFormsList($objecttmp, $htmlname, $preselectedvalue, $showempty = '', $searchkey = '', $placeholder = '', $morecss = '', $moreparams = '', $forcecombo = 0, $outputmode = 0)
+ public function selectForFormsList($objecttmp, $htmlname, $preselectedvalue, $showempty = '', $searchkey = '', $placeholder = '', $morecss = '', $moreparams = '', $forcecombo = 0, $outputmode = 0, $disabled = 0)
{
global $conf, $langs, $user;
+ //print "$objecttmp->filter, $htmlname, $preselectedvalue, $showempty = '', $searchkey = '', $placeholder = '', $morecss = '', $moreparams = '', $forcecombo = 0, $outputmode = 0, $disabled";
+
$prefixforautocompletemode=$objecttmp->element;
if ($prefixforautocompletemode == 'societe') $prefixforautocompletemode='company';
$confkeyforautocompletemode=strtoupper($prefixforautocompletemode).'_USE_SEARCH_TO_SELECT'; // For example COMPANY_USE_SEARCH_TO_SELECT
@@ -5923,19 +5959,28 @@ class Form
// Search data
$sql = "SELECT t.rowid, ".$fieldstoshow." FROM ".MAIN_DB_PREFIX .$objecttmp->table_element." as t";
if ($objecttmp->ismultientitymanaged == 2)
- if (!$user->rights->societe->client->voir && !$user->societe_id) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
+ if (!$user->rights->societe->client->voir && !$user->socid) $sql .= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc";
$sql.= " WHERE 1=1";
if(! empty($objecttmp->ismultientitymanaged)) $sql.= " AND t.entity IN (".getEntity($objecttmp->table_element).")";
- if ($objecttmp->ismultientitymanaged == 1 && ! empty($user->societe_id))
- {
- if ($objecttmp->element == 'societe') $sql.= " AND t.rowid = ".$user->societe_id;
- else $sql.= " AND t.fk_soc = ".$user->societe_id;
+ if ($objecttmp->ismultientitymanaged == 1 && ! empty($user->socid)) {
+ if ($objecttmp->element == 'societe') $sql.= " AND t.rowid = ".$user->socid;
+ else $sql.= " AND t.fk_soc = ".$user->socid;
}
if ($searchkey != '') $sql.=natural_search(explode(',', $fieldstoshow), $searchkey);
- if ($objecttmp->ismultientitymanaged == 2)
- if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= " AND t.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
+ if ($objecttmp->ismultientitymanaged == 2) {
+ if (!$user->rights->societe->client->voir && !$user->socid) $sql.= " AND t.rowid = sc.fk_soc AND sc.fk_user = " .$user->id;
+ }
+ if ($objecttmp->filter) { // Syntax example "(t.ref:like:'SO-%') and (t.date_creation:<:'20160101')"
+ /*if (! DolibarrApi::_checkFilters($objecttmp->filter))
+ {
+ throw new RestException(503, 'Error when validating parameter sqlfilters '.$objecttmp->filter);
+ }*/
+ $regexstring='\(([^:\'\(\)]+:[^:\'\(\)]+:[^:\(\)]+)\)';
+ $sql.=" AND (".preg_replace_callback('/'.$regexstring.'/', 'Form::forgeCriteriaCallback', $objecttmp->filter).")";
+ }
$sql.=$this->db->order($fieldstoshow, "ASC");
//$sql.=$this->db->plimit($limit, 0);
+ //print $sql;
// Build output string
$resql=$this->db->query($sql);
@@ -5948,7 +5993,7 @@ class Form
}
// Construct $out and $outarray
- $out.= ''."\n";
+ $out.= ''."\n";
// Warning: Do not use textifempty = ' ' or ' ' here, or search on key will search on ' key'. Seems it is no more true with selec2 v4
$textifempty=' ';
diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php
index 8a0341135c7..82bfe17bf69 100644
--- a/htdocs/core/class/html.formfile.class.php
+++ b/htdocs/core/class/html.formfile.class.php
@@ -231,10 +231,10 @@ class FormFile
if (empty($usewithoutform))
{
- $out .= '