diff --git a/ChangeLog b/ChangeLog
index 1235a85e097..7823d4cefb1 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -17,8 +17,48 @@ Following changes may create regressions for some external modules, but were nec
__PROPALREF__, ...)
+***** ChangeLog for 6.0.1 compared to 6.0.* *****
+FIX: #7000 Dashboard link for late pending payment supplier invoices do not work
+FIX: #7325 Default VAT rate when editing template invoices is 0%
+FIX: #7330
+FIX: #7359
+FIX: #7367
+FIX: #7368
+FIX: #7391
+FIX: #7420
+FIX: Add some missing attributes in Adherent:makeSubstitution (type, phone…
+FIX: Bad const name
+FIX: Bad link to unpayed suppliers invoices
+FIX: Better protection to no send email when we change limit
+FIX: Calculation in the activity box
+FIX: Clean bad parameters when inserting line of template invoice
+FIX: dateSelector was not taken into account
+FIX: hidden option MAIN_PROPAGATE_CONTACTS_FROM_ORIGIN
+FIX: journalization for bank journal should not rely on a label.
+FIX: menu enty when url is external link
+FIX: missing supplier qty and supplier discount in available fields for product export.
+FIX: multicompany better accuracy in rounding and with revenue stamp.
+FIX: Must use pdf format page as default for merging PDF.
+FIX: PDF output was sharing 2 different currencies in same total
+FIX: Position of signature on strato template
+FIX: Protection to avoid to apply credit note discount > remain to pay
+FIX: Remove warning when using log into syslog
+FIX: Responsive
+FIX: Security fixes (filter onload js, less verbose error message in
+FIX: SEPA recording payment must save one payment in bank per customer
+FIX: Several problem with the last event box on project/tasks
+FIX: Sign of amount in origin currency on credit note created from lines
+FIX: Some page of admin were not responsive
+FIX: SQL injection
+FIX: time.php crashed without project id in param
+FIX: transfer of line extrafields from order to invoice
+FIX: Upgrade missing on field
+FIX: View of timespent for another user
+FIX: ODT generation
+FIX: CVE-2017-9840, CVE-2017-14238, CVE-2017-14239, CVE-2017-14240, CVE-2017-14241,
+ CVE-2017-14242
+
***** ChangeLog for 6.0.0 compared to 5.0.* *****
-
NEW: Add experimental BlockeLog module (to log business events in a non reversible log file).
NEW: Add a payment module for Stripe.
NEW: Add module "Product variant" (like red, blue for the product shoes)
diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php
index bb67ec46468..b2bb56b14b5 100644
--- a/htdocs/adherents/card.php
+++ b/htdocs/adherents/card.php
@@ -121,14 +121,22 @@ $hookmanager->initHooks(array('membercard','globalcard'));
* Actions
*/
-if ($cancel) $action='';
-
$parameters=array('id'=>$id, 'rowid'=>$id, 'objcanvas'=>$objcanvas);
$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 ($cancel)
+ {
+ if (! empty($backtopage))
+ {
+ header("Location: ".$backtopage);
+ exit;
+ }
+ $action='';
+ }
+
if ($action == 'setuserid' && ($user->rights->user->self->creer || $user->rights->user->user->creer))
{
$error=0;
@@ -230,6 +238,7 @@ if (empty($reshook))
}
}
+ /*
if ($action == 'confirm_sendinfo' && $confirm == 'yes')
{
if ($object->email)
@@ -242,7 +251,7 @@ if (empty($reshook))
$langs->load("mails");
setEventMessages($langs->trans("MailSuccessfulySent", $from, $object->email), null, 'mesgs');
}
- }
+ }*/
if ($action == 'update' && ! $cancel && $user->rights->adherent->creer)
{
@@ -715,10 +724,21 @@ if (empty($reshook))
}
}
+ // Actions when printing a doc from card
+ include DOL_DOCUMENT_ROOT.'/core/actions_printing.inc.php';
+
// Actions to build doc
$upload_dir = $conf->adherent->dir_output;
$permissioncreate=$user->rights->adherent->creer;
include DOL_DOCUMENT_ROOT.'/core/actions_builddoc.inc.php';
+
+ // Actions to send emails
+ $trigger_name='MEMBER_SENTBYMAIL';
+ $paramname='id';
+ $mode='emailfrommember';
+ $trackid='mem'.$object->id;
+ include DOL_DOCUMENT_ROOT.'/core/actions_sendmails.inc.php';
+
}
@@ -1344,10 +1364,10 @@ else
}
// Confirm send card by mail
- if ($action == 'sendinfo')
+ /*if ($action == 'sendinfo')
{
print $form->formconfirm("card.php?rowid=".$id,$langs->trans("SendCardByMail"),$langs->trans("ConfirmSendCardByMail",$object->email),"confirm_sendinfo",'',0,1);
- }
+ }*/
// Confirm terminate
if ($action == 'resign')
@@ -1590,6 +1610,31 @@ else
if (empty($reshook)) {
if ($action != 'valid' && $action != 'editlogin' && $action != 'editthirdparty')
{
+ // Send
+ if ($object->statut == 1) {
+ print '
';
+ }
+
+ // Send card by email
+ // TODO Remove this to replace with a template
+ /*
+ if ($user->rights->adherent->creer)
+ {
+ if ($object->statut >= 1)
+ {
+ if ($object->email) print '
';
// Message of the day on home page
- $substitutionarray=getCommonSubstitutionArray($langs, 0, array('object'));
+ $substitutionarray=getCommonSubstitutionArray($langs, 0, array('object','objectamount'));
complete_substitutions_array($substitutionarray, $langs);
- $substitutionarray['__(AnyTranslationKey)__']=$langs->trans('TranslationKey');
print '
';
+ }
// Town
if (! empty($arrayfields['s.town']['checked']))
{
diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php
index 2ac0b3a5885..e0acad65ab8 100644
--- a/htdocs/core/actions_massactions.inc.php
+++ b/htdocs/core/actions_massactions.inc.php
@@ -104,7 +104,7 @@ if (! $error && $massaction == 'confirm_presend')
if (empty($receiver) || $receiver == '-1') $receiver=array();
else $receiver=array($receiver);
}
- if (count($receiver) == 0 && count($listofobjectthirdparties) == 1) // if only one recipient, receiver is mandatory
+ if (! trim($_POST['sendto']) && count($receiver) == 0 && count($listofobjectthirdparties) == 1) // if only one recipient, receiver is mandatory
{
$error++;
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Recipient")), null, 'warnings');
@@ -322,114 +322,129 @@ if (! $error && $massaction == 'confirm_presend')
if ($objectclass == 'CommandeFournisseur') $sendtocc = (empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO)?'':$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_ORDER_TO);
if ($objectclass == 'FactureFournisseur') $sendtocc = (empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO)?'':$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO);
- $objecttmp=new $objectclass($db);
- $objecttmp->thirdparty = $thirdparty;
-
- // Make substitution in email content
- $substitutionarray=getCommonSubstitutionArray($langs, 0, null, $objecttmp);
- $substitutionarray['__ID__'] = join(', ',array_keys($listofqualifiedid));
- $substitutionarray['__EMAIL__'] = $thirdparty->email;
- $substitutionarray['__CHECK_READ__'] = '';
- $substitutionarray['__REF__'] = join(', ',$listofqualifiedref);
-
- $parameters=array('mode'=>'formemail');
- complete_substitutions_array($substitutionarray, $langs, $objecttmp, $parameters);
-
- $subject=make_substitutions($subject, $substitutionarray);
- $message=make_substitutions($message, $substitutionarray);
-
- $filepath = $attachedfiles['paths'];
- $filename = $attachedfiles['names'];
- $mimetype = $attachedfiles['mimes'];
-
- //var_dump($filepath);
-
- // Send mail (substitutionarray must be done just before this)
- require_once(DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php');
- $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,$sendtobcc,$deliveryreceipt,-1);
- if ($mailfile->error)
+ // $listofqualifiedid is array with key = object id of qualified objects for the current thirdparty
+ $oneemailperrecipient=(GETPOST('oneemailperrecipient')=='on'?1:0);
+ $looparray=array();
+ if (! $oneemailperrecipient)
{
- $resaction.='
'.$mailfile->error.'
';
+ $looparray = $listofqualifiedid;
}
else
{
- $result=$mailfile->sendfile();
- if ($result)
- {
- $resaction.=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2)).' '; // Must not contain "
-
- $error=0;
-
- // Insert logs into agenda
- foreach($listofqualifiedid as $objid => $object)
- {
- /*if ($objectclass == 'Propale') $actiontypecode='AC_PROP';
- if ($objectclass == 'Commande') $actiontypecode='AC_COM';
- if ($objectclass == 'Facture') $actiontypecode='AC_FAC';
- if ($objectclass == 'Supplier_Proposal') $actiontypecode='AC_SUP_PRO';
- if ($objectclass == 'CommandeFournisseur') $actiontypecode='AC_SUP_ORD';
- if ($objectclass == 'FactureFournisseur') $actiontypecode='AC_SUP_INV';*/
-
- $actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto;
- if ($message)
- {
- if ($sendtocc) $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . $sendtocc);
- $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subject);
- $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":");
- $actionmsg = dol_concatdesc($actionmsg, $message);
- }
- $actionmsg2='';
-
- // Initialisation donnees
- $object->sendtoid = 0;
- $object->actionmsg = $actionmsg; // Long text
- $object->actionmsg2 = $actionmsg2; // Short text
- $object->fk_element = $objid;
- $object->elementtype = $object->element;
-
- $triggername = strtoupper(get_class($object)) .'_SENTBYMAIL';
- if ($triggername == 'SOCIETE_SENTBYMAIL') $triggername = 'COMPANY_SENTBYEMAIL';
- if ($triggername == 'CONTRAT_SENTBYMAIL') $triggername = 'CONTRACT_SENTBYEMAIL';
- if ($triggername == 'COMMANDE_SENTBYMAIL') $triggername = 'ORDER_SENTBYEMAIL';
- if ($triggername == 'FACTURE_SENTBYMAIL') $triggername = 'BILL_SENTBYEMAIL';
- if ($triggername == 'EXPEDITION_SENTBYMAIL') $triggername = 'SHIPPING_SENTBYEMAIL';
- if ($triggername == 'COMMANDEFOURNISSEUR_SENTBYMAIL') $triggername = 'ORDER_SUPPLIER_SENTBYMAIL';
- if ($triggername == 'FACTUREFOURNISSEUR_SENTBYMAIL') $triggername = 'BILL_SUPPLIER_SENTBYEMAIL';
- if ($triggername == 'SUPPLIERPROPOSAL_SENTBYMAIL') $triggername = 'PROPOSAL_SUPPLIER_SENTBYEMAIL';
-
- if (! empty($trigger_name))
- {
- // Appel des triggers
- include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php");
- $interface=new Interfaces($db);
- $result=$interface->run_triggers($trigger_name, $object, $user, $langs, $conf);
- if ($result < 0) { $error++; $errors=$interface->errors; }
- // Fin appel triggers
-
- if ($error)
- {
- setEventMessages($db->lasterror(), $errors, 'errors');
- dol_syslog("Error in trigger ".$trigger_name.' '.$db->lasterror(), LOG_ERR);
- }
- }
-
- $nbsent++;
- }
- }
- else
- {
- $langs->load("other");
- if ($mailfile->error)
- {
- $resaction.=$langs->trans('ErrorFailedToSendMail',$from,$sendto);
- $resaction.='
'.$mailfile->error.'
';
- }
- else
- {
- $resaction.='
No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS
';
- }
- }
+ $objectforloop=new $objectclass($db);
+ $objectforloop->thirdparty = $thirdparty;
+ $looparray[0]=$objectforloop;
}
+ //var_dump($looparray);exit;
+
+ foreach ($looparray as $objecttmp) // $objecttmp is a real object or an empty if we choose to send one email per thirdparty instead of per record
+ {
+ // Make substitution in email content
+ $substitutionarray=getCommonSubstitutionArray($langs, 0, null, $objecttmp);
+ $substitutionarray['__ID__'] = ($oneemailperrecipient ? join(', ',array_keys($listofqualifiedid)) : $objecttmp->id);
+ $substitutionarray['__REF__'] = ($oneemailperrecipient ? join(', ',$listofqualifiedref) : $objecttmp->ref);
+ $substitutionarray['__EMAIL__'] = $thirdparty->email;
+ $substitutionarray['__CHECK_READ__'] = '';
+
+ $parameters=array('mode'=>'formemail');
+ complete_substitutions_array($substitutionarray, $langs, $objecttmp, $parameters);
+
+ $subject=make_substitutions($subject, $substitutionarray);
+ $message=make_substitutions($message, $substitutionarray);
+
+ $filepath = $attachedfiles['paths'];
+ $filename = $attachedfiles['names'];
+ $mimetype = $attachedfiles['mimes'];
+
+ //var_dump($filepath);
+
+ // Send mail (substitutionarray must be done just before this)
+ require_once(DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php');
+ $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,$sendtobcc,$deliveryreceipt,-1);
+ if ($mailfile->error)
+ {
+ $resaction.='
'.$mailfile->error.'
';
+ }
+ else
+ {
+ $result=$mailfile->sendfile();
+ if ($result)
+ {
+ $resaction.=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2)).' '; // Must not contain "
+
+ $error=0;
+
+ // Insert logs into agenda
+ foreach($listofqualifiedid as $objid => $object)
+ {
+ /*if ($objectclass == 'Propale') $actiontypecode='AC_PROP';
+ if ($objectclass == 'Commande') $actiontypecode='AC_COM';
+ if ($objectclass == 'Facture') $actiontypecode='AC_FAC';
+ if ($objectclass == 'Supplier_Proposal') $actiontypecode='AC_SUP_PRO';
+ if ($objectclass == 'CommandeFournisseur') $actiontypecode='AC_SUP_ORD';
+ if ($objectclass == 'FactureFournisseur') $actiontypecode='AC_SUP_INV';*/
+
+ $actionmsg=$langs->transnoentities('MailSentBy').' '.$from.' '.$langs->transnoentities('To').' '.$sendto;
+ if ($message)
+ {
+ if ($sendtocc) $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('Bcc') . ": " . $sendtocc);
+ $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('MailTopic') . ": " . $subject);
+ $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":");
+ $actionmsg = dol_concatdesc($actionmsg, $message);
+ }
+ $actionmsg2='';
+
+ // Initialisation donnees
+ $object->sendtoid = 0;
+ $object->actionmsg = $actionmsg; // Long text
+ $object->actionmsg2 = $actionmsg2; // Short text
+ $object->fk_element = $objid;
+ $object->elementtype = $object->element;
+
+ $triggername = strtoupper(get_class($object)) .'_SENTBYMAIL';
+ if ($triggername == 'SOCIETE_SENTBYMAIL') $triggername = 'COMPANY_SENTBYEMAIL';
+ if ($triggername == 'CONTRAT_SENTBYMAIL') $triggername = 'CONTRACT_SENTBYEMAIL';
+ if ($triggername == 'COMMANDE_SENTBYMAIL') $triggername = 'ORDER_SENTBYEMAIL';
+ if ($triggername == 'FACTURE_SENTBYMAIL') $triggername = 'BILL_SENTBYEMAIL';
+ if ($triggername == 'EXPEDITION_SENTBYMAIL') $triggername = 'SHIPPING_SENTBYEMAIL';
+ if ($triggername == 'COMMANDEFOURNISSEUR_SENTBYMAIL') $triggername = 'ORDER_SUPPLIER_SENTBYMAIL';
+ if ($triggername == 'FACTUREFOURNISSEUR_SENTBYMAIL') $triggername = 'BILL_SUPPLIER_SENTBYEMAIL';
+ if ($triggername == 'SUPPLIERPROPOSAL_SENTBYMAIL') $triggername = 'PROPOSAL_SUPPLIER_SENTBYEMAIL';
+
+ if (! empty($trigger_name))
+ {
+ // Appel des triggers
+ include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php");
+ $interface=new Interfaces($db);
+ $result=$interface->run_triggers($trigger_name, $object, $user, $langs, $conf);
+ if ($result < 0) { $error++; $errors=$interface->errors; }
+ // Fin appel triggers
+
+ if ($error)
+ {
+ setEventMessages($db->lasterror(), $errors, 'errors');
+ dol_syslog("Error in trigger ".$trigger_name.' '.$db->lasterror(), LOG_ERR);
+ }
+ }
+
+ $nbsent++;
+ }
+ }
+ else
+ {
+ $langs->load("other");
+ if ($mailfile->error)
+ {
+ $resaction.=$langs->trans('ErrorFailedToSendMail',$from,$sendto);
+ $resaction.='
'.$mailfile->error.'
';
+ }
+ else
+ {
+ $resaction.='
No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS
';
+ }
+ }
+ }
+ }
}
}
diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php
index fddd6889515..4439f0034ce 100644
--- a/htdocs/core/actions_sendmails.inc.php
+++ b/htdocs/core/actions_sendmails.inc.php
@@ -18,8 +18,8 @@
/**
* \file htdocs/core/actions_sendmails.inc.php
-* \brief Code for actions on sending mails from object page
-*/
+ * \brief Code for actions on sending mails from object page
+ */
// $mysoc must be defined
// $id must be defined
@@ -113,13 +113,18 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO
$result=$object->fetch($id);
$sendtosocid=0; // Thirdparty on object
- if (method_exists($object,"fetch_thirdparty") && $object->element != 'societe')
+ if (method_exists($object,"fetch_thirdparty") && ! in_array($object->element, array('societe','member')))
{
$result=$object->fetch_thirdparty();
if ($object->element == 'user' && $result == 0) $result=1; // Even if not found, we consider ok
$thirdparty=$object->thirdparty;
$sendtosocid=$thirdparty->id;
}
+ else if ($object->element == 'member')
+ {
+ $thirdparty=$object;
+ if ($thirdparty->id > 0) $sendtosocid=$thirdparty->id;
+ }
else if ($object->element == 'societe')
{
$thirdparty=$object;
@@ -348,21 +353,6 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO
$substitutionarray=getCommonSubstitutionArray($langs, 0, null, $object);
$substitutionarray['__EMAIL__'] = $sendto;
$substitutionarray['__CHECK_READ__'] = (is_object($object) && is_object($object->thirdparty))?'':'';
- // Add specific substitution for contracts
- if (is_object($object) && $object->element == 'contrat' && is_array($object->lines))
- {
- $dateplannedstart='';
- $datenextexpiration='';
- foreach($object->lines as $line)
- {
- if ($line->date_ouverture_prevue > $dateplannedstart) $dateplannedstart = $line->date_ouverture_prevue;
- if ($line->statut == 4 && $line->date_fin_prevue && (! $datenextexpiration || $line->date_fin_prevue < $datenextexpiration)) $datenextexpiration = $line->date_fin_prevue;
- }
- $substitutionarray['__CONTRACT_HIGHEST_PLANNED_START_DATE__'] = dol_print_date($dateplannedstart, 'dayrfc');
- $substitutionarray['__CONTRACT_HIGHEST_PLANNED_START_DATETIME__'] = dol_print_date($dateplannedstart, 'standard');
- $substitutionarray['__CONTRACT_LOWEST_EXPIRATION_DATE__'] = dol_print_date($datenextexpiration, 'dayrfc');
- $substitutionarray['__CONTRACT_LOWEST_EXPIRATION_DATETIME__'] = dol_print_date($datenextexpiration, 'standard');
- }
$parameters=array('mode'=>'formemail');
complete_substitutions_array($substitutionarray, $langs, $object, $parameters);
@@ -370,6 +360,12 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO
$subject=make_substitutions($subject, $substitutionarray);
$message=make_substitutions($message, $substitutionarray);
+ if (method_exists($object, 'makeSubstitution'))
+ {
+ $subject = $object->makeSubstitution($subject);
+ $message = $object->makeSubstitution($message);
+ }
+
// Send mail (substitutionarray must be done just before this)
if (empty($sendcontext)) $sendcontext = 'standard';
$mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,$sendtobcc,$deliveryreceipt,-1,'','',$trackid,'', $sendcontext);
@@ -485,7 +481,7 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO
else
{
$langs->load("other");
- setEventMessages($langs->trans('ErrorFailedToReadEntity',$object->element), null, 'errors');
+ setEventMessages($langs->trans('ErrorFailedToReadObject',$object->element), null, 'errors');
dol_syslog('Failed to read data of object id='.$object->id.' element='.$object->element);
$action = 'presend';
}
diff --git a/htdocs/core/actions_setnotes.inc.php b/htdocs/core/actions_setnotes.inc.php
index 39f63683575..50b35392644 100644
--- a/htdocs/core/actions_setnotes.inc.php
+++ b/htdocs/core/actions_setnotes.inc.php
@@ -32,7 +32,7 @@ if ($action == 'setnote_public' && ! empty($permissionnote) && ! GETPOST('cancel
{
if (empty($action) || ! is_object($object) || empty($id)) dol_print_error('','Include of actions_setnotes.inc.php was done but required variable was not set before');
if (empty($object->id)) $object->fetch($id); // Fetch may not be already done
- $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public'), ENT_QUOTES),'_public');
+ $result=$object->update_note(dol_html_entity_decode(GETPOST('note_public', 'none'), ENT_QUOTES),'_public');
if ($result < 0) setEventMessages($object->error, $object->errors, 'errors');
}
// Set public note
@@ -40,6 +40,6 @@ else if ($action == 'setnote_private' && ! empty($permissionnote) && ! GETPOST('
{
if (empty($action) || ! is_object($object) || empty($id)) dol_print_error('','Include of actions_setnotes.inc.php was done but required variable was not set before');
if (empty($object->id)) $object->fetch($id); // Fetch may not be already done
- $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private'), ENT_QUOTES),'_private');
+ $result=$object->update_note(dol_html_entity_decode(GETPOST('note_private', 'none'), ENT_QUOTES),'_private');
if ($result < 0) setEventMessages($object->error, $object->errors, 'errors');
}
diff --git a/htdocs/core/boxes/box_activity.php b/htdocs/core/boxes/box_activity.php
index 71a9a4e3125..d3059daba53 100644
--- a/htdocs/core/boxes/box_activity.php
+++ b/htdocs/core/boxes/box_activity.php
@@ -435,7 +435,7 @@ class box_activity extends ModeleBoxes
}
// Add the sum in the bottom of the boxes
- $this->info_box_contents[$line][0] = array('tr' => 'class="liste_total"');
+ $this->info_box_contents[$line][0] = array('tr' => 'class="liste_total_wrap"');
$this->info_box_contents[$line][1] = array('td' => 'align="left" class="liste_total" ', 'text' => $langs->trans("Total")." ".$textHead);
$this->info_box_contents[$line][2] = array('td' => 'align="right" class="liste_total" ', 'text' => $totalnb);
$this->info_box_contents[$line][3] = array('td' => 'align="right" class="liste_total" ', 'text' => '');
diff --git a/htdocs/core/boxes/modules_boxes.php b/htdocs/core/boxes/modules_boxes.php
index 9c496964942..93b8fa3d9d2 100644
--- a/htdocs/core/boxes/modules_boxes.php
+++ b/htdocs/core/boxes/modules_boxes.php
@@ -286,7 +286,7 @@ class ModeleBoxes // Can't be abtract as it is instantiated to build "empty"
if (isset($contents[$i]))
{
// TR
- if (isset($contents[$i][0]['tr'])) $out.= '
';
+ if (isset($contents[$i][0]['tr'])) $out.= '
';
else $out.= '
';
// Loop on each TD
diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php
index ed318bbd900..9ebcb295792 100644
--- a/htdocs/core/class/html.form.class.php
+++ b/htdocs/core/class/html.form.class.php
@@ -544,7 +544,7 @@ class Form
$disabled=0;
$ret='
';
- $ret.='
';
if (! empty($conf->use_javascript_ajax))
@@ -2987,12 +2987,12 @@ class Form
* Constant MAIN_DEFAULT_PAYMENT_TERM_ID can used to set default value but scope is all application, probably not what you want.
* See instead to force the default value by the caller.
*
- * @param int $selected Id of payment term to preselect by default
- * @param string $htmlname Nom de la zone select
- * @param int $filtertype Not used
+ * @param int $selected Id of payment term to preselect by default
+ * @param string $htmlname Nom de la zone select
+ * @param int $filtertype Not used
* @param int $addempty Add an empty entry
- * @param int $noadmininfo 0=Add admin info, 1=Disable admin info
- * @param string $morecss Add more CSS on select tag
+ * @param int $noinfoadmin 0=Add admin info, 1=Disable admin info
+ * @param string $morecss Add more CSS on select tag
* @return void
*/
function select_conditions_paiements($selected=0, $htmlname='condid', $filtertype=-1, $addempty=0, $noinfoadmin=0, $morecss='')
@@ -3277,7 +3277,7 @@ class Form
$return= '';
- $sql = 'SELECT rowid, label from '.MAIN_DB_PREFIX.'c_units';
+ $sql = 'SELECT rowid, label, code from '.MAIN_DB_PREFIX.'c_units';
$sql.= ' WHERE active > 0';
$resql = $this->db->query($sql);
@@ -5215,15 +5215,16 @@ class Form
*/
static function selectArrayAjax($htmlname, $url, $id='', $moreparam='', $moreparamtourl='', $disabled=0, $minimumInputLength=1, $morecss='', $callurlonselect=0, $placeholder='', $acceptdelayedhtml=0)
{
- global $langs;
+ global $conf, $langs;
global $delayedhtmlcontent;
- $tmpplugin='select2';
+ // TODO Use an internal dolibarr component instead of select2
+ if (empty($conf->global->MAIN_USE_JQUERY_MULTISELECT) && ! defined('REQUIRE_JQUERY_MULTISELECT')) return '';
$out='';
- // TODO Use an internal dolibarr component instead of select2
- $outdelayed='
+ $tmpplugin='select2';
+ $outdelayed="\n".'
'."\n";
- print ''."\n";
}
}
@@ -1319,7 +1320,7 @@ function top_htmlhead($head, $title='', $disablejs=0, $disablehead=0, $arrayofjs
// Global js function
print ''."\n";
- print ''."\n";
+ print ''."\n";
// Add datepicker default options
/*if (! defined('DISABLE_DATE_PICKER'))
diff --git a/htdocs/modulebuilder/index.php b/htdocs/modulebuilder/index.php
index dfd12354399..dade8847aa6 100644
--- a/htdocs/modulebuilder/index.php
+++ b/htdocs/modulebuilder/index.php
@@ -23,7 +23,7 @@
* \brief Home page for module builder module
*/
-if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti CSRF attack test
+if (! defined('NOSCANPOSTFORINJECTION')) define('NOSCANPOSTFORINJECTION','1'); // Do not check anti SQL+XSS injection attack test
require '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
@@ -337,13 +337,13 @@ if ($dirins && $action == 'initobject' && $module && $objectname)
if (! $error)
{
// Edit the class file to write properties
- $result=rebuildObjectClass($destdir, $module, $objectname, $newmask);
- if ($result < 0) $error++;
+ $object=rebuildObjectClass($destdir, $module, $objectname, $newmask);
+ if (is_numeric($object) && $object < 0) $error++;
}
if (! $error)
{
// Edit sql with new properties
- $result=rebuildObjectSql($destdir, $module, $objectname, $newmask);
+ $result=rebuildObjectSql($destdir, $module, $objectname, $newmask, '', $object);
if ($result < 0) $error++;
}
@@ -362,22 +362,32 @@ if ($dirins && $action == 'addproperty' && !empty($module) && ! empty($tabobj))
dol_mkdir($destdir);
$addfieldentry = array(
- 'name'=>GETPOST('propname','aZ09'),'type'=>GETPOST('proptype','aZ09'),'label'=>GETPOST('proplabel','aZ09'),'visible'=>GETPOST('propvisible','int'),'enabled'=>GETPOST('propenabled','int'),
+ 'name'=>GETPOST('propname','aZ09'),'label'=>GETPOST('proplabel','alpha'),'type'=>GETPOST('proptype','alpha'),
+ 'arrayofkeyval'=>GETPOST('proparrayofkeyval','none'), // Example json string '{"0":"Draft","1":"Active","-1":"Cancel"}'
+ 'visible'=>GETPOST('propvisible','int'),'enabled'=>GETPOST('propenabled','int'),
'position'=>GETPOST('propposition','int'),'notnull'=>GETPOST('propnotnull','int'),'index'=>GETPOST('propindex','int'),'searchall'=>GETPOST('propsearchall','int'),
'isameasure'=>GETPOST('propisameasure','int'), 'comment'=>GETPOST('propcomment','alpha'),'help'=>GETPOST('prophelp'));
+ if (! empty($addfieldentry['arrayofkeyval']) && ! is_array($addfieldentry['arrayofkeyval']))
+ {
+ $addfieldentry['arrayofkeyval'] = dol_json_decode($addfieldentry['arrayofkeyval'], true);
+ }
+
// Edit the class file to write properties
if (! $error)
{
- $result=rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, $addfieldentry);
- if ($result <= 0) $error++;
+ $object=rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, $addfieldentry);
+ if (is_numeric($result) && $result <= 0) $error++;
}
// Edit sql with new properties
if (! $error)
{
- $result=rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir);
- if ($result <= 0) $error++;
+ $result=rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir, $object);
+ if ($result <= 0)
+ {
+ $error++;
+ }
}
if (! $error)
@@ -405,14 +415,14 @@ if ($dirins && $action == 'confirm_deleteproperty' && $propertykey)
// Edit the class file to write properties
if (! $error)
{
- $result=rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, array(), $propertykey);
- if ($result <= 0) $error++;
+ $object=rebuildObjectClass($destdir, $module, $objectname, $newmask, $srcdir, array(), $propertykey);
+ if (is_numeric($object) && $object <= 0) $error++;
}
// Edit sql with new properties
if (! $error)
{
- $result=rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir);
+ $result=rebuildObjectSql($destdir, $module, $objectname, $newmask, $srcdir, $object);
if ($result <= 0) $error++;
}
@@ -675,16 +685,26 @@ if ($action == 'savefile' && empty($cancel))
// Save old version
if (dol_is_file($pathoffile))
{
- dol_move($pathoffile, $pathoffilebackup, 0, 1, 0, 0);
+ dol_copy($pathoffile, $pathoffilebackup, 0, 1);
}
- $content = GETPOST('editfilecontent');
+ $content = GETPOST('editfilecontent','none');
// Save file on disk
- file_put_contents($pathoffile, $content);
- @chmod($pathoffile, octdec($newmask));
+ if ($content)
+ {
+ dol_delete_file($pathoffile);
+ file_put_contents($pathoffile, $content);
+ @chmod($pathoffile, octdec($newmask));
- setEventMessages($langs->trans("FileSaved"), null);
+ setEventMessages($langs->trans("FileSaved"), null);
+ }
+ else
+ {
+ setEventMessages($langs->trans("ContentCantBeEmpty"), null, 'errors');
+ //$action='editfile';
+ $error++;
+ }
}
}
@@ -831,7 +851,8 @@ if ($message)
print $message;
}
-print $langs->trans("ModuleBuilderDesc3", count($listofmodules), $FILEFLAG).' ';
+//print $langs->trans("ModuleBuilderDesc3", count($listofmodules), $FILEFLAG).' ';
+$infomodulesfound = '