diff --git a/.travis.yml b/.travis.yml
index 8655b27d4ed..4c18c5caa3b 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -10,7 +10,7 @@ php:
- '5.3'
- '5.4'
- '5.5'
-- '5.6'
+- '5.6.29'
- '7.0'
- nightly
diff --git a/ChangeLog b/ChangeLog
index 5fe3c741499..e4c07380aae 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -12,6 +12,28 @@ Upgrading to any other version or any other database system is abolutely require
make a Dolibarr upgrade.
+***** ChangeLog for 4.0.6 to 4.0.5 *****
+FIX: #6613 Default subject for Supplier proposal emails is filled with a non-existing key
+FIX: #6623 User card shows "Return to list" link even if the user has no rights to list users
+FIX: #6636 Complete fix
+FIX: #6669 User with no permission to edit customer invoices can see a edit button in project entry
+FIX: #6671 Cannot remove thirdparty type with "#" in its name
+FIX: #6673 Missing "nature" table header in thirdparty list
+FIX: #6675 Restricted user with no agenda permissions can see a button to create appointment in thirdparty contact list
+FIX: #6677 Expired contracts dashboard box does not show the name of the thirdparty
+FIX: #6679 User with restricted supplier invoice permissions can edit project, payment conditions, payment mode
+FIX: #6680 User with restricted supplier invoice permissions sees "reopen" button even if he has no permission to do it
+FIX: #6813
+FIX: Correction with author and validator user on orders
+FIX: doactions hook missing in invoice model page
+FIX: dont get empty "Incoterms : - " string if no incoterm
+FIX: dont lose supplier ref if no supplier price in database
+FIX: forgotten parameter for right multicompany use
+FIX: global $dateSelector isn't the good one, then date selector on objectline_create tpl was hidden
+FIX: limit+1 dosn't show Total line
+FIX: supplier order line were always created with rang = 0
+
+
***** ChangeLog for 4.0.5 to 4.0.4 *****
FIX: #6234
FIX: #6259
diff --git a/build/exe/doliwamp/doliwamp.iss b/build/exe/doliwamp/doliwamp.iss
index 34757a5123a..2ef8ab32f22 100644
--- a/build/exe/doliwamp/doliwamp.iss
+++ b/build/exe/doliwamp/doliwamp.iss
@@ -353,10 +353,12 @@ begin
begin
// TODO Copy file or ask to install package ?
//CustomMessage('YouWillInstallDoliWamp')+#13#13
- MsgBox('The package vcredist_x86.exe must have been installed first. It seems it is not. Please install it first from http://www.microsoft.com/en-us/download/details.aspx?id=30679 then restart DoliWamp installation/upgrade.',mbInformation,MB_OK);
+ MsgBox('The package vcredist_x86.exe must have been installed first. It seems it is not. Please install it first from http://www.microsoft.com/en-us/download/details.aspx?id=30679 then restart DoliWamp installation/upgrade.',mbInformation,MB_OK);
end;
-
-
+ // Pb seems similar with msvcp110.dll
+ //vcredist_x64.exe
+
+
// If we have a new database version, we should only copy old my.ini file into new directory
// and change only all basedir= strings to use new version. Like this, data dir is still correct.
// Install of service and stop/start scripts are already rebuild by installer.
diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl
index c06d8f0730f..20dfc2579aa 100755
--- a/build/makepack-dolibarr.pl
+++ b/build/makepack-dolibarr.pl
@@ -19,7 +19,7 @@ use Cwd;
# Change this to defined target for option 98 and 99
$PROJECT="dolibarr";
$PUBLISHSTABLE="eldy,dolibarr\@frs.sourceforge.net:/home/frs/project/dolibarr";
-$PUBLISHBETARC="ldestailleur\@asso.dolibarr.org:/home/dolibarr/dolibarr.org/httpdocs/files";
+$PUBLISHBETARC="ldestailleur\@vmprod.dolibarr.org:/home/dolibarr/dolibarr.org/httpdocs/files";
#@LISTETARGET=("TGZ","ZIP","RPM_GENERIC","RPM_FEDORA","RPM_MANDRIVA","RPM_OPENSUSE","DEB","APS","EXEDOLIWAMP","SNAPSHOT"); # Possible packages
@@ -518,6 +518,7 @@ if ($nboftargetok) {
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/dolimed*`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/dolimod*`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/factory*`;
+ $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/forceproject*`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/lead*`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/management*`;
$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/multicompany*`;
diff --git a/htdocs/compta/bank/treso.php b/htdocs/compta/bank/treso.php
index 26be80caa68..d87a439f404 100644
--- a/htdocs/compta/bank/treso.php
+++ b/htdocs/compta/bank/treso.php
@@ -282,6 +282,8 @@ if ($_REQUEST["account"] || $_REQUEST["ref"])
$refcomp=$societestatic->getNomUrl(1,'',24);
$paiement = $facturestatic->getSommePaiement(); // Payment already done
+ $paiement+= $facturestatic->getSumDepositsUsed();
+ $paiement+= $facturestatic->getSumCreditNotesUsed();
}
if ($obj->family == 'social_contribution')
{
diff --git a/htdocs/compta/facture.php b/htdocs/compta/facture.php
index 4e7f7fe1c32..8a35fd7583d 100644
--- a/htdocs/compta/facture.php
+++ b/htdocs/compta/facture.php
@@ -1998,7 +1998,7 @@ if ($action == 'create')
if (!empty($soc->id)) $absolute_discount = $soc->getAvailableDiscounts();
$note_public = $object->getDefaultCreateValueFor('note_public', (is_object($objectsrc)?$objectsrc->note_public:null));
$note_private = $object->getDefaultCreateValueFor('note_private', ((! empty($origin) && ! empty($originid) && is_object($objectsrc))?$objectsrc->note_private:null));
-
+
if (! empty($conf->use_javascript_ajax))
{
require_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php';
@@ -2197,7 +2197,7 @@ if ($action == 'create')
if ((empty($origin)) || ((($origin == 'propal') || ($origin == 'commande')) && (! empty($originid))))
{
// Deposit
- if (empty($conf->global->INVOICE_DISABLE_DEPOSIT))
+ if (empty($conf->global->INVOICE_DISABLE_DEPOSIT))
{
print '
';
continue; // Payment done or started or canceled
}
-
+
// Read document
// TODO Use future field $object->fullpathdoc to know where is stored default file
// TODO If not defined, use $object->modelpdf (or defaut invoice config) to know what is template to use to regenerate doc.
@@ -347,39 +347,39 @@ if (empty($reshook))
$object->fetch_thirdparty();
$sendto = $object->thirdparty->email;
}
-
- if (empty($sendto))
+
+ if (empty($sendto))
{
//print "No recipient for thirdparty ".$object->thirdparty->name;
$nbignored++;
continue;
}
-
+
if (dol_strlen($sendto))
{
// Create form object
$attachedfiles=array(
- 'paths'=>array_merge($attachedfiles['paths'],array($file)),
- 'names'=>array_merge($attachedfiles['names'],array($filename)),
+ 'paths'=>array_merge($attachedfiles['paths'],array($file)),
+ 'names'=>array_merge($attachedfiles['names'],array($filename)),
'mimes'=>array_merge($attachedfiles['mimes'],array($mime))
);
}
-
+
$listofqualifiedinvoice[$objectid]=$object;
$listofqualifiedref[$objectid]=$object->ref;
}
else
- {
+ {
$nbignored++;
$langs->load("errors");
$resaction.='
'.$langs->trans('ErrorCantReadFile',$file).'
';
dol_syslog('Failed to read file: '.$file, LOG_WARNING);
continue;
}
-
+
//var_dump($listofqualifiedref);
}
-
+
if (count($listofqualifiedinvoice) > 0)
{
$langs->load("commercial");
@@ -389,7 +389,7 @@ if (empty($reshook))
$message = GETPOST('message');
$sendtocc = GETPOST('sentocc');
$sendtobcc = (empty($conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO)?'':$conf->global->MAIN_MAIL_AUTOCOPY_INVOICE_TO);
-
+
$substitutionarray=array(
'__ID__' => join(', ',array_keys($listofqualifiedinvoice)),
'__EMAIL__' => $thirdparty->email,
@@ -400,16 +400,16 @@ if (empty($reshook))
'__REF__' => join(', ',$listofqualifiedref),
'__REFCLIENT__' => $thirdparty->name
);
-
+
$subject=make_substitutions($subject, $substitutionarray);
$message=make_substitutions($message, $substitutionarray);
-
+
$filepath = $attachedfiles['paths'];
$filename = $attachedfiles['names'];
$mimetype = $attachedfiles['mimes'];
-
+
//var_dump($filepath);
-
+
// Send mail
require_once(DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php');
$mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,$sendtobcc,$deliveryreceipt,-1);
@@ -423,9 +423,9 @@ if (empty($reshook))
if ($result)
{
$resaction.=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2)).' '; // Must not contain "
-
+
$error=0;
-
+
// Insert logs into agenda
foreach($listofqualifiedinvoice as $invid => $object)
{
@@ -438,7 +438,7 @@ if (empty($reshook))
$actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":");
$actionmsg = dol_concatdesc($actionmsg, $message);
}
-
+
// Initialisation donnees
$object->sendtoid = 0;
$object->actiontypecode = $actiontypecode;
@@ -446,14 +446,14 @@ if (empty($reshook))
$object->actionmsg2 = $actionmsg2; // Short text
$object->fk_element = $invid;
$object->elementtype = $object->element;
-
+
// Appel des triggers
include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php");
$interface=new Interfaces($db);
$result=$interface->run_triggers('BILL_SENTBYMAIL',$object,$user,$langs,$conf);
if ($result < 0) { $error++; $errors=$interface->errors; }
// Fin appel triggers
-
+
if ($error)
{
setEventMessages($db->lasterror(), $errors, 'errors');
@@ -484,7 +484,7 @@ if (empty($reshook))
$resaction.=$langs->trans("NbSelected").': '.count($toselect)."\n ";
$resaction.=$langs->trans("NbIgnored").': '.($nbignored?$nbignored:0)."\n ";
$resaction.=$langs->trans("NbSent").': '.($nbsent?$nbsent:0)."\n ";
-
+
if ($nbsent)
{
$action=''; // Do not show form post if there was at least one successfull sent
@@ -497,7 +497,7 @@ if (empty($reshook))
setEventMessages($resaction, null, 'warnings');
}
}
-
+
$action='list';
$massaction='';
}
@@ -507,7 +507,7 @@ if (empty($reshook))
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/pdf.lib.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
-
+
$objecttmp=new Facture($db);
$listofobjectid=array();
$listofobjectthirdparties=array();
@@ -542,7 +542,7 @@ if (empty($reshook))
}
}
}
-
+
// Define output language (Here it is not used because we do only merging existing PDF)
$outputlangs = $langs;
$newlang='';
@@ -607,12 +607,12 @@ if (empty($reshook))
setEventMessages($langs->trans('NoPDFAvailableForDocGenAmongChecked'), null, 'errors');
}
}
-
+
// Remove file
if ($action == 'remove_file')
{
require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
-
+
$langs->load("other");
$upload_dir = $diroutputmassaction;
$file = $upload_dir . '/' . GETPOST('file');
@@ -621,10 +621,10 @@ if (empty($reshook))
else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), null, 'errors');
$action='';
}
-
+
}
-
+
/*
* View
@@ -650,7 +650,7 @@ $sql.= " typent.code as typent_code,";
$sql.= " state.code_departement as state_code, state.nom as state_name";
// We need dynamount_payed to be able to sort on status (value is surely wrong because we can count several lines several times due to other left join or link with contacts. But what we need is just 0 or > 0)
// TODO Better solution to be able to sort on already payed or remain to pay is to store amount_payed in a denormalized field.
-if (! $sall) $sql.= ', SUM(pf.amount) as dynamount_payed';
+if (! $sall) $sql.= ', SUM(pf.amount) as dynamount_payed';
// Add fields from extrafields
foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key.' as options_'.$key : '');
// Add fields from hooks
@@ -795,7 +795,7 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST))
$nbtotalofrecords = $db->num_rows($result);
}
-$sql.= $db->plimit($limit,$offset);
+$sql.= $db->plimit($limit + 1,$offset);
//print $sql;
$resql = $db->query($sql);
@@ -804,7 +804,7 @@ if ($resql)
$num = $db->num_rows($resql);
$arrayofselected=is_array($toselect)?$toselect:array();
-
+
if ($socid)
{
$soc = new Societe($db);
@@ -842,11 +842,12 @@ if ($resql)
$tmpkey=preg_replace('/search_options_/','',$key);
if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val);
}
-
+
$massactionbutton=$form->selectMassAction('', $massaction == 'presend' ? array() : array('presend'=>$langs->trans("SendByMail"), 'builddoc'=>$langs->trans("PDFMerge")));
-
+
$i = 0;
print '\n";
-
+
if ($massaction == 'builddoc' || $action == 'remove_file' || $show_files)
{
/*
@@ -1492,15 +1493,15 @@ if ($resql)
*/
$urlsource=$_SERVER['PHP_SELF'].'?sortfield='.$sortfield.'&sortorder='.$sortorder;
$urlsource.=str_replace('&','&',$param);
-
+
$filedir=$diroutputmassaction;
$genallowed=$user->rights->facture->lire;
$delallowed=$user->rights->facture->lire;
-
+
print ' ';
$paramwithoutshowfiles=preg_replace('/show_files=1&?/','',$param);
$title=$langs->trans("MassFilesArea").' ('.$langs->trans("Hide").')';
-
+
print $formfile->showdocuments('massfilesarea_facture','',$filedir,$urlsource,0,$delallowed,'',1,1,0,48,1,$param,$title,'');
}
else
diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php
index cd14736632d..0785efe6b1a 100644
--- a/htdocs/compta/prelevement/class/bonprelevement.class.php
+++ b/htdocs/compta/prelevement/class/bonprelevement.class.php
@@ -252,7 +252,7 @@ class BonPrelevement extends CommonObject
function getErrorString($error)
{
global $langs;
-
+
$errors = array();
$errors[1027] = $langs->trans("DateInvalid");
@@ -920,7 +920,7 @@ class BonPrelevement extends CommonObject
$dir=$conf->prelevement->dir_output.'/receipts';
if (! is_dir($dir)) dol_mkdir($dir);
-
+
$this->filename = $dir.'/'.$ref.'.xml';
// Create withdraw receipt in database
@@ -1028,7 +1028,7 @@ class BonPrelevement extends CommonObject
$this->emetteur_bic = $account->bic;
$this->emetteur_ics = $conf->global->PRELEVEMENT_ICS; // Ex: PRELEVEMENT_ICS = "FR78ZZZ123456";
-
+
$this->raison_sociale = $account->proprio;
}
@@ -1272,18 +1272,6 @@ class BonPrelevement extends CommonObject
* section Debiteur (sepa Debiteurs bloc lines)
*/
- $tmp_invoices = array();
-
- $sql = "SELECT f.facnumber as fac FROM ".MAIN_DB_PREFIX."prelevement_lignes as pl, ".MAIN_DB_PREFIX."facture as f, ".MAIN_DB_PREFIX."prelevement_facture as pf, ".MAIN_DB_PREFIX."societe as soc, ".MAIN_DB_PREFIX."c_country as p, ".MAIN_DB_PREFIX."societe_rib as rib WHERE pl.fk_prelevement_bons = ".$this->id." AND pl.rowid = pf.fk_prelevement_lignes AND pf.fk_facture = f.rowid AND soc.fk_pays = p.rowid AND soc.rowid = f.fk_soc AND rib.fk_soc = f.fk_soc AND rib.default_rib = 1";
- $resql=$this->db->query($sql);
- if ($resql) {
- while ($objfac = $this->db->fetch_object($resql)) {
- $tmp_invoices[] = $objfac->fac;
- }
- }
-
- $ListOfFactures = implode($tmp_invoices);
-
$sql = "SELECT soc.code_client as code, soc.address, soc.zip, soc.town, c.code as country_code,";
$sql.= " pl.client_nom as nom, pl.code_banque as cb, pl.code_guichet as cg, pl.number as cc, pl.amount as somme,";
$sql.= " f.facnumber as fac, pf.fk_facture as idfac, rib.datec, rib.iban_prefix as iban, rib.bic as bic, rib.rowid as drum";
@@ -1310,7 +1298,7 @@ class BonPrelevement extends CommonObject
while ($i < $num)
{
$obj = $this->db->fetch_object($resql);
- $fileDebiteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $ListOfFactures, $obj->idfac, $obj->iban, $obj->bic, $this->db->jdate($obj->datec), $obj->drum);
+ $fileDebiteurSection .= $this->EnregDestinataireSEPA($obj->code, $obj->nom, $obj->address, $obj->zip, $obj->town, $obj->country_code, $obj->cb, $obj->cg, $obj->cc, $obj->somme, $obj->fac, $obj->idfac, $obj->iban, $obj->bic, $this->db->jdate($obj->datec), $obj->drum);
$this->total = $this->total + $obj->somme;
$i++;
}
@@ -1581,11 +1569,11 @@ class BonPrelevement extends CommonObject
$XML_DEBITOR .=' '.$CrLf;
$XML_DEBITOR .=' '.$CrLf;
$XML_DEBITOR .=' '.$CrLf;
- $XML_DEBITOR .=' '.strtoupper(dol_string_unaccent($row_nom)).''.$CrLf;
+ $XML_DEBITOR .=' '.strtoupper(dolEscapeXML(dol_string_unaccent($row_nom))).''.$CrLf;
$XML_DEBITOR .=' '.$CrLf;
$XML_DEBITOR .=' '.$row_country_code.''.$CrLf;
- $XML_DEBITOR .=' '.dol_string_unaccent(strtr($row_address, array(CHR(13) => ", ", CHR(10) => ""))).''.$CrLf;
- $XML_DEBITOR .=' '.dol_string_unaccent($row_zip.' '.$row_town).''.$CrLf;
+ $XML_DEBITOR .=' '.dolEscapeXML(dol_trunc(dol_string_unaccent(strtr($row_address, array(CHR(13) => ", ", CHR(10) => ""))),70,'right','UTF-8',true)).''.$CrLf;
+ $XML_DEBITOR .=' '.dolEscapeXML(dol_string_unaccent($row_zip.' '.$row_town)).''.$CrLf;
$XML_DEBITOR .=' '.$CrLf;
$XML_DEBITOR .=' '.$CrLf;
$XML_DEBITOR .=' '.$CrLf;
@@ -1680,7 +1668,7 @@ class BonPrelevement extends CommonObject
* @return string String with SEPA Sender
*/
function EnregEmetteurSEPA($configuration, $ladate, $nombre, $total, $CrLf='\n')
- {
+ {
// SEPA INITIALISATION
global $conf;
@@ -1699,12 +1687,12 @@ class BonPrelevement extends CommonObject
$this->emetteur_number_key = $account->cle_rib;
$this->emetteur_iban = $account->iban;
$this->emetteur_bic = $account->bic;
-
+
$this->emetteur_ics = $conf->global->PRELEVEMENT_ICS; // Ex: PRELEVEMENT_ICS = "FR78ZZZ123456";
-
+
$this->raison_sociale = $account->proprio;
}
-
+
// Récupération info demandeur
$sql = "SELECT rowid, ref";
$sql.= " FROM";
diff --git a/htdocs/contrat/class/contrat.class.php b/htdocs/contrat/class/contrat.class.php
index d9addfff113..9269d505664 100644
--- a/htdocs/contrat/class/contrat.class.php
+++ b/htdocs/contrat/class/contrat.class.php
@@ -1599,8 +1599,8 @@ class Contrat extends CommonObject
if (empty($conf->global->MAIN_EXTRAFIELDS_DISABLED) && is_array($array_options) && count($array_options)>0) // For avoid conflicts if trigger used
{
$contractline = new ContratLigne($this->db);
- $contractline->array_options=$array_option;
- $contractline->id= $this->db->last_insert_id(MAIN_DB_PREFIX.$contractline->table_element);
+ $contractline->array_options=$array_options;
+ $contractline->id= $rowid;
$result=$contractline->insertExtraFields();
if ($result < 0)
{
diff --git a/htdocs/core/datepicker.php b/htdocs/core/datepicker.php
index 63b765fbadb..99bf9b15a80 100644
--- a/htdocs/core/datepicker.php
+++ b/htdocs/core/datepicker.php
@@ -39,7 +39,7 @@ if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML',1);
require_once '../main.inc.php';
require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php';
-if (GETPOST('lang')) $langs->setDefaultLang(GETPOST('lang')); // If language was forced on URL by the main.inc.php
+if (GETPOST('lang', 'aZ09')) $langs->setDefaultLang(GETPOST('lang', 'aZ09')); // If language was forced on URL by the main.inc.php
$langs->load("main");
$langs->load("agenda");
$right=($langs->trans("DIRECTION")=='rtl'?'left':'right');
diff --git a/htdocs/core/get_menudiv.php b/htdocs/core/get_menudiv.php
index 655e10afd67..f8b3a652e08 100644
--- a/htdocs/core/get_menudiv.php
+++ b/htdocs/core/get_menudiv.php
@@ -35,7 +35,7 @@ if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML',1);
require_once '../main.inc.php';
-if (GETPOST('lang')) $langs->setDefaultLang(GETPOST('lang')); // If language was forced on URL by the main.inc.php
+if (GETPOST('lang', 'aZ09')) $langs->setDefaultLang(GETPOST('lang', 'aZ09')); // If language was forced on URL by the main.inc.php
$langs->load("main");
$right=($langs->trans("DIRECTION")=='rtl'?'left':'right');
$left=($langs->trans("DIRECTION")=='rtl'?'right':'left');
diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php
index 562dcf9d223..03e2c6910cd 100644
--- a/htdocs/core/lib/date.lib.php
+++ b/htdocs/core/lib/date.lib.php
@@ -2,6 +2,7 @@
/* Copyright (C) 2004-2011 Laurent Destailleur
* Copyright (C) 2005-2011 Regis Houssin
* Copyright (C) 2011-2015 Juanjo Menent
+ * Copyright (C) 2017 Ferran Marcet
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -407,7 +408,7 @@ function dol_get_next_week($day, $week, $month, $year)
{
$tmparray = dol_get_first_day_week($day, $month, $year);
- $time=dol_mktime(12,0,0,$month,$tmparray['first_day'],$year,1,0);
+ $time=dol_mktime(12,0,0,$tmparray['first_month'],$tmparray['first_day'],$tmparray['first_year'],1,0);
$time+=24*60*60*7;
$tmparray=dol_getdate($time,true);
diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php
index 3ced09db552..c4674fbe5a0 100644
--- a/htdocs/core/lib/functions.lib.php
+++ b/htdocs/core/lib/functions.lib.php
@@ -191,7 +191,7 @@ function getBrowserInfo($user_agent)
elseif (preg_match('/opera(\/|\s)([\d\.]*)/i', $user_agent, $reg)) { $name='opera'; $version=$reg[2]; }
elseif (preg_match('/(MSIE\s([0-9]+\.[0-9]))|.*(Trident\/[0-9]+.[0-9];\srv:([0-9]+\.[0-9]+))/i', $user_agent, $reg)) { $name='ie'; $version=end($reg); } // MS products at end
elseif (preg_match('/l(i|y)n(x|ks)(\(|\/|\s)*([\d\.]+)/i', $user_agent, $reg)) { $name='lynxlinks'; $version=$reg[4]; }
-
+
if ($tablet) {
$layout = 'tablet';
} elseif ($phone) {
@@ -250,6 +250,9 @@ function GETPOST($paramname,$check='',$method=0,$filter=NULL,$options=NULL)
case 'int':
if (! is_numeric($out)) { $out=''; }
break;
+ case 'intcomma':
+ if (preg_match('/[^0-9,]+/i',$out)) $out='';
+ break;
case 'alpha':
$out=trim($out);
// '"' is dangerous because param in url can close the href= or src= and add javascript functions.
@@ -266,7 +269,7 @@ function GETPOST($paramname,$check='',$method=0,$filter=NULL,$options=NULL)
break;
case 'aZ09':
$out=trim($out);
- if (preg_match('/[^a-z0-9]+/i',$out)) $out='';
+ if (preg_match('/[^a-z0-9_\-]+/i',$out)) $out='';
break;
case 'array':
if (! is_array($out) || empty($out)) $out=array();
@@ -287,13 +290,13 @@ function GETPOST($paramname,$check='',$method=0,$filter=NULL,$options=NULL)
* This prefix is unique for instance and avoid conflict between multi-instances,
* even when having two instances with one root dir or two instances in virtual servers
*
- * @param string $mode '' or 'email'
+ * @param string $mode '' or 'email'
* @return string A calculated prefix
*/
function dol_getprefix($mode='')
{
global $conf;
-
+
// If MAIL_PREFIX_FOR_EMAIL_ID is set and prefix is for email
if ($mode == 'email' && ! empty($conf->global->MAIL_PREFIX_FOR_EMAIL_ID))
{
@@ -375,15 +378,15 @@ function dol_buildpath($path, $type=0)
if ($type == 1) $res = DOL_URL_ROOT.'/'.$path; // Standard value
if ($type == 2) $res = DOL_MAIN_URL_ROOT.'/'.$path; // Standard value
if ($type == 3) $res = DOL_URL_ROOT.'/'.$path;
-
+
foreach ($conf->file->dol_document_root as $key => $dirroot) // ex: array(["main"]=>"/home/main/htdocs", ["alt0"]=>"/home/dirmod/htdocs", ...)
{
- if ($key == 'main')
+ if ($key == 'main')
{
if ($type == 3)
{
global $dolibarr_main_url_root;
-
+
// Define $urlwithroot
$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
@@ -410,12 +413,12 @@ function dol_buildpath($path, $type=0)
if ($type == 3)
{
global $dolibarr_main_url_root;
-
+
// Define $urlwithroot
$urlwithouturlroot=preg_replace('/'.preg_quote(DOL_URL_ROOT,'/').'$/i','',trim($dolibarr_main_url_root));
$urlwithroot=$urlwithouturlroot.DOL_URL_ROOT; // This is to use external domain name found into config file
//$urlwithroot=DOL_MAIN_URL_ROOT; // This is to use same domain name than current
-
+
$res=(preg_match('/^http/i',$conf->file->dol_url_root[$key])?'':$urlwithroot).$conf->file->dol_url_root[$key].'/'.$path; // Test on start with http is for old conf syntax
}
break;
@@ -954,7 +957,7 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r
$maxvisiblephotos=(isset($conf->global->PRODUCT_MAX_VISIBLE_PHOTO)?$conf->global->PRODUCT_MAX_VISIBLE_PHOTO:5);
if ($conf->browser->phone) $maxvisiblephotos=1;
if ($showimage) $morehtmlleft.='
'; // For thirdparty
if (! empty($object->label)) $morehtmlref.='
'.$object->label.'
'; // For product
- if ($object->element != 'product')
+ if ($object->element != 'product')
{
$morehtmlref.='
';
$morehtmlref.=$object->getBannerAddress('refaddress',$object);
@@ -1181,9 +1184,9 @@ function dol_print_date($time,$format='',$tzoutput='tzserver',$outputlangs='',$e
$reduceformat=(! empty($conf->dol_optimize_smallscreen) && in_array($format,array('day','dayhour')))?1:0;
$formatwithoutreduce = preg_replace('/reduceformat/','',$format);
if ($formatwithoutreduce != $format) { $format = $formatwithoutreduce; $reduceformat=1; } // so format 'dayreduceformat' is processed like day
-
+
// Change predefined format into computer format. If found translation in lang file we use it, otherwise we use default.
- // TODO Add format daysmallyear and dayhoursmallyear
+ // TODO Add format daysmallyear and dayhoursmallyear
if ($format == 'day') $format=($outputlangs->trans("FormatDateShort")!="FormatDateShort"?$outputlangs->trans("FormatDateShort"):$conf->format_date_short);
else if ($format == 'hour') $format=($outputlangs->trans("FormatHourShort")!="FormatHourShort"?$outputlangs->trans("FormatHourShort"):$conf->format_hour_short);
else if ($format == 'hourduration') $format=($outputlangs->trans("FormatHourShortDuration")!="FormatHourShortDuration"?$outputlangs->trans("FormatHourShortDuration"):$conf->format_hour_short_duration);
@@ -1954,7 +1957,7 @@ function dol_print_graph($htmlid,$width,$height,$data,$showlegend=0,$type='pie',
print '
'.$langs->trans("NotEnoughDataYet").'
';
return;
}
-
+
if (empty($conf->use_javascript_ajax)) return;
$jsgraphlib='flot';
$datacolor=array();
@@ -2123,7 +2126,7 @@ function dol_trunc($string,$size=40,$trunc='right',$stringencoding='UTF-8',$nodo
global $conf;
if ($size==0 || ! empty($conf->global->MAIN_DISABLE_TRUNC)) return $string;
-
+
if (empty($stringencoding)) $stringencoding='UTF-8';
// reduce for small screen
if ($conf->dol_optimize_smallscreen==1 && $display==1) $size = round($size/3);
@@ -3073,7 +3076,7 @@ function load_fiche_titre($titre, $mesg='', $picto='title_generic.png', $pictois
* @param string $options parametres complementaires lien ('' par defaut)
* @param string $sortfield champ de tri ('' par defaut)
* @param string $sortorder ordre de tri ('' par defaut)
- * @param string $center chaine du centre ('' par defaut). We often find here string $massaction comming from $form->selectMassAction()
+ * @param string $center chaine du centre ('' par defaut). We often find here string $massaction comming from $form->selectMassAction()
* @param int $num number of records found by select with limit+1
* @param int $totalnboflines Total number of records/lines for all pages (if known). Use a negative value to no show number.
* @param string $picto Icon to use before title (should be a 32x32 transparent png file)
@@ -3087,11 +3090,11 @@ function load_fiche_titre($titre, $mesg='', $picto='title_generic.png', $pictois
function print_barre_liste($titre, $page, $file, $options='', $sortfield='', $sortorder='', $center='', $num=-1, $totalnboflines=0, $picto='title_generic.png', $pictoisfullpath=0, $morehtml='', $morecss='', $limit=-1, $hideselectlimit=0)
{
global $conf,$langs;
-
+
$savlimit = $limit;
$savtotalnboflines = $totalnboflines;
$totalnboflines=abs($totalnboflines);
-
+
if ($picto == 'setup') $picto='title_setup.png';
if (($conf->browser->name == 'ie') && $picto=='title_generic.png') $picto='title.gif';
if ($limit < 0) $limit = $conf->liste_limit;
@@ -3104,7 +3107,7 @@ function print_barre_liste($titre, $page, $file, $options='', $sortfield='', $so
$nextpage = 0;
}
//print 'totalnboflines='.$totalnboflines.'-savlimit='.$savlimit.'-limit='.$limit.'-num='.$num.'-nextpage='.$nextpage;
-
+
print "\n";
print "\n";
print '
';
@@ -3203,7 +3206,7 @@ function print_fleche_navigation($page, $file, $options='', $nextpage=0, $betwee
//$pagesizechoices.=',0:'.$langs->trans("All"); // Not yet supported
//$pagesizechoices.=',2:2';
if (! empty($conf->global->MAIN_PAGESIZE_CHOICES)) $pagesizechoices=$conf->global->MAIN_PAGESIZE_CHOICES;
-
+
print '
';
print '
';
+ print '';
}
if ($page > 0)
{
@@ -3282,7 +3285,7 @@ function print_fleche_navigation($page, $file, $options='', $nextpage=0, $betwee
function vatrate($rate,$addpercent=false,$info_bits=0,$usestarfornpr=0)
{
$morelabel='';
-
+
if (preg_match('/%/',$rate))
{
$rate=str_replace('%','',$rate);
@@ -3485,7 +3488,7 @@ function price2num($amount,$rounding='',$alreadysqlnb=0)
/**
* Output a dimension with best unit
- *
+ *
* @param float $dimension Dimension
* @param int $unit Unit of dimension (0, -3, ...)
* @param string $type 'weight', 'volume', ...
@@ -3497,16 +3500,16 @@ function price2num($amount,$rounding='',$alreadysqlnb=0)
function showDimensionInBestUnit($dimension, $unit, $type, $outputlangs, $round=-1, $forceunitoutput='no')
{
require_once DOL_DOCUMENT_ROOT.'/core/lib/product.lib.php';
-
- if (($forceunitoutput == 'no' && $dimension < 1/10000) || (is_numeric($forceunitoutput) && $forceunitoutput == -6))
+
+ if (($forceunitoutput == 'no' && $dimension < 1/10000) || (is_numeric($forceunitoutput) && $forceunitoutput == -6))
{
$dimension = $dimension * 1000000;
- $unit = $unit - 6;
+ $unit = $unit - 6;
}
elseif (($forceunitoutput == 'no' && $dimension < 1/10) || (is_numeric($forceunitoutput) && $forceunitoutput == -3))
{
$dimension = $dimension * 1000;
- $unit = $unit - 3;
+ $unit = $unit - 3;
}
elseif (($forceunitoutput == 'no' && $dimension > 100000000) || (is_numeric($forceunitoutput) && $forceunitoutput == 6))
{
@@ -3518,9 +3521,9 @@ function showDimensionInBestUnit($dimension, $unit, $type, $outputlangs, $round=
$dimension = $dimension / 1000;
$unit = $unit + 3;
}
-
+
$ret=price($dimension, 0, $outputlangs, 0, 0, $round).' '.measuring_units_string($unit, $type);
-
+
return $ret;
}
@@ -3551,12 +3554,12 @@ function get_localtax($vatrate, $local, $thirdparty_buyer="", $thirdparty_seller
$vatratecleaned = trim($reg[1]);
$vatratecode = $reg[2];
}
-
+
/*if ($thirdparty_buyer->country_code != $thirdparty_seller->country_code)
{
return 0;
}*/
-
+
// Some test to guess with no need to make database access
if ($mysoc->country_code == 'ES') // For spain localtaxes 1 and 2, tax is qualified if buyer use local taxe
{
@@ -3597,7 +3600,7 @@ function get_localtax($vatrate, $local, $thirdparty_buyer="", $thirdparty_seller
{
$conf->global->MAIN_GET_LOCALTAXES_VALUES_FROM_THIRDPARTY = 1;
}
-
+
// Search local taxes
if (! empty($conf->global->MAIN_GET_LOCALTAXES_VALUES_FROM_THIRDPARTY))
{
@@ -3654,7 +3657,7 @@ function get_localtax($vatrate, $local, $thirdparty_buyer="", $thirdparty_seller
if ($local==1) return $obj->localtax1;
elseif ($local==2) return $obj->localtax2;
}
-
+
return 0;
}
@@ -3714,7 +3717,7 @@ function get_localtax_by_third($local)
/**
* Get vat rate and npr from id.
- * You can call getLocalTaxesFromRate after to get other fields
+ * You can call getLocalTaxesFromRate after to get other fields
*
* @param int $vatrowid Line ID into vat rate table.
* @return array array(localtax_type1(1-6 / 0 if not found), rate of localtax1, ...)
@@ -3768,7 +3771,7 @@ function getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisi
$vatratecleaned = $reg[1];
$vatratecode = $reg[2];
}
-
+
// Search local taxes
$sql = "SELECT t.localtax1, t.localtax1_type, t.localtax2, t.localtax2_type, t.accountancy_code_sell, t.accountancy_code_buy";
$sql .= " FROM ".MAIN_DB_PREFIX."c_tva as t";
@@ -3781,7 +3784,7 @@ function getLocalTaxesFromRate($vatrate, $local, $buyer, $seller, $firstparamisi
$sql.= " AND t.taux = ".((float) $vatratecleaned)." AND t.active = 1";
if ($vatratecode) $sql.= " AND t.code ='".$vatratecode."'";
}
-
+
$resql=$db->query($sql);
if ($resql)
{
@@ -4188,7 +4191,7 @@ function yn($yesno, $case=1, $color=0)
/**
* Return a path to have a directory according to object.
* New usage: $conf->product->multidir_output[$object->entity].'/'.get_exdir(0, 0, 0, 1, $object, 'modulepart')
- * Old usage: '015' with level 3->"0/1/5/", '015' with level 1->"5/", 'ABC-1' with level 3 ->"0/0/1/"
+ * Old usage: '015' with level 3->"0/1/5/", '015' with level 1->"5/", 'ABC-1' with level 3 ->"0/0/1/"
*
* @param string $num Id of object (deprecated, $object will be used in future)
* @param int $level Level of subdirs to return (1, 2 or 3 levels). (deprecated, global option will be used in future)
@@ -4205,7 +4208,7 @@ function get_exdir($num,$level,$alpha,$withoutslash,$object,$modulepart)
$path = '';
$arrayforoldpath=array('cheque','user','category','holiday','shipment', 'member','don','donation','supplier_invoice','invoice_supplier','mailing');
- if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) $arrayforoldpath[]='product';
+ if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO)) $arrayforoldpath[]='product';
if (! empty($level) && in_array($modulepart, $arrayforoldpath))
{
// This part should be removed once all code is using "get_exdir" to forge path, with all parameters provided
@@ -4357,7 +4360,7 @@ function dolGetFirstLineOfText($text)
{
$firstline=preg_replace('/ ]*>.*$/s','',$text); // The s pattern modifier means the . can match newline characters
$firstline=preg_replace('/
]*>.*$/s','',$firstline); // The s pattern modifier means the . can match newline characters
-
+
}
else
{
@@ -5383,11 +5386,11 @@ function printCommonFooter($zone='private')
{
print ''."\n";
print ''."\n";
}
-
+
// Google Analytics (need Google module)
if (! empty($conf->google->enabled) && ! empty($conf->global->MAIN_GOOGLE_AN_ID))
{
@@ -5620,15 +5623,15 @@ function natural_search($fields, $value, $mode=0, $nofirstand=0)
$tmpcrit=trim($tmpcrit);
$tmpcrit2=$tmpcrit;
$tmpbefore='%'; $tmpafter='%';
- if (preg_match('/^[\^\$]/', $tmpcrit))
- {
+ if (preg_match('/^[\^\$]/', $tmpcrit))
+ {
$tmpbefore='';
- $tmpcrit2 = preg_replace('/^[\^\$]/', '', $tmpcrit2);
+ $tmpcrit2 = preg_replace('/^[\^\$]/', '', $tmpcrit2);
}
- if (preg_match('/[\^\$]$/', $tmpcrit))
- {
+ if (preg_match('/[\^\$]$/', $tmpcrit))
+ {
$tmpafter='';
- $tmpcrit2 = preg_replace('/[\^\$]$/', '', $tmpcrit2);
+ $tmpcrit2 = preg_replace('/[\^\$]$/', '', $tmpcrit2);
}
$newres .= $tmpbefore;
$newres .= $db->escape($tmpcrit2);
diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php
index d682aa2db97..f98357bb698 100644
--- a/htdocs/core/modules/DolibarrModules.class.php
+++ b/htdocs/core/modules/DolibarrModules.class.php
@@ -48,22 +48,22 @@ class DolibarrModules // Can not be abstract, because we need to insta
* @var string Publisher name
*/
public $editor_name;
-
+
/**
* @var string URL of module at publisher site
*/
- public $editor_web;
-
+ public $editor_web;
+
/**
* @var string Family
*/
public $family;
-
+
/**
* @var int module_position
*/
public $module_position=500;
-
+
/**
* @var string Module name
*/
@@ -171,7 +171,7 @@ class DolibarrModules // Can not be abstract, because we need to insta
* @var string Module description (long text)
*/
public $descriptionlong;
-
+
/**
* @var string[] Module language files
*/
@@ -211,7 +211,7 @@ class DolibarrModules // Can not be abstract, because we need to insta
* @var bool Module is enabled globally (Multicompany support)
*/
public $core_enabled;
-
+
/**
* @var string Relative path to module style sheet
* @deprecated
@@ -219,8 +219,8 @@ class DolibarrModules // Can not be abstract, because we need to insta
*/
public $style_sheet = '';
-
-
+
+
/**
* Constructor. Define names, constants, directories, boxes, permissions
*
@@ -468,9 +468,9 @@ class DolibarrModules // Can not be abstract, because we need to insta
{
global $langs;
$langs->load("admin");
-
+
if (empty($this->descriptionlong)) return '';
-
+
// If module description translation does not exist using its unique id, we can use its name to find translation
if (is_array($this->langfiles))
{
@@ -481,7 +481,7 @@ class DolibarrModules // Can not be abstract, because we need to insta
}
return $langs->trans($this->descriptionlong);
}
-
+
/**
* Gives the publisher name
*
@@ -491,7 +491,7 @@ class DolibarrModules // Can not be abstract, because we need to insta
{
return $this->editor_name;
}
-
+
/**
* Gives the publisher url
*
@@ -501,7 +501,7 @@ class DolibarrModules // Can not be abstract, because we need to insta
{
return $this->editor_url;
}
-
+
/**
* Gives module version (translated if param $translated is on)
* For 'experimental' modules, gives 'experimental' translation
@@ -705,7 +705,7 @@ class DolibarrModules // Can not be abstract, because we need to insta
$files[] = $file;
}
sort($files);
- foreach ($files as $file)
+ foreach ($files as $file)
{
if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'llx_' && substr($file,0,4) != 'data')
{
@@ -723,7 +723,7 @@ class DolibarrModules // Can not be abstract, because we need to insta
$files[] = $file;
}
sort($files);
- foreach ($files as $file)
+ foreach ($files as $file)
{
if (preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'llx_' && substr($file,0,4) != 'data')
{
@@ -741,7 +741,7 @@ class DolibarrModules // Can not be abstract, because we need to insta
$files[] = $file;
}
sort($files);
- foreach ($files as $file)
+ foreach ($files as $file)
{
if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'data')
{
@@ -759,7 +759,7 @@ class DolibarrModules // Can not be abstract, because we need to insta
$files[] = $file;
}
sort($files);
- foreach ($files as $file)
+ foreach ($files as $file)
{
if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,6) == 'update')
{
@@ -899,19 +899,19 @@ class DolibarrModules // Can not be abstract, because we need to insta
//$titre = $this->boxes[$key][0];
$file = $this->boxes[$key]['file'];
//$note = $this->boxes[$key][2];
-
+
// TODO If the box is also included by another module and the other module is still on, we should not remove it.
// For the moment, we manage this with hard coded exception
//print "Remove box ".$file.' ';
if ($file == 'box_graph_product_distribution.php')
{
- if (! empty($conf->produit->enabled) || ! empty($conf->service->enabled))
+ if (! empty($conf->produit->enabled) || ! empty($conf->service->enabled))
{
dol_syslog("We discard disabling of module ".$file." because another module still active require it.");
continue;
}
}
-
+
if (empty($file)) $file = isset($this->boxes[$key][1])?$this->boxes[$key][1]:''; // For backward compatibility
if ($this->db->type == 'sqlite3') {
@@ -986,7 +986,7 @@ class DolibarrModules // Can not be abstract, because we need to insta
$status = isset($this->cronjobs[$key]['status'])?$this->cronjobs[$key]['status']:'';
$priority = isset($this->cronjobs[$key]['priority'])?$this->cronjobs[$key]['priority']:'';
$test = isset($this->cronjobs[$key]['test'])?$this->cronjobs[$key]['test']:''; // Line must be visible
-
+
// Search if boxes def already present
$sql = "SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."cronjob";
$sql.= " WHERE module_name = '".$this->db->escape($this->rights_class)."'";
@@ -1124,55 +1124,55 @@ class DolibarrModules // Can not be abstract, because we need to insta
*
* @return int Error count (0 if ok)
*/
- function insert_tabs()
- {
- global $conf;
+ function insert_tabs()
+ {
+ global $conf;
- $err=0;
+ $err=0;
- if (! empty($this->tabs))
- {
- $i=0;
- foreach ($this->tabs as $key => $value)
- {
- if (is_array($value) && count($value) == 0) continue; // Discard empty arrays
+ if (! empty($this->tabs))
+ {
+ $i=0;
+ foreach ($this->tabs as $key => $value)
+ {
+ if (is_array($value) && count($value) == 0) continue; // Discard empty arrays
- $entity=$conf->entity;
- $newvalue = $value;
+ $entity=$conf->entity;
+ $newvalue = $value;
- if (is_array($value))
- {
- $newvalue = $value['data'];
- if (isset($value['entity'])) $entity = $value['entity'];
- }
+ if (is_array($value))
+ {
+ $newvalue = $value['data'];
+ if (isset($value['entity'])) $entity = $value['entity'];
+ }
- if ($newvalue)
- {
- $sql = "INSERT INTO ".MAIN_DB_PREFIX."const (";
- $sql.= "name";
- $sql.= ", type";
- $sql.= ", value";
- $sql.= ", note";
- $sql.= ", visible";
- $sql.= ", entity";
- $sql.= ")";
- $sql.= " VALUES (";
- $sql.= $this->db->encrypt($this->const_name."_TABS_".$i,1);
- $sql.= ", 'chaine'";
- $sql.= ", ".$this->db->encrypt($value,1);
- $sql.= ", null";
- $sql.= ", '0'";
- $sql.= ", ".$conf->entity;
- $sql.= ")";
+ if ($newvalue)
+ {
+ $sql = "INSERT INTO ".MAIN_DB_PREFIX."const (";
+ $sql.= "name";
+ $sql.= ", type";
+ $sql.= ", value";
+ $sql.= ", note";
+ $sql.= ", visible";
+ $sql.= ", entity";
+ $sql.= ")";
+ $sql.= " VALUES (";
+ $sql.= $this->db->encrypt($this->const_name."_TABS_".$i,1);
+ $sql.= ", 'chaine'";
+ $sql.= ", ".$this->db->encrypt($newvalue,1);
+ $sql.= ", null";
+ $sql.= ", '0'";
+ $sql.= ", ".$entity;
+ $sql.= ")";
- dol_syslog(get_class($this)."::insert_tabs", LOG_DEBUG);
- $this->db->query($sql);
- }
- $i++;
- }
- }
- return $err;
- }
+ dol_syslog(get_class($this)."::insert_tabs", LOG_DEBUG);
+ $this->db->query($sql);
+ }
+ $i++;
+ }
+ }
+ return $err;
+ }
/**
* Adds constants
diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
index 52971f76770..57c8d55c983 100644
--- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
+++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php
@@ -1120,7 +1120,26 @@ class pdf_crabe extends ModelePDFFactures
}
//}
+
// VAT
+ // Situations totals migth be wrong on huge amounts
+ if ($object->situation_cycle_ref && $object->situation_counter > 1) {
+
+ $sum_pdf_tva = 0;
+ foreach($this->tva as $tvakey => $tvaval){
+ $sum_pdf_tva+=$tvaval; // sum VAT amounts to compare to object
+ }
+
+ if($sum_pdf_tva!=$object->total_tva) { // apply coef to recover the VAT object amount (the good one)
+ $coef_fix_tva = $object->total_tva / $sum_pdf_tva;
+
+ foreach($this->tva as $tvakey => $tvaval) {
+ $this->tva[$tvakey]=$tvaval * $coef_fix_tva;
+ }
+ }
+
+ }
+
foreach($this->tva as $tvakey => $tvaval)
{
if ($tvakey != 0) // On affiche pas taux 0
diff --git a/htdocs/core/search_page.php b/htdocs/core/search_page.php
index 09b37f4bb8a..c0d98a001b8 100644
--- a/htdocs/core/search_page.php
+++ b/htdocs/core/search_page.php
@@ -35,7 +35,7 @@ if (! defined('NOREQUIREMENU')) define('NOREQUIREMENU',1);
require_once '../main.inc.php';
-if (GETPOST('lang')) $langs->setDefaultLang(GETPOST('lang')); // If language was forced on URL by the main.inc.php
+if (GETPOST('lang', 'aZ09')) $langs->setDefaultLang(GETPOST('lang', 'aZ09')); // If language was forced on URL by the main.inc.php
$langs->load("main");
$right=($langs->trans("DIRECTION")=='rtl'?'left':'right');
$left=($langs->trans("DIRECTION")=='rtl'?'right':'left');
@@ -76,11 +76,11 @@ if ($conf->use_javascript_ajax && 1 == 2) // select2 is ko with jmobile
else
{
$conf->global->MAIN_HTML5_PLACEHOLDER = 1;
-
-
+
+
$usedbyinclude = 1; // Used into next include
include DOL_DOCUMENT_ROOT.'/core/ajax/selectsearchbox.php';
-
+
$accesskeyalreadyassigned=array();
foreach($arrayresult as $key => $val)
{
diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php
index bd1d74e35b8..5fba81a3422 100644
--- a/htdocs/cron/class/cronjob.class.php
+++ b/htdocs/cron/class/cronjob.class.php
@@ -108,7 +108,7 @@ class Cronjob extends CommonObject
if (isset($this->nbrun)) $this->nbrun=trim($this->nbrun);
if (isset($this->libname)) $this->libname = trim($this->libname);
if (isset($this->test)) $this->test = trim($this->test);
-
+
// Check parameters
// Put here code to add a control on parameters values
if (dol_strlen($this->datestart)==0) {
@@ -363,9 +363,9 @@ class Cronjob extends CommonObject
function fetch_all($sortorder='DESC', $sortfield='t.rowid', $limit=0, $offset=0, $status=1, $filter='')
{
global $langs;
-
+
$this->lines=array();
-
+
$sql = "SELECT";
$sql.= " t.rowid,";
$sql.= " t.entity,";
@@ -403,7 +403,7 @@ class Cronjob extends CommonObject
if ($status == 2) $sql.= " AND t.status = 2";
//Manage filter
if (is_array($filter) && count($filter)>0) {
- foreach($filter as $key => $value)
+ foreach($filter as $key => $value)
{
if ($key == 't.rowid') $sql.= ' AND '.$key.' = '.$this->db->escape($value);
else $sql.= ' AND '.$key.' LIKE \'%'.$this->db->escape($value).'%\'';
@@ -526,7 +526,7 @@ class Cronjob extends CommonObject
if (empty($this->maxrun)) $this->maxrun=0;
if (isset($this->libname)) $this->libname = trim($this->libname);
if (isset($this->test)) $this->test = trim($this->test);
-
+
// Check parameters
// Put here code to add a control on parameters values
if (dol_strlen($this->datestart)==0) {
@@ -837,8 +837,8 @@ class Cronjob extends CommonObject
/**
* Run a job.
- * Once job is finished, status and nb of run is updated.
- * This function does not plan the next run. This is done by function ->reprogram_jobs
+ * Once job is finished, status and nb of run is updated.
+ * This function does not plan the next run. This is done by function ->reprogram_jobs
*
* @param string $userlogin User login
* @return int <0 if KO, >0 if OK
@@ -853,7 +853,7 @@ class Cronjob extends CommonObject
$langs->load('cron');
- if (empty($userlogin))
+ if (empty($userlogin))
{
$this->error="User login is mandatory";
dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR);
@@ -914,16 +914,16 @@ class Cronjob extends CommonObject
// load classes
if (! $error)
{
- $ret=dol_include_once($this->classesname);
- if ($ret===false || (! class_exists($this->objectname)))
- {
- $this->error=$langs->trans('CronCannotLoadClass',$this->classesname,$this->objectname);
- dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR);
- $this->lastoutput = $this->error;
- $this->lastresult = -1;
- $retval = $this->lastresult;
- $error++;
- }
+ $ret=dol_include_once($this->classesname);
+ if ($ret===false || (! class_exists($this->objectname)))
+ {
+ $this->error=$langs->trans('CronCannotLoadClass',$this->classesname,$this->objectname);
+ dol_syslog(get_class($this)."::run_jobs ".$this->error, LOG_ERR);
+ $this->lastoutput = $this->error;
+ $this->lastresult = -1;
+ $retval = $this->lastresult;
+ $error++;
+ }
}
// test if method exists
@@ -939,7 +939,7 @@ class Cronjob extends CommonObject
$error++;
}
}
-
+
// Load langs
if (! $error)
{
@@ -954,14 +954,14 @@ class Cronjob extends CommonObject
$error++;
}
}
-
+
if (! $error)
{
dol_syslog(get_class($this)."::run_jobs START ".$this->objectname."->".$this->methodename."(".$this->params.");", LOG_DEBUG);
-
+
// Create Object for the call module
$object = new $this->objectname($this->db);
-
+
$params_arr = explode(", ",$this->params);
if (!is_array($params_arr))
{
@@ -971,8 +971,8 @@ class Cronjob extends CommonObject
{
$result = call_user_func_array(array($object, $this->methodename), $params_arr);
}
-
- if ($result===false || $result != 0)
+
+ if ($result === false || (! is_bool($result) && $result != 0))
{
$langs->load("errors");
dol_syslog(get_class($this)."::run_jobs END result=".$result." error=".$object->error, LOG_ERR);
@@ -989,7 +989,7 @@ class Cronjob extends CommonObject
$this->lastresult=var_export($result,true);
$retval = $this->lastresult;
}
- }
+ }
}
if($this->jobtype == 'function')
@@ -1021,7 +1021,7 @@ class Cronjob extends CommonObject
$result = call_user_func_array($this->methodename, $params_arr);
}
- if ($result === false || $result != 0)
+ if ($result === false || (! is_bool($result) && $result != 0))
{
$langs->load("errors");
dol_syslog(get_class($this)."::run_jobs result=".$result, LOG_ERR);
@@ -1062,7 +1062,7 @@ class Cronjob extends CommonObject
$this->lastoutput = ''; // Will be filled later
$this->lastresult = $retval;
$retval = $this->lastresult;
- $error++;
+ $error++;
}
}
if ($execmethod == 2)
@@ -1086,21 +1086,21 @@ class Cronjob extends CommonObject
}
// Update with result
- if (is_array($output_arr) && count($output_arr)>0)
- {
- foreach($output_arr as $val)
- {
- $this->lastoutput.=$val."\n";
- }
- }
-
- $this->lastresult=$retval;
-
- dol_syslog(get_class($this)."::run_jobs output_arr:".var_export($output_arr,true)." lastoutput=".$this->lastoutput." lastresult=".$this->lastresult, LOG_DEBUG);
+ if (is_array($output_arr) && count($output_arr)>0)
+ {
+ foreach($output_arr as $val)
+ {
+ $this->lastoutput.=$val."\n";
+ }
+ }
+
+ $this->lastresult=$retval;
+
+ dol_syslog(get_class($this)."::run_jobs output_arr:".var_export($output_arr,true)." lastoutput=".$this->lastoutput." lastresult=".$this->lastresult, LOG_DEBUG);
}
-
+
dol_syslog(get_class($this)."::run_jobs now we update job to track it is finished (with success or error)");
-
+
$this->datelastresult=dol_now();
$result = $this->update($user); // This include begin/commit
if ($result < 0)
@@ -1125,19 +1125,19 @@ class Cronjob extends CommonObject
function reprogram_jobs($userlogin, $now)
{
dol_syslog(get_class($this)."::reprogram_jobs userlogin:$userlogin", LOG_DEBUG);
-
+
require_once DOL_DOCUMENT_ROOT.'/user/class/user.class.php';
$user=new User($this->db);
$result=$user->fetch('',$userlogin);
- if ($result<0)
+ if ($result<0)
{
$this->error="User Error:".$user->error;
dol_syslog(get_class($this)."::reprogram_jobs ".$this->error, LOG_ERR);
return -1;
}
- else
+ else
{
- if (empty($user->id))
+ if (empty($user->id))
{
$this->error=" User user login:".$userlogin." do not exists";
dol_syslog(get_class($this)."::reprogram_jobs ".$this->error, LOG_ERR);
@@ -1147,24 +1147,24 @@ class Cronjob extends CommonObject
dol_syslog(get_class($this)."::reprogram_jobs ", LOG_DEBUG);
-
- if (empty($this->datenextrun))
+
+ if (empty($this->datenextrun))
{
if (empty($this->datestart)) $this->datenextrun = $now + ($this->frequency * $this->unitfrequency);
else $this->datenextrun = $this->datestart + ($this->frequency * $this->unitfrequency);
}
- if ($this->datenextrun < $now && $this->frequency > 0 && $this->unitfrequency > 0)
+ if ($this->datenextrun < $now && $this->frequency > 0 && $this->unitfrequency > 0)
{
// Loop until date is after future
while ($this->datenextrun < $now)
{
$this->datenextrun += ($this->frequency * $this->unitfrequency);
-
+
// TODO For exact frequency (every month, every year, ...), use instead a dol_time_plus_duree($time, $duration_value, $duration_unit)
}
}
- else
+ else
{
//$this->datenextrun=$this->datenextrun + ($this->frequency * $this->unitfrequency);
}
@@ -1180,9 +1180,9 @@ class Cronjob extends CommonObject
dol_syslog(get_class($this)."::reprogram_jobs Job will be set to archived", LOG_ERR);
}
}
-
+
$result = $this->update($user);
- if ($result<0)
+ if ($result<0)
{
dol_syslog(get_class($this)."::reprogram_jobs ".$this->error, LOG_ERR);
return -1;
diff --git a/htdocs/externalsite/frames.php b/htdocs/externalsite/frames.php
index c0b5cf92e7e..adf9d547073 100644
--- a/htdocs/externalsite/frames.php
+++ b/htdocs/externalsite/frames.php
@@ -38,7 +38,7 @@ $mainmenu=GETPOST('mainmenu', 'alpha');
$leftmenu=GETPOST('leftmenu', 'alpha');
$idmenu=GETPOST('idmenu', 'int');
$theme=GETPOST('theme', 'alpha');
-$codelang=GETPOST('lang', 'alpha');
+$codelang=GETPOST('lang', 'aZ09');
print "
diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php
index d2ca04278ff..13349d3c1da 100644
--- a/htdocs/filefunc.inc.php
+++ b/htdocs/filefunc.inc.php
@@ -31,7 +31,7 @@
*/
if (! defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE','Dolibarr');
-if (! defined('DOL_VERSION')) define('DOL_VERSION','4.0.6');
+if (! defined('DOL_VERSION')) define('DOL_VERSION','4.0.7');
if (! defined('EURO')) define('EURO',chr(128));
diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php
index e9b143382ad..5bfae3c955f 100644
--- a/htdocs/fourn/commande/card.php
+++ b/htdocs/fourn/commande/card.php
@@ -2585,19 +2585,29 @@ elseif (! empty($object->id))
// Create bill
if (! empty($conf->facture->enabled))
{
- if (! empty($conf->fournisseur->enabled) && ($object->statut >= 2 && $object->billed != 1)) // 2 means accepted
+ if (! empty($conf->fournisseur->enabled) && ($object->statut >= 2 && $object->billed != 1)) // statut 2 means approved
{
if ($user->rights->fournisseur->facture->creer)
{
print ''.$langs->trans("CreateBill").'';
}
-
- if ($user->rights->fournisseur->commande->creer && $object->statut >= 2 && !empty($object->linkedObjectsIds['invoice_supplier']))
- {
- print 'id.'&action=classifybilled">'.$langs->trans("ClassifyBilled").'';
- }
}
+ }
+ // Classify billed manually (need one invoice if module invoice is on, no condition on invoice if not)
+ if ($user->rights->fournisseur->commande->creer && $object->statut >= 2 && $object->billed != 1) // statut 2 means approved
+ {
+ if (empty($conf->facture->enabled))
+ {
+ print 'id.'&action=classifybilled">'.$langs->trans("ClassifyBilled").'';
+ }
+ else if (!empty($object->linkedObjectsIds['invoice_supplier']))
+ {
+ if ($user->rights->fournisseur->facture->creer)
+ {
+ print 'id.'&action=classifybilled">'.$langs->trans("ClassifyBilled").'';
+ }
+ }
}
// Create a remote order using WebService only if module is activated
diff --git a/htdocs/holiday/card.php b/htdocs/holiday/card.php
index 016984c5382..b4c2c71959b 100644
--- a/htdocs/holiday/card.php
+++ b/htdocs/holiday/card.php
@@ -3,7 +3,7 @@
* Copyright (C) 2012-2015 Laurent Destailleur
* Copyright (C) 2012-2016 Regis Houssin
* Copyright (C) 2013 Juanjo Menent
- * Copyright (C) 2014 Ferran Marcet
+ * Copyright (C) 2014-2017 Ferran Marcet
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
@@ -39,7 +39,6 @@ require_once DOL_DOCUMENT_ROOT.'/holiday/common.inc.php';
$myparam = GETPOST("myparam");
$action=GETPOST('action', 'alpha');
$id=GETPOST('id', 'int');
-$userid = GETPOST('userid')?GETPOST('userid'):$user->id;
// Protection if external user
if ($user->societe_id > 0) accessforbidden();
@@ -57,7 +56,8 @@ if ($action == 'create')
$cp = new Holiday($db);
// If no right to create a request
- if (($userid == $user->id && empty($user->rights->holiday->write)) || ($userid != $user->id && empty($user->rights->holiday->write_all)))
+ $fuserid = GETPOST('fuserid');
+ if (($fuserid == $user->id && empty($user->rights->holiday->write)) || ($fuserid != $user->id && empty($user->rights->holiday->write_all)))
{
$error++;
setEventMessages($langs->trans('CantCreateCP'), null, 'errors');
@@ -82,7 +82,6 @@ if ($action == 'create')
$valideur = GETPOST('valideur');
$description = trim(GETPOST('description'));
- $userID = GETPOST('userID');
// If no type
if ($type <= 0)
@@ -115,7 +114,7 @@ if ($action == 'create')
}
// Check if there is already holiday for this period
- $verifCP = $cp->verifDateHolidayCP($userID, $date_debut, $date_fin, $halfday);
+ $verifCP = $cp->verifDateHolidayCP($fuserid, $date_debut, $date_fin, $halfday);
if (! $verifCP)
{
setEventMessages($langs->trans("alreadyCPexist"), null, 'errors');
@@ -145,7 +144,7 @@ if ($action == 'create')
if (! $error)
{
- $cp->fk_user = $userid;
+ $cp->fk_user = $fuserid;
$cp->description = $description;
$cp->date_debut = $date_debut;
$cp->date_fin = $date_fin;
@@ -689,7 +688,7 @@ llxHeader('', $langs->trans('CPTitreMenu'));
if (empty($id) || $action == 'add' || $action == 'request' || $action == 'create')
{
// Si l'utilisateur n'a pas le droit de faire une demande
- if (($userid == $user->id && empty($user->rights->holiday->write)) || ($userid != $user->id && empty($user->rights->holiday->write_all)))
+ if (($fuserid == $user->id && empty($user->rights->holiday->write)) || ($fuserid != $user->id && empty($user->rights->holiday->write_all)))
{
$errors[]=$langs->trans('CantCreateCP');
}
@@ -769,7 +768,6 @@ if (empty($id) || $action == 'add' || $action == 'request' || $action == 'create
// Formulaire de demande
print '
';
diff --git a/htdocs/install/inc.php b/htdocs/install/inc.php
index a0d873d4f5c..c0d89083325 100644
--- a/htdocs/install/inc.php
+++ b/htdocs/install/inc.php
@@ -258,7 +258,7 @@ if (function_exists('get_magic_quotes_gpc')) // magic_quotes_* removed in PHP 5.
// Defini objet langs
$langs = new Translate('..',$conf);
-if (GETPOST('lang')) $langs->setDefaultLang(GETPOST('lang'));
+if (GETPOST('lang', 'aZ09')) $langs->setDefaultLang(GETPOST('lang', 'aZ09'));
else $langs->setDefaultLang('auto');
$bc[false]=' class="bg1"';
@@ -442,9 +442,9 @@ function pFooter($nonext=0,$setuplang='',$jscheckfunction='', $withpleasewait=0)
print '
';
if ($nonext == '2')
{
- print $langs->trans("ErrorFoundDuringMigration", $_SERVER["REQUEST_URI"].'&ignoreerrors=1').'