diff --git a/ChangeLog b/ChangeLog index d4bcd3ea17c..c672c02a7a0 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,41 @@ English Dolibarr ChangeLog -------------------------------------------------------------- +***** ChangeLog for 8.0.6 compared to 8.0.5 ***** +FIX: #11244 +FIX: #11316 +FIX: Add missing end date of subscription in export +FIX: A user may read holiday and expense report without permissions +FIX: better syntax +FIX: condition +FIX: confirmation of mass email sending + option MAILING_NO_USING_PHPMAIL +FIX: crabe pdf: bad detailed VAT for situation invoices, in situations S2 and above +FIX: default value for duration of validity can be set from generic +FIX: do not include disabled modules tpl +FIX: do not include tpl from disabled modules +FIX: Error management when MAILING_NO_USING_PHPMAIL is set +FIX: Even with permission, can't validate leave once validator defined. +FIX: extrafield list search: SQL error when field is multiselect +FIX: if last char of customercode is accent making the truncate of first +FIX: in edit mode, dictionary inputs do not escape the string inside the 'value' attribute, causing errors if there are any double quotes +FIX: invalid link on user.fk_user +FIX: invoice class: bad SQL request if product type not set +FIX: mail presend: can overwrite a file previously uploaded +FIX: mail presend: can overwrite a file previously uploaded (Issue #11056) +FIX: mass send mail +FIX: missing compatibility with multicompany transverse mode +FIX: modulebuilder: hardcoded llx_ +FIX: Not showing Contract and Project columns on ficheinter list +FIX: remove isolated transaction commit +FIX: security (a user can read leave or holiday of other without perm. +FIX: situation invoices: bad detailed VAT in situations following the first one +FIX: situation invoices: block progress percentage change for discount lines +FIX: syntax error +FIX: try to use WHERE EXISTS instead DISTINCT +FIX: use dol_sanitizeFileName() function to remove double spaces in filenames, as well as done on document.php when we want to download pdf +FIX: var name +FIX: we need to fetch fourn invoice with ref in current entity +FIX: Wrong stock movement on supplier credit notes ***** ChangeLog for 8.0.5 compared to 8.0.4 ***** FIX: #10381 diff --git a/build/generate_filelist_xml.php b/build/generate_filelist_xml.php index 0764d64b491..25f4af98207 100755 --- a/build/generate_filelist_xml.php +++ b/build/generate_filelist_xml.php @@ -121,6 +121,7 @@ else } print "Release : ".$release."\n"; +print "Working on files into : ".DOL_DOCUMENT_ROOT."\n"; print "Include custom in signature : ".$includecustom."\n"; print "Include constants in signature : "; foreach ($includeconstants as $countrycode => $tmp) diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl index 7ba988231cc..14d4924136a 100755 --- a/build/makepack-dolibarr.pl +++ b/build/makepack-dolibarr.pl @@ -22,7 +22,7 @@ $PUBLISHSTABLE="eldy,dolibarr\@frs.sourceforge.net:/home/frs/project/dolibarr"; $PUBLISHBETARC="dolibarr\@vmprod1.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 +#@LISTETARGET=("TGZ","ZIP","RPM_GENERIC","RPM_FEDORA","RPM_MANDRIVA","RPM_OPENSUSE","DEB","EXEDOLIWAMP","SNAPSHOT"); # Possible packages @LISTETARGET=("TGZ","ZIP","RPM_GENERIC","RPM_FEDORA","RPM_MANDRIVA","RPM_OPENSUSE","DEB","EXEDOLIWAMP","SNAPSHOT"); # Possible packages %REQUIREMENTPUBLISH=( "SF"=>"git ssh rsync", @@ -36,8 +36,8 @@ $PUBLISHBETARC="dolibarr\@vmprod1.dolibarr.org:/home/dolibarr/dolibarr.org/httpd "RPM_FEDORA"=>"rpmbuild", "RPM_MANDRIVA"=>"rpmbuild", "RPM_OPENSUSE"=>"rpmbuild", -"DEB"=>"dpkg", -"APS"=>"zip", +"DEB"=>"dpkg dpatch", +"FLATPACK"=>"flatpack", "EXEDOLIWAMP"=>"ISCC.exe", "SNAPSHOT"=>"tar" ); @@ -142,7 +142,6 @@ $FILENAMETGZ = "$PROJECT-$MAJOR.$MINOR.$BUILD"; $FILENAMEZIP = "$PROJECT-$MAJOR.$MINOR.$BUILD"; $FILENAMEXZ = "$PROJECT-$MAJOR.$MINOR.$BUILD"; $FILENAMEDEB = "see later"; -$FILENAMEAPS = "$PROJECT-$MAJOR.$MINOR.$BUILD.app"; $FILENAMEEXEDOLIWAMP = "DoliWamp-$MAJOR.$MINOR.$BUILD"; # For RPM $ARCH='noarch'; @@ -358,16 +357,16 @@ if ($nboftargetok) { } else { - print "ChangeLog for $MAJOR.$MINOR\.$BUILD was found into '$SOURCE/ChangeLog. But you can regenerate it with command:'\n"; + print "ChangeLog for $MAJOR.$MINOR\.$BUILD was found into '$SOURCE/ChangeLog. But you can regenerate it with command:\n"; } if (! $BUILD || $BUILD eq '0-rc') # For a major version { - print 'cd ~/git/dolibarr_'.$MAJOR.'.'.$MINOR.'; git log `git rev-list --boundary '.$MAJOR.'.'.$MINOR.'..origin/develop | grep ^- | cut -c2- | head -n 1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e \'^FIX\|NEW\' | sort -u | sed \'s/FIXED:/FIX:/g\' | sed \'s/FIXED :/FIX:/g\' | sed \'s/FIX :/FIX:/g\' | sed \'s/FIX /FIX: /g\' | sed \'s/NEW :/NEW:/g\' | sed \'s/NEW /NEW: /g\' > /tmp/aaa'; + print 'cd ~/git/dolibarr_'.$MAJOR.'.'.$MINOR.'; git log `git rev-list --boundary '.$MAJOR.'.'.$MINOR.'..origin/develop | grep ^- | cut -c2- | head -n 1`.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e \'^FIX\|NEW\|CLOSE\' | sort -u | sed \'s/FIXED:/FIX:/g\' | sed \'s/FIXED :/FIX:/g\' | sed \'s/FIX :/FIX:/g\' | sed \'s/FIX /FIX: /g\' | sed \'s/NEW :/NEW:/g\' | sed \'s/NEW /NEW: /g\' > /tmp/aaa'; } else # For a maintenance release { #print 'cd ~/git/dolibarr_'.$MAJOR.'.'.$MINOR.'; git log '.$MAJOR.'.'.$MINOR.'.'.($BUILD-1).'.. --no-merges --pretty=short --oneline | sed -e "s/^[0-9a-z]* //" | grep -e \'^FIX\|NEW\' | sort -u | sed \'s/FIXED:/FIX:/g\' | sed \'s/FIXED :/FIX:/g\' | sed \'s/FIX :/FIX:/g\' | sed \'s/FIX /FIX: /g\' | sed \'s/NEW :/NEW:/g\' | sed \'s/NEW /NEW: /g\' > /tmp/aaa'; - print 'cd ~/git/dolibarr_'.$MAJOR.'.'.$MINOR.'; git log '.$MAJOR.'.'.$MINOR.'.'.($BUILD-1).'.. | grep -v "Merge branch" | grep -v "Merge pull" | grep "^ " | sed -e "s/^[0-9a-z]* *//" | grep -e \'^FIX\|NEW\' | sort -u | sed \'s/FIXED:/FIX:/g\' | sed \'s/FIXED :/FIX:/g\' | sed \'s/FIX :/FIX:/g\' | sed \'s/FIX /FIX: /g\' | sed \'s/NEW :/NEW:/g\' | sed \'s/NEW /NEW: /g\' > /tmp/aaa'; + print 'cd ~/git/dolibarr_'.$MAJOR.'.'.$MINOR.'; git log '.$MAJOR.'.'.$MINOR.'.'.($BUILD-1).'.. | grep -v "Merge branch" | grep -v "Merge pull" | grep "^ " | sed -e "s/^[0-9a-z]* *//" | grep -e \'^FIX\|NEW\|CLOSE\' | sort -u | sed \'s/FIXED:/FIX:/g\' | sed \'s/FIXED :/FIX:/g\' | sed \'s/FIX :/FIX:/g\' | sed \'s/FIX /FIX: /g\' | sed \'s/NEW :/NEW:/g\' | sed \'s/NEW /NEW: /g\' > /tmp/aaa'; } print "\n"; @@ -388,6 +387,7 @@ if ($nboftargetok) { #----------------------- if ($CHOOSEDTARGET{'-CHKSUM'}) { + chdir("$SOURCE"); print 'Create xml check file with md5 checksum with command php '.$SOURCE.'/build/generate_filelist_xml.php release='.$MAJOR.'.'.$MINOR.'.'.$BUILD."\n"; $ret=`php $SOURCE/build/generate_filelist_xml.php release=$MAJOR.$MINOR.$BUILD`; print $ret."\n"; @@ -536,6 +536,8 @@ if ($nboftargetok) { $ret=`find $BUILDROOT/$PROJECT/htdocs/custom/* -type l -exec rm -fr {} \\; >/dev/null 2>&1`; # For custom we want to remove all subdirs, even symbolic links, but not files # Removed known external modules to avoid any error when packaging from env where external modules are tested + $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/abricot*`; + $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/accountingexport*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/allscreens*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/ancotec*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/cabinetmed*`; @@ -550,11 +552,14 @@ if ($nboftargetok) { $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/multicompany*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/ndf*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/nltechno*`; + $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/nomenclature*`; + $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/of/`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/oscim*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/pos*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/teclib*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/timesheet*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/webmail*`; + $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/workstation*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/accountingexport*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/themes/oblyon*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/themes/allscreen*`; @@ -586,6 +591,8 @@ if ($nboftargetok) { $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/phpoffice/phpexcel/Examples`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/phpoffice/phpexcel/unitTests`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/phpoffice/phpexcel/license.md`; + $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/sabre/sabre/*/tests`; + $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/stripe/tests`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/stripe/LICENSE`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/tcpdf/fonts/dejavu-fonts-ttf-*`; $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/tcpdf/fonts/freefont-*`; @@ -692,7 +699,7 @@ if ($nboftargetok) { print "Go to directory $BUILDROOT\n"; $olddir=getcwd(); chdir("$BUILDROOT"); - $cmd= "xz -9 -r $BUILDROOT/$FILENAMEAPS.xz \*"; + $cmd= "xz -9 -r $BUILDROOT/$FILENAMEXZ.xz \*"; print $cmd."\n"; $ret= `$cmd`; chdir("$olddir"); @@ -1140,7 +1147,7 @@ if ($nboftargetok) { $ret=`cat "$SOURCE/build/exe/doliwamp/doliwamp.iss" | sed -e 's/__FILENAMEEXEDOLIWAMP__/$FILENAMEEXEDOLIWAMP/g' > "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"`; print "Compil exe $FILENAMEEXEDOLIWAMP.exe file from iss file \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\"\n"; - $cmd= "ISCC.exe \"Z:$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\""; + $cmd= "wine ISCC.exe \"Z:$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\""; print "$cmd\n"; $ret= `$cmd`; #print "$ret\n"; diff --git a/htdocs/adherents/class/adherent.class.php b/htdocs/adherents/class/adherent.class.php index ac3e6890cf4..44aa788dd65 100644 --- a/htdocs/adherents/class/adherent.class.php +++ b/htdocs/adherents/class/adherent.class.php @@ -222,22 +222,22 @@ class Adherent extends CommonObject '__ID__'=>$this->id, '__MEMBER_ID__'=>$this->id, '__CIVILITY__'=>$this->getCivilityLabel(), - '__FIRSTNAME__'=>$msgishtml?dol_htmlentitiesbr($this->firstname):$this->firstname, - '__LASTNAME__'=>$msgishtml?dol_htmlentitiesbr($this->lastname):$this->lastname, + '__FIRSTNAME__'=>$msgishtml?dol_htmlentitiesbr($this->firstname):($this->firstname?$this->firstname:''), + '__LASTNAME__'=>$msgishtml?dol_htmlentitiesbr($this->lastname):($this->lastname?$this->lastname:''), '__FULLNAME__'=>$msgishtml?dol_htmlentitiesbr($this->getFullName($langs)):$this->getFullName($langs), - '__COMPANY__'=>$msgishtml?dol_htmlentitiesbr($this->societe):$this->societe, - '__ADDRESS__'=>$msgishtml?dol_htmlentitiesbr($this->address):$this->address, - '__ZIP__'=>$msgishtml?dol_htmlentitiesbr($this->zip):$this->zip, - '__TOWN__'=>$msgishtml?dol_htmlentitiesbr($this->town):$this->town, - '__COUNTRY__'=>$msgishtml?dol_htmlentitiesbr($this->country):$this->country, - '__EMAIL__'=>$msgishtml?dol_htmlentitiesbr($this->email):$this->email, - '__BIRTH__'=>$msgishtml?dol_htmlentitiesbr($birthday):$birthday, - '__PHOTO__'=>$msgishtml?dol_htmlentitiesbr($this->photo):$this->photo, - '__LOGIN__'=>$msgishtml?dol_htmlentitiesbr($this->login):$this->login, - '__PASSWORD__'=>$msgishtml?dol_htmlentitiesbr($this->pass):$this->pass, - '__PHONE__'=>$msgishtml?dol_htmlentitiesbr($this->phone):$this->phone, - '__PHONEPRO__'=>$msgishtml?dol_htmlentitiesbr($this->phone_perso):$this->phone_perso, - '__PHONEMOBILE__'=>$msgishtml?dol_htmlentitiesbr($this->phone_mobile):$this->phone_mobile, + '__COMPANY__'=>$msgishtml?dol_htmlentitiesbr($this->societe):($this->societe?$this->societe:''), + '__ADDRESS__'=>$msgishtml?dol_htmlentitiesbr($this->address):($this->address?$this->address:''), + '__ZIP__'=>$msgishtml?dol_htmlentitiesbr($this->zip):($this->zip?$this->zip:''), + '__TOWN__'=>$msgishtml?dol_htmlentitiesbr($this->town):($this->town?$this->town:''), + '__COUNTRY__'=>$msgishtml?dol_htmlentitiesbr($this->country):($this->country?$this->country:''), + '__EMAIL__'=>$msgishtml?dol_htmlentitiesbr($this->email):($this->email?$this->email:''), + '__BIRTH__'=>$msgishtml?dol_htmlentitiesbr($birthday):($birthday?$birthday:''), + '__PHOTO__'=>$msgishtml?dol_htmlentitiesbr($this->photo):($this->photo?$this->photo:''), + '__LOGIN__'=>$msgishtml?dol_htmlentitiesbr($this->login):($this->login?$this->login:''), + '__PASSWORD__'=>$msgishtml?dol_htmlentitiesbr($this->pass):($this->pass?$this->pass:''), + '__PHONE__'=>$msgishtml?dol_htmlentitiesbr($this->phone):($this->phone?$this->phone:''), + '__PHONEPRO__'=>$msgishtml?dol_htmlentitiesbr($this->phone_perso):($this->phone_perso?$this->phone_perso:''), + '__PHONEMOBILE__'=>$msgishtml?dol_htmlentitiesbr($this->phone_mobile):($this->phone_mobile?$this->phone_mobile:'') ); complete_substitutions_array($substitutionarray, $langs, $this); diff --git a/htdocs/compta/prelevement/factures.php b/htdocs/compta/prelevement/factures.php index 2eabd64873d..defa9a345db 100644 --- a/htdocs/compta/prelevement/factures.php +++ b/htdocs/compta/prelevement/factures.php @@ -157,7 +157,7 @@ $sql.= " AND pl.fk_prelevement_bons = p.rowid"; $sql.= " AND f.fk_soc = s.rowid"; $sql.= " AND pf.fk_facture = f.rowid"; $sql.= " AND f.entity = ".$conf->entity; -if ($prev_id) $sql.= " AND p.rowid=".$prev_id; +if ($object->id) $sql.= " AND p.rowid=".$object->id; if ($socid) $sql.= " AND s.rowid = ".$socid; $sql.= $db->order($sortfield,$sortorder); diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index 07766ac7fef..2f5f03ee5a8 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -70,6 +70,8 @@ if (! $error && $massaction == 'confirm_presend') $listofobjectid=array(); $listofobjectthirdparties=array(); $listofobjectref=array(); + $attachedfilesThirdpartyObj=array(); + $oneemailperrecipient=(GETPOST('oneemailperrecipient')=='on'?1:0); if (! $error) { @@ -194,7 +196,6 @@ if (! $error && $massaction == 'confirm_presend') $sendtocc=implode(',',$tmparray); //var_dump($listofobjectref);exit; - $attachedfiles=array('paths'=>array(), 'names'=>array(), 'mimes'=>array()); $listofqualifiedobj=array(); $listofqualifiedref=array(); $thirdpartywithoutemail=array(); @@ -259,7 +260,7 @@ if (! $error && $massaction == 'confirm_presend') // TODO If not defined, use $objectobj->modelpdf (or defaut invoice config) to know what is template to use to regenerate doc. $filename = dol_sanitizeFileName($objectobj->ref).'.pdf'; $subdir = ''; - // TODO Set subdir to be compatible with multi levels dir trees + // TODO Set subdir to be compatible with multi levels dir trees // $subdir = get_exdir($objectobj->id, 2, 0, 0, $objectobj, $objectobj->element) $filedir = $uploaddir . '/' . $subdir . dol_sanitizeFileName($objectobj->ref); $file = $filedir . '/' . $filename; @@ -275,12 +276,12 @@ if (! $error && $massaction == 'confirm_presend') if (dol_is_file($file)) { - // Create form object - $attachedfiles=array( - 'paths'=>array_merge($attachedfiles['paths'],array($file)), - 'names'=>array_merge($attachedfiles['names'],array($filename)), - 'mimes'=>array_merge($attachedfiles['mimes'],array($mime)) - ); + // Create form object + $attachedfilesThirdpartyObj[$thirdpartyid][$objectid]=array( + 'paths'=>array($file), + 'names'=>array($filename), + 'mimes'=>array($mime) + ); } else { @@ -346,7 +347,7 @@ if (! $error && $massaction == 'confirm_presend') if ($objectclass == 'FactureFournisseur') $sendtobcc .= (empty($conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO) ? '' : (($sendtobcc?", ":"").$conf->global->MAIN_MAIL_AUTOCOPY_SUPPLIER_INVOICE_TO)); // $listofqualifiedobj is array with key = object id and value is instance of qualified objects, for the current thirdparty (but thirdparty property is not loaded yet) - $oneemailperrecipient=(GETPOST('oneemailperrecipient')=='on'?1:0); + $looparray=array(); if (! $oneemailperrecipient) { @@ -363,8 +364,9 @@ if (! $error && $massaction == 'confirm_presend') $looparray[0]=$objectforloop; } //var_dump($looparray);exit; - - foreach ($looparray as $objecttmp) // $objecttmp is a real object or an empty object if we choose to send one email per thirdparty instead of one per record + dol_syslog("We have set an array of ".count($looparray)." emails to send. oneemailperrecipient=".$oneemailperrecipient); + //var_dump($oneemailperrecipient); var_dump($listofqualifiedobj); var_dump($listofqualifiedref); + foreach ($looparray as $objectid => $objecttmp) // $objecttmp is a real object or an empty object if we choose to send one email per thirdparty instead of one per object { // Make substitution in email content $substitutionarray=getCommonSubstitutionArray($langs, 0, null, $objecttmp); @@ -384,18 +386,44 @@ if (! $error && $massaction == 'confirm_presend') complete_substitutions_array($substitutionarray, $langs, $objecttmp, $parameters); - $subject=make_substitutions($subject, $substitutionarray); - $message=make_substitutions($message, $substitutionarray); + $subjectreplaced=make_substitutions($subject, $substitutionarray); + $messagereplaced=make_substitutions($message, $substitutionarray); + + + $attachedfiles=array('paths'=>array(), 'names'=>array(), 'mimes'=>array()); + if($oneemailperrecipient) + { + // if "one email per recipient" isn't check we must collate $attachedfiles by thirdparty + if(is_array($attachedfilesThirdpartyObj[$thirdparty->id]) && count($attachedfilesThirdpartyObj[$thirdparty->id])) + { + foreach ($attachedfilesThirdpartyObj[$thirdparty->id] as $keyObjId => $objAttachedFiles){ + // Create form object + $attachedfiles=array( + 'paths'=>array_merge($attachedfiles['paths'], $objAttachedFiles['paths']), + 'names'=>array_merge($attachedfiles['names'], $objAttachedFiles['names']), + 'mimes'=>array_merge($attachedfiles['mimes'], $objAttachedFiles['mimes']) + ); + } + } + } + elseif(!empty($attachedfilesThirdpartyObj[$thirdparty->id][$objectid])){ + // Create form object + // if "one email per recipient" isn't check we must separate $attachedfiles by object + $attachedfiles=$attachedfilesThirdpartyObj[$thirdparty->id][$objectid]; + } $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); + require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; + $mailfile = new CMailFile($subjectreplaced, $sendto, $from, $messagereplaced, $filepath, $mimetype, $filename, $sendtocc, $sendtobcc, $deliveryreceipt, -1); if ($mailfile->error) { $resaction.='
'.$mailfile->error.'
'; @@ -410,8 +438,12 @@ if (! $error && $massaction == 'confirm_presend') $error=0; // Insert logs into agenda - foreach($listofqualifiedobj as $objid => $objectobj) + foreach($listofqualifiedobj as $objid2 => $objectobj2) { + if ((! $oneemailperrecipient) && $objid2 != $objectid) continue; // We discard this pass to avoid duplicate with other pass in looparray at higher level + + dol_syslog("Try to insert email event into agenda for objid=".$objid2." => objectobj=".get_class($objectobj2)); + /*if ($objectclass == 'Propale') $actiontypecode='AC_PROP'; if ($objectclass == 'Commande') $actiontypecode='AC_COM'; if ($objectclass == 'Facture') $actiontypecode='AC_FAC'; @@ -423,18 +455,18 @@ if (! $error && $massaction == 'confirm_presend') 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('MailTopic') . ": " . $subjectreplaced); $actionmsg = dol_concatdesc($actionmsg, $langs->transnoentities('TextUsedInTheMessageBody') . ":"); - $actionmsg = dol_concatdesc($actionmsg, $message); + $actionmsg = dol_concatdesc($actionmsg, $messagereplaced); } $actionmsg2=''; // Initialisation donnees - $objectobj->sendtoid = 0; - $objectobj->actionmsg = $actionmsg; // Long text - $objectobj->actionmsg2 = $actionmsg2; // Short text - $objectobj->fk_element = $objid; - $objectobj->elementtype = $objectobj->element; + $objectobj2->sendtoid = 0; + $objectobj2->actionmsg = $actionmsg; // Long text + $objectobj2->actionmsg2 = $actionmsg2; // Short text + $objectobj2->fk_element = $objid2; + $objectobj2->elementtype = $objectobj2->element; $triggername = strtoupper(get_class($objectobj)) .'_SENTBYMAIL'; if ($triggername == 'SOCIETE_SENTBYMAIL') $triggername = 'COMPANY_SENTBYEMAIL'; @@ -449,9 +481,9 @@ if (! $error && $massaction == 'confirm_presend') if (! empty($triggername)) { // Appel des triggers - include_once(DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php"); + include_once DOL_DOCUMENT_ROOT . "/core/class/interfaces.class.php"; $interface=new Interfaces($db); - $result=$interface->run_triggers($triggername, $objectobj, $user, $langs, $conf); + $result=$interface->run_triggers($triggername, $objectobj2, $user, $langs, $conf); if ($result < 0) { $error++; $errors=$interface->errors; } // Fin appel triggers @@ -462,7 +494,7 @@ if (! $error && $massaction == 'confirm_presend') } } - $nbsent++; + $nbsent++; // Nb of record sent } } else @@ -736,7 +768,7 @@ if ($massaction == 'confirm_createbills') if (! $error) { $db->commit(); - setEventMessage($langs->trans('BillCreated', $nb_bills_created)); + setEventMessages($langs->trans('BillCreated', $nb_bills_created), null, 'mesgs'); // Make a redirect to avoid to bill twice if we make a refresh or back $param=''; diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index ac742f0dbb7..db758f6c614 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -992,7 +992,6 @@ class FormMail extends Form $defaultmessage=preg_replace("/^(
)+/","",$defaultmessage); $defaultmessage=preg_replace("/^\n+/","",$defaultmessage); } - $out.= ''; $out.= ''; $out.=$form->textwithpicto($langs->trans('MailText'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfrombody'); diff --git a/htdocs/core/extrafieldsinexport.inc.php b/htdocs/core/extrafieldsinexport.inc.php index 13b2d1ae520..78dbba9934e 100644 --- a/htdocs/core/extrafieldsinexport.inc.php +++ b/htdocs/core/extrafieldsinexport.inc.php @@ -34,6 +34,15 @@ if ($resql) // This can fail when class is used on old database (during migra case 'boolean': $typeFilter="Boolean"; break; + case 'select': + if (! empty($conf->global->EXPORT_LABEL_FOR_SELECT)) + { + $tmpparam=unserialize($obj->param); // $tmpparam may be array with 'options' = array(key1=>val1, key2=>val2 ...) + if ($tmpparam['options'] && is_array($tmpparam['options'])) { + $typeFilter="Select:".$obj->param; + } + } + break; case 'sellist': $tmp=''; $tmpparam=unserialize($obj->param); // $tmp ay be array 'options' => array 'c_currencies:code_iso:code_iso' => null diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 6da863e54ef..dfc46eccddb 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -6233,6 +6233,8 @@ function make_substitutions($text, $substitutionarray, $outputlangs=null) // Make substitition for array $substitutionarray foreach ($substitutionarray as $key => $value) { + if (! isset($value)) continue; // If value is null, it same than not having substitution key at all into array, we do not replace. + if ($key == '__SIGNATURE__' && (! empty($conf->global->MAIN_MAIL_DO_NOT_USE_SIGN))) $value=''; // Protection if ($key == '__USER_SIGNATURE__' && (! empty($conf->global->MAIN_MAIL_DO_NOT_USE_SIGN))) $value=''; // Protection diff --git a/htdocs/core/modules/modAdherent.class.php b/htdocs/core/modules/modAdherent.class.php index 3acd162bb03..76ff02b588b 100644 --- a/htdocs/core/modules/modAdherent.class.php +++ b/htdocs/core/modules/modAdherent.class.php @@ -273,20 +273,22 @@ class modAdherent extends DolibarrModules 'a.phone'=>"PhonePro",'a.phone_perso'=>"PhonePerso",'a.phone_mobile'=>"PhoneMobile",'a.email'=>"Email",'a.birth'=>"Birthday",'a.statut'=>"Status", 'a.photo'=>"Photo",'a.note_public'=>"NotePublic",'a.note_private'=>"NotePrivate",'a.datec'=>'DateCreation','a.datevalid'=>'DateValidation', 'a.tms'=>'DateLastModification','a.datefin'=>'DateEndSubscription','ta.rowid'=>'MemberTypeId','ta.libelle'=>'MemberTypeLabel', - 'c.rowid'=>'SubscriptionId','c.dateadh'=>'DateSubscription','c.subscription'=>'Amount' + 'c.rowid'=>'SubscriptionId','c.dateadh'=>'DateSubscription','c.datef'=>'DateEndSubscription','c.subscription'=>'Amount' ); $this->export_TypeFields_array[$r]=array( 'a.civility'=>"Text",'a.lastname'=>"Text",'a.firstname'=>"Text",'a.login'=>"Text",'a.morphy'=>'Text','a.societe'=>'Text','a.address'=>"Text", 'a.zip'=>"Text",'a.town'=>"Text",'d.nom'=>"Text",'co.code'=>'Text','co.label'=>"Text",'a.phone'=>"Text",'a.phone_perso'=>"Text",'a.phone_mobile'=>"Text", 'a.email'=>"Text",'a.birth'=>"Date",'a.statut'=>"Status",'a.note_public'=>"Text",'a.note_private'=>"Text",'a.datec'=>'Date','a.datevalid'=>'Date', - 'a.tms'=>'Date','a.datefin'=>'Date','ta.rowid'=>'List:adherent_type:libelle::member_type','ta.libelle'=>'Text','c.rowid'=>'Numeric','c.dateadh'=>'Date','c.subscription'=>'Numeric' + 'a.tms'=>'Date','a.datefin'=>'Date','ta.rowid'=>'List:adherent_type:libelle::member_type','ta.libelle'=>'Text', + 'c.rowid'=>'Numeric','c.dateadh'=>'Date','c.datef'=>'Date','c.subscription'=>'Numeric' ); $this->export_entities_array[$r]=array( 'a.rowid'=>'member','a.civility'=>"member",'a.lastname'=>"member",'a.firstname'=>"member",'a.login'=>"member",'a.morphy'=>'member', 'a.societe'=>'member','a.address'=>"member",'a.zip'=>"member",'a.town'=>"member",'d.nom'=>"member",'co.code'=>"member",'co.label'=>"member", 'a.phone'=>"member",'a.phone_perso'=>"member",'a.phone_mobile'=>"member",'a.email'=>"member",'a.birth'=>"member",'a.statut'=>"member", 'a.photo'=>"member",'a.note_public'=>"member",'a.note_private'=>"member",'a.datec'=>'member','a.datevalid'=>'member','a.tms'=>'member', - 'a.datefin'=>'member','ta.rowid'=>'member_type','ta.libelle'=>'member_type','c.rowid'=>'subscription','c.dateadh'=>'subscription','c.subscription'=>'subscription' + 'a.datefin'=>'member','ta.rowid'=>'member_type','ta.libelle'=>'member_type', + 'c.rowid'=>'subscription','c.dateadh'=>'subscription','c.datef'=>'subscription','c.subscription'=>'subscription' ); // Add extra fields $keyforselect='adherent'; $keyforelement='member'; $keyforaliasextra='extra'; diff --git a/htdocs/core/tpl/massactions_pre.tpl.php b/htdocs/core/tpl/massactions_pre.tpl.php index a66e9ba270e..a5d7883f3e5 100644 --- a/htdocs/core/tpl/massactions_pre.tpl.php +++ b/htdocs/core/tpl/massactions_pre.tpl.php @@ -44,7 +44,7 @@ if ($massaction == 'presend') $listofselectedid = array(); $listofselectedthirdparties = array(); $listofselectedref = array(); - + if (! GETPOST('cancel', 'alpha')) { foreach ($arrayofselected as $toselectid) @@ -111,8 +111,9 @@ if ($massaction == 'presend') } else { $formmail->withtoreadonly = 1; } - - $formmail->withoptiononeemailperrecipient = (count($listofselectedref) == 1 || empty($liste))? 0 : ((GETPOST('oneemailperrecipient')=='on')?1:-1); + + $formmail->withoptiononeemailperrecipient = ((count($listofselectedref) == 1 && count(reset($listofselectedref)) == 1) || empty($liste)) ? 0 : ((GETPOST('oneemailperrecipient')=='on')?1:-1); + $formmail->withto = empty($liste)?(GETPOST('sendto','alpha')?GETPOST('sendto','alpha'):array()):$liste; $formmail->withtofree = empty($liste)?1:0; $formmail->withtocc = 1; @@ -131,6 +132,7 @@ if ($massaction == 'presend') // Make substitution in email content $substitutionarray = getCommonSubstitutionArray($langs, 0, null, $object); + $substitutionarray['__EMAIL__'] = $sendto; $substitutionarray['__CHECK_READ__'] = (is_object($object) && is_object($object->thirdparty)) ? '' : ''; $substitutionarray['__PERSONALIZED__'] = ''; // deprecated diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index aa85132b243..ed6b0227f91 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -468,7 +468,8 @@ if (empty($reshook)) else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->expedition->supprimer) { - $result = $object->delete(); + $also_update_stock = GETPOST('alsoUpdateStock', 'alpha') ?: 0; + $result = $object->delete($also_update_stock); if ($result > 0) { header("Location: ".DOL_URL_ROOT.'/expedition/index.php'); @@ -1648,7 +1649,26 @@ else if ($id || $ref) // Confirm deleteion if ($action == 'delete') { - $formconfirm=$form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id,$langs->trans('DeleteSending'),$langs->trans("ConfirmDeleteSending",$object->ref),'confirm_delete','',0,1); + $formquestion = array(); + if ($object->statut == Expedition::STATUS_CLOSED && !empty($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE)) { + $formquestion = array( + array( + 'label' => $langs->trans('ShipmentIncrementStockOnDelete'), + 'name' => 'alsoUpdateStock', + 'type' => 'checkbox', + 'value' => 0 + ), + ); + } + $formconfirm=$form->formconfirm( + $_SERVER['PHP_SELF'].'?id='.$object->id, + $langs->trans('DeleteSending'), + $langs->trans("ConfirmDeleteSending",$object->ref), + 'confirm_delete', + $formquestion, + 0, + 1 + ); } // Confirmation validation diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index dd0d4842276..a8d9acc7b48 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -1079,7 +1079,7 @@ class Expedition extends CommonObject * * @return int >0 if OK, 0 if deletion done but failed to delete files, <0 if KO */ - function delete() + function delete($also_update_stock = false) { global $conf, $langs, $user; @@ -1113,7 +1113,7 @@ class Expedition extends CommonObject // Stock control if (! $error && $conf->stock->enabled && (($conf->global->STOCK_CALCULATE_ON_SHIPMENT && $this->statut > self::STATUS_DRAFT) || - ($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE && $this->statut == 2))) + ($conf->global->STOCK_CALCULATE_ON_SHIPMENT_CLOSE && $this->statut == self::STATUS_CLOSED && $also_update_stock))) { require_once(DOL_DOCUMENT_ROOT."/product/stock/class/mouvementstock.class.php"); diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index e623a76c87c..cc553f1e5de 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -62,6 +62,8 @@ $comments=GETPOST('comments','none'); $fk_c_type_fees=GETPOST('fk_c_type_fees','int'); $socid = GETPOST('socid','int')?GETPOST('socid','int'):GETPOST('socid_id','int'); +$childids = $user->getAllChildIds(1); + // Security check $id=GETPOST("id",'int'); if ($user->societe_id) $socid=$user->societe_id; @@ -105,7 +107,17 @@ $permissionnote = $user->rights->expensereport->creer; // Used by the include $permissiondellink = $user->rights->expensereport->creer; // Used by the include of actions_dellink.inc.php $permissionedit = $user->rights->expensereport->creer; // Used by the include of actions_lineupdown.inc.php - +if ($object->id > 0) +{ + // Check current user can read this expense report + $canread = 0; + if (! empty($user->rights->expensereport->readall)) $canread=1; + if (! empty($user->rights->expensereport->lire) && in_array($object->fk_user_author, $childids)) $canread=1; + if (! $canread) + { + accessforbidden(); + } +} /* diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index 96a1199255c..d5226795140 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -5,7 +5,7 @@ * Copyright (C) 2011-2012 Juanjo Menent * Copyright (C) 2013 Cédric Salvador * Copyright (C) 2015 Jean-François Ferry - * Copyright (C) 2018 Ferran Marcet + * Copyright (C) 2018-2019 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 @@ -32,23 +32,31 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; require_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; require_once DOL_DOCUMENT_ROOT.'/fichinter/class/fichinter.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; +if ($conf->projet->enabled) { + require_once DOL_DOCUMENT_ROOT . '/projet/class/project.class.php'; +} +if ($conf->contrat->enabled) { + require_once DOL_DOCUMENT_ROOT . '/contrat/class/contrat.class.php'; +} + + // Load translation files required by the page -$langs->loadLangs(array('companies', 'bills', 'interventions')); +$langs->loadLangs(array('companies', 'bills', 'interventions', 'exports')); -$action=GETPOST('action','alpha'); -$massaction=GETPOST('massaction','alpha'); -$show_files=GETPOST('show_files','int'); -$confirm=GETPOST('confirm','alpha'); +$action=GETPOST('action', 'alpha'); +$massaction=GETPOST('massaction', 'alpha'); +$show_files=GETPOST('show_files', 'int'); +$confirm=GETPOST('confirm', 'alpha'); $toselect = GETPOST('toselect', 'array'); -$contextpage=GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'interventionlist'; +$contextpage=GETPOST('contextpage', 'aZ')?GETPOST('contextpage', 'aZ'):'interventionlist'; -$search_ref=GETPOST('search_ref')?GETPOST('search_ref','alpha'):GETPOST('search_inter','alpha'); -$search_company=GETPOST('search_company','alpha'); -$search_desc=GETPOST('search_desc','alpha'); -$search_status=GETPOST('search_status'); +//$search_ref=GETPOST('search_ref')?GETPOST('search_ref','alpha'):GETPOST('search_inter','alpha'); +//$search_company=GETPOST('search_company','alpha'); +//$search_desc=GETPOST('search_desc','alpha'); +//$search_status=GETPOST('search_status'); $sall=trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alphanohtml'):GETPOST('sall', 'alphanohtml')); -$optioncss = GETPOST('optioncss','alpha'); +//$optioncss = GETPOST('optioncss','alpha'); $socid=GETPOST('socid','int'); // Security check @@ -79,6 +87,8 @@ $search_company=GETPOST('search_company','alpha'); $search_desc=GETPOST('search_desc','alpha'); $search_status=GETPOST('search_status'); $optioncss = GETPOST('optioncss','alpha'); +$search_project=GETPOST('search_project','alpha'); +$search_contract=GETPOST('search_contract','alpha'); // Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context $object = new Fichinter($db); @@ -103,10 +113,10 @@ if (! empty($conf->global->FICHINTER_DISABLE_DETAILS)) unset($fieldstosearchall[ $arrayfields=array( 'f.ref'=>array('label'=>$langs->trans("Ref"), 'checked'=>1), 's.nom'=>array('label'=>$langs->trans("ThirdParty"), 'checked'=>1), - 'f.fk_project'=>array('label'=>$langs->trans("Project"), 'checked'=>1), + 'f.fk_projet'=>array('label'=>$langs->trans("Project"), 'checked'=>1), 'f.fk_contrat'=>array('label'=>$langs->trans("Contract"), 'checked'=>1), 'f.description'=>array('label'=>$langs->trans("Description"), 'checked'=>1), - 'fd.description'=>array('label'=>"xx", 'checked'=>1, 'enabled'=>empty($conf->global->FICHINTER_DISABLE_DETAILS)?1:0), + 'fd.description'=>array('label'=>$langs->trans("LineDescription"), 'checked'=>1, 'enabled'=>empty($conf->global->FICHINTER_DISABLE_DETAILS)?1:0), 'fd.date'=>array('label'=>$langs->trans("Date"), 'checked'=>1, 'enabled'=>empty($conf->global->FICHINTER_DISABLE_DETAILS)?1:0), 'fd.duree'=>array('label'=>$langs->trans("Duration"), 'checked'=>1, 'enabled'=>empty($conf->global->FICHINTER_DISABLE_DETAILS)?1:0), 'f.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), @@ -173,6 +183,12 @@ $form = new Form($db); $formfile = new FormFile($db); $objectstatic=new Fichinter($db); $companystatic=new Societe($db); +if ($conf->projet->enabled) { + $projectstatic = new Project($db); +} +if ($conf->contrat->enabled) { + $contratstatic = new Contrat($db); +} $title=$langs->trans("ListOfInterventions"); llxHeader('', $title); @@ -182,6 +198,12 @@ $sql = "SELECT"; $sql.= " f.ref, f.rowid, f.fk_statut, f.description, f.datec as date_creation, f.tms as date_update, f.note_private,"; if (empty($conf->global->FICHINTER_DISABLE_DETAILS)) $sql.= " fd.description as descriptiondetail, fd.date as dp, fd.duree,"; $sql.= " s.nom as name, s.rowid as socid, s.client"; +if (! empty($arrayfields['f.fk_projet']['checked'])){ + $sql.= " ,p.rowid as projectid, p.ref as projectref, p.title as projecttitle"; +} +if (! empty($arrayfields['f.fk_contrat']['checked'])){ + $sql.= " ,c.rowid as contractid, c.ref as contractref"; +} // 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 @@ -189,6 +211,12 @@ $parameters=array(); $reshook=$hookmanager->executeHooks('printFieldListSelect',$parameters); // Note that $action and $object may have been modified by hook $sql.=$hookmanager->resPrint; $sql.= " FROM ".MAIN_DB_PREFIX."fichinter as f"; +if (! empty($arrayfields['f.fk_projet']['checked'])){ + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet as p ON f.fk_projet = p.rowid"; +} +if (! empty($arrayfields['f.fk_contrat']['checked'])){ + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."contrat as c ON f.fk_contrat = c.rowid"; +} if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."fichinter_extrafields as ef on (f.rowid = ef.fk_object)"; if (empty($conf->global->FICHINTER_DISABLE_DETAILS)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."fichinterdet as fd ON fd.fk_fichinter = f.rowid"; if (! $user->rights->societe->client->voir && empty($socid)) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; @@ -212,6 +240,12 @@ if (! $user->rights->societe->client->voir && empty($socid)) $sql .= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; if ($socid) $sql.= " AND s.rowid = " . $socid; +if ($search_project) { + $sql .= natural_search('p.ref', $search_project); +} +if ($search_contract) { + $sql .= natural_search('c.ref', $search_contract); +} if ($sall) { $sql .= natural_search(array_keys($fieldstosearchall), $sall); } @@ -262,6 +296,8 @@ if ($resql) if ($search_company) $param.="&search_company=".urlencode($search_company); if ($search_desc) $param.="&search_desc=".urlencode($search_desc); if ($search_status != '' && $search_status > -1) $param.="&search_status=".urlencode($search_status); + if ($search_project) $param.="&search_project=".urlencode($search_project); + if ($search_contract) $param.="&search_contract=".urlencode($search_contract); if ($show_files) $param.='&show_files=' .$show_files; if ($optioncss != '') $param.='&optioncss='.$optioncss; // Add $param from extra fields @@ -343,6 +379,18 @@ if ($resql) print ''; print ''; } + if (! empty($arrayfields['f.fk_projet']['checked'])) + { + print ''; + print ''; + print ''; + } + if (! empty($arrayfields['f.fk_contrat']['checked'])) + { + print ''; + print ''; + print ''; + } if (! empty($arrayfields['f.description']['checked'])) { print ''; @@ -399,21 +447,23 @@ if ($resql) print "\n"; print ''; - if (! empty($arrayfields['f.ref']['checked'])) print_liste_field_titre("Ref",$_SERVER["PHP_SELF"],"f.ref","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre("ThirdParty",$_SERVER["PHP_SELF"],"s.nom","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['f.description']['checked'])) print_liste_field_titre("Description",$_SERVER["PHP_SELF"],"f.description","",$param,'',$sortfield,$sortorder); - if (! empty($arrayfields['fd.description']['checked'])) print_liste_field_titre('',$_SERVER["PHP_SELF"],''); - if (! empty($arrayfields['fd.date']['checked'])) print_liste_field_titre("Date",$_SERVER["PHP_SELF"],"fd.date","",$param,'align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['fd.duree']['checked'])) print_liste_field_titre("Duration",$_SERVER["PHP_SELF"],"fd.duree","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['f.ref']['checked'])) print_liste_field_titre($arrayfields['f.ref']['label'],$_SERVER["PHP_SELF"],"f.ref","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'],$_SERVER["PHP_SELF"],"s.nom","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['f.fk_projet']['checked'])) print_liste_field_titre($arrayfields['f.fk_projet']['label'],$_SERVER["PHP_SELF"],"p.ref","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['f.fk_contrat']['checked'])) print_liste_field_titre($arrayfields['f.fk_contrat']['label'],$_SERVER["PHP_SELF"],"p.ref","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['f.description']['checked'])) print_liste_field_titre($arrayfields['f.description']['label'],$_SERVER["PHP_SELF"],"f.description","",$param,'',$sortfield,$sortorder); + if (! empty($arrayfields['fd.description']['checked'])) print_liste_field_titre($arrayfields['fd.description']['label'],$_SERVER["PHP_SELF"],''); + if (! empty($arrayfields['fd.date']['checked'])) print_liste_field_titre($arrayfields['fd.date']['label'],$_SERVER["PHP_SELF"],"fd.date","",$param,'align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['fd.duree']['checked'])) print_liste_field_titre($arrayfields['fd.duree']['label'],$_SERVER["PHP_SELF"],"fd.duree","",$param,'align="right"',$sortfield,$sortorder); // Extra fields include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; // Hook fields $parameters=array('arrayfields'=>$arrayfields,'param'=>$param,'sortfield'=>$sortfield,'sortorder'=>$sortorder); $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; - if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre("DateCreationShort",$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre("DateModificationShort",$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre("Status",$_SERVER["PHP_SELF"],"f.fk_statut","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['f.datec']['checked'])) print_liste_field_titre($arrayfields['f.datec']['label'],$_SERVER["PHP_SELF"],"f.datec","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['f.tms']['checked'])) print_liste_field_titre($arrayfields['f.tms']['label'],$_SERVER["PHP_SELF"],"f.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['f.fk_statut']['checked'])) print_liste_field_titre($arrayfields['f.fk_statut']['label'],$_SERVER["PHP_SELF"],"f.fk_statut","",$param,'align="right"',$sortfield,$sortorder); print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; @@ -477,6 +527,29 @@ if ($resql) print ''; if (! $i) $totalarray['nbfield']++; } + if (! empty($arrayfields['f.fk_projet']['checked'])) + { + print ''; + if ($obj->projectid > 0) { + $projectstatic->ref = $obj->projectref; + $projectstatic->id = $obj->projectid; + $projectstatic->title = $obj->projecttitle; + print $projectstatic->getNomUrl(1, '', 44); + } + print ''; + if (! $i) $totalarray['nbfield']++; + } + if (! empty($arrayfields['f.fk_contrat']['checked'])) + { + print ''; + if ($obj->contractid > 0) { + $contratstatic->ref = $obj->contractref; + $contratstatic->id = $obj->contractid; + print $contratstatic->getNomUrl(1, '', 44); + } + print ''; + if (! $i) $totalarray['nbfield']++; + } if (! empty($arrayfields['f.description']['checked'])) { print ''.dol_trunc(dolGetFirstLineOfText($obj->description),48).''; diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index fbc1f52cac7..5a71e94c2d4 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','8.0.6'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c +if (! defined('DOL_VERSION')) define('DOL_VERSION','8.0.7'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c if (! defined('EURO')) define('EURO',chr(128)); diff --git a/htdocs/holiday/card.php b/htdocs/holiday/card.php index 288cecef75d..6de04c5aeed 100644 --- a/htdocs/holiday/card.php +++ b/htdocs/holiday/card.php @@ -62,6 +62,22 @@ if (! empty($user->rights->holiday->delete)) $candelete=1; $morefilter = 'AND employee = 1'; if (! empty($conf->global->HOLIDAY_FOR_NON_SALARIES_TOO)) $morefilter = ''; +$object = new Holiday($db); +if ($id > 0) +{ + $object->fetch($id); + + // Check current user can read this leave request + $canread = 0; + if (! empty($user->rights->holiday->read_all)) $canread=1; + if (! empty($user->rights->holiday->read) && in_array($object->fk_user, $childids)) $canread=1; + if (! $canread) + { + accessforbidden(); + } +} + + /* * Actions @@ -75,7 +91,6 @@ if (GETPOST('cancel', 'alpha')) // If create a request if ($action == 'create') { - $object = new Holiday($db); // If no right to create a request if (! $cancreate) @@ -87,6 +102,8 @@ if ($action == 'create') if (! $error) { + $object = new Holiday($db); + $db->begin(); $date_debut = dol_mktime(0, 0, 0, GETPOST('date_debut_month'), GETPOST('date_debut_day'), GETPOST('date_debut_year')); @@ -196,7 +213,6 @@ if ($action == 'create') if ($action == 'update' && GETPOSTISSET('savevalidator') && ! empty($user->rights->holiday->approve)) { - $object = new Holiday($db); $object->fetch($id); $object->oldcopy = dol_clone($object); @@ -242,7 +258,6 @@ if ($action == 'update' && ! GETPOSTISSET('savevalidator')) exit; } - $object = new Holiday($db); $object->fetch($id); // If under validation @@ -326,7 +341,6 @@ if ($action == 'confirm_delete' && GETPOST('confirm') == 'yes' && $user->rights- $db->begin(); - $object = new Holiday($db); $object->fetch($id); // If this is a rough draft, approved, canceled or refused @@ -360,7 +374,6 @@ if ($action == 'confirm_delete' && GETPOST('confirm') == 'yes' && $user->rights- // Si envoi de la demande if ($action == 'confirm_send') { - $object = new Holiday($db); $object->fetch($id); // Si brouillon et créateur @@ -463,7 +476,6 @@ if ($action == 'confirm_send') // Si Validation de la demande if ($action == 'confirm_valid') { - $object = new Holiday($db); $object->fetch($id); // Si statut en attente de validation et valideur = utilisateur @@ -558,7 +570,6 @@ if ($action == 'confirm_refuse' && GETPOST('confirm','alpha') == 'yes') { if (! empty($_POST['detail_refuse'])) { - $object = new Holiday($db); $object->fetch($id); // Si statut en attente de validation et valideur = utilisateur @@ -643,7 +654,6 @@ if ($action == 'confirm_draft' && GETPOST('confirm') == 'yes') { $error = 0; - $object = new Holiday($db); $object->fetch($id); $oldstatus = $object->statut; @@ -674,7 +684,6 @@ if ($action == 'confirm_cancel' && GETPOST('confirm') == 'yes') { $error = 0; - $object = new Holiday($db); $object->fetch($id); // Si statut en attente de validation et valideur = valideur ou utilisateur, ou droits de faire pour les autres diff --git a/htdocs/langs/fr_FR/sendings.lang b/htdocs/langs/fr_FR/sendings.lang index 1071d5f23f9..4f4bfc514e2 100644 --- a/htdocs/langs/fr_FR/sendings.lang +++ b/htdocs/langs/fr_FR/sendings.lang @@ -60,6 +60,8 @@ NoProductToShipFoundIntoStock=Aucun produit à expédier n'a été trouver dans WeightVolShort=Poids/vol. ValidateOrderFirstBeforeShipment=Vous devez d'abord valider la commande pour pouvoir créer une expédition. +ShipmentIncrementStockOnDelete=Remettre en stock les éléments de cette expédition + # Sending methods # ModelDocument DocumentModelTyphon=Modèle de bon de réception/livraison complet (logo…)