Merge remote-tracking branch 'Dolibarr/8.0' into 8.0

This commit is contained in:
Inovea Conseil 2019-11-30 19:59:42 +01:00
commit 7077457d50
123 changed files with 1279 additions and 435 deletions

10
.stickler.yml Normal file
View File

@ -0,0 +1,10 @@
---
linters:
phpcs:
standard: 'dev/setup/codesniffer/ruleset.xml'
extensions: 'php'
tab_width: 4
fixer: true
fixers:
enable: true

119
ChangeLog
View File

@ -2,6 +2,125 @@
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
FIX: #10460 compatibility with MariaDB 10.4
FIX: #11025
FIX: Accountancy - Add transaction with multicompany use all the time 1st entity
FIX: Accountancy - Format EBP import
FIX: actioncomm export: ORDER BY clause is in wrong export property + event type filter does not work
FIX: actioncomm: sort events by date after external calendars and hook
FIX: action list: add printFieldListSelect and printFieldListWhere hooks
FIX: add fk_unit on addline action
FIX: avoid php warning
FIX: bad sql request
FIX: better method
FIX: better test
FIX: better test on fetch
FIX: broken external authentication module feature and avoid warning
FIX: Can not create contract with numbering module without autogen rule
FIX: can't add lines on invoices
FIX: Can't generate invoice pdf
FIX: Can't insert if there is extrafields mandatory on another entity.
FIX: Can't insert if there is extrafields mandatory on another entity. FIX: Can't set default value of extrafield of type varchar
FIX: Check for old picture name if the new one was not found
FIX: Civility not saved when creating a member.
FIX: $conf->fournisseur->commande->enabled doesn't exist, we must use $conf->fournisseur->enabled
FIX: could not create several superadmin in transversal mode
FIX: credit note can have negative value
FIX: Default value on sales representative on third party creation
FIX: Don't show journal:getNomUrl without data
FIX: Erreur dans le Total
FIX: error messages not displayed
FIX: expedition: reset status on rollback + replace hardcoded status with const
FIX: Fix PHP warning "count(): Parameter must be an array..."
FIX: fk_default_warehouse missing in group by
FIX: function sendEmailsReminder isn't completely developed, then MAIN_FEATURES_LEVEL must be 2 to "use" it
FIX: holidays get natural_search if search params are set only
FIX: if empty error message, we just see "error" displayed
FIX: if(!method_exists(dol_loginfunction))
FIX: If we build one invoice for several orders, we must put the ref of order on the line to not lose information.
FIX: in fact expensereport must be in $check array
FIX: Interface regression for bind people. Fix option MAIN_OPTIMIZEFORTEXTBROWSER
FIX: line edit template: keep fk_parent_line
FIX: Loan impossible to account
FIX: Mark credit note as available for credit note in other currency
FIX: missing access security checking with multicompany
FIX: missing entity filter and wrong var name
FIX: missing entity filter in function "build_filterField()" (export)
FIX: Missing field in import/export of users
FIX: missing hook completeTabsHead in margins module
FIX: missing $ismultientitymanaged for previous/next ref
FIX: Missing province in export of invoice
FIX: multicompany compatibility
FIX: must fetch member in current entity
FIX: need an order by in case we found other invoice with same number but not same date
FIX: need to round with 2 decimals to avoid movements not correctly balanced
FIX: no need to test anything to display documents tabs on expense report
FIX: positive values creating diff on addline rounding
FIX: problem with multicompany transverse mode
FIX: Product accountancey sell intra code must be visible if main feature level 1
FIX: project_title for display of getNomUrl()
FIX: quick search for supplier orders
FIX: Remane of project
FIX: same thing here
FIX: Selection of email recipient with option MAIN_OPTIMIZEFORTEXTBROWSER
FIX: several hooks in shipping/delivery cards
FIX: shipping default warehouse if only one warehouse
FIX: SQL injection on rowid of dict.php
FIX: 'statut' is ignored when updating a user with the REST API.
FIX: supplier invoice payment total dont care about deposit or credit
FIX: supplier invoice product stats total ht is line total not invoice total
FIX: The minimum amount filter does not work in the VAT report per customer
FIX: Total per day shows 00:00 if the total time spent is equal to 12:00
FIX: Update/delete currency on same languages
FIX: [URGENT] broken feature, "$usercancreate" is for Dolibarr 9
FIX: useless join
FIX: we need to keep originline special_code
FIX: we want to be able to reopen fourn credit note
FIX: when 2 extra fields are mandatory in 2 different entities
FIX: when we add a payment on an invoice which already has payments with credit note or deposit amount, and then we get an excess received, discount amount must be $total_paiements + $total_creditnote_and_deposit - $object->total_ttc;
FIX: when we create deposit with multi tva, we mustn't add line if amount = 0 (example when we have a 100% reduc on one of origin invoice line)
FIX: wrong redirect link on holiday refuse
FIX: wrong test enabled
FIX: Wrong variable name
FIX: XSS
***** ChangeLog for 8.0.4 compared to 8.0.3 *****
FIX: #10030 better german chart

View File

@ -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)

View File

@ -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";

View File

@ -1,6 +1,7 @@
<?php
/* Copyright (C) 2016 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2016-2018 Alexandre Spangaro <aspangaro@zendsi.com>
* Copyright (C) 2019 Frédéric France <frederic.france@netlogic.fr>
*
* 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
@ -47,6 +48,7 @@ if ($user->societe_id > 0)
llxHeader('', $langs->trans("AccountancyArea"));
print load_fiche_titre($langs->trans("AccountancyArea"), '', 'title_accountancy');
dol_fiche_head();
$step = 0;
@ -165,6 +167,7 @@ else
{
print $langs->trans("Module10Desc")."<br>\n";
}
dol_fiche_end();
llxFooter();
$db->close();

View File

@ -208,7 +208,7 @@ if ($conf->facture->enabled)
{
print '<tr class="oddeven"><td>'.$langs->trans("ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS").'</td>';
print '<td>';
$form->select_produits($conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS, 'ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS');
$form->select_produits($conf->global->ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS, 'ADHERENT_PRODUCT_ID_FOR_SUBSCRIPTIONS', '', 0);
print '</td>';
}
print "</tr>\n";

View File

@ -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);

View File

@ -1976,7 +1976,7 @@ function fieldList($fieldlist, $obj='', $tabname='', $context='')
}
if (! $transfound)
{
print '<input type="text" class="flat'.($class?' '.$class:'').'" value="'.(isset($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'').'" name="'.$fieldlist[$field].'">';
print '<input type="text" class="flat'.($class?' '.$class:'').'" value="'.dol_escape_htmltag(isset($obj->{$fieldlist[$field]})?$obj->{$fieldlist[$field]}:'').'" name="'.$fieldlist[$field].'">';
}
print '</td>';
}

View File

@ -49,15 +49,14 @@ $action = GETPOST('action', 'alpha');
if (preg_match('/set_([a-z0-9_\-]+)/i',$action,$reg))
{
$code=$reg[1];
$value=(GETPOST($code, 'alpha') ? GETPOST($code, 'alpha') : 1);
$value=GETPOST($code, 'alpha');
if (dolibarr_set_const($db, $code, $value, 'chaine', 0, '', $conf->entity) > 0)
{
header("Location: ".$_SERVER["PHP_SELF"]);
exit;
setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
}
else
{
dol_print_error($db);
setEventMessages($langs->trans("Error"), null, 'errors');
}
}
@ -66,12 +65,11 @@ if (preg_match('/del_([a-z0-9_\-]+)/i',$action,$reg))
$code=$reg[1];
if (dolibarr_del_const($db, $code, 0) > 0)
{
header("Location: ".$_SERVER["PHP_SELF"]);
exit;
setEventMessages($langs->trans("SetupSaved"), null, 'mesgs');
}
else
{
dol_print_error($db);
setEventMessages($langs->trans("Error"), null, 'errors');
}
}
@ -106,9 +104,7 @@ elseif ($action == 'update_currency')
{
$error = 0;
$submit = GETPOST('submit', 'alpha');
if ($submit == $langs->trans('Modify'))
if (GETPOST('updatecurrency', 'alpha'))
{
$fk_multicurrency = GETPOST('fk_multicurrency', 'int');
$rate = price2num(GETPOST('rate', 'alpha'));
@ -127,7 +123,7 @@ elseif ($action == 'update_currency')
}
}
}
elseif ($submit == $langs->trans('Delete'))
elseif (GETPOST('deletecurrency', 'alpha'))
{
$fk_multicurrency = GETPOST('fk_multicurrency', 'int');
$currency = new MultiCurrency($db);
@ -334,8 +330,8 @@ foreach ($TCurrency as &$currency)
print '<input type="hidden" name="fk_multicurrency" value="'.$currency->id.'">';
print '1 '.$conf->currency.' = ';
print '<input type="text" name="rate" value="'.($currency->rate->rate ? $currency->rate->rate : '').'" size="13" />&nbsp;'.$currency->code.'&nbsp;';
print '<input type="submit" name="submit" class="button" value="'.$langs->trans("Modify").'">&nbsp;';
print '<input type="submit" name="submit" class="button" value="'.$langs->trans("Delete").'">';
print '<input type="submit" name="updatecurrency" class="button" value="'.$langs->trans("Modify").'">&nbsp;';
print '<input type="submit" name="deletecurrency" class="button" value="'.$langs->trans("Delete").'">';
print '</form>';
print '</td></tr>';
}

View File

@ -65,9 +65,12 @@ $arrayofcss=array('/includes/jquery/plugins/jquerytreeview/jquery.treeview.css')
llxHeader('',$title,'','',0,0,$arrayofjs,$arrayofcss);
$newcardbutton = '<a class="butActionNew" href="'.DOL_URL_ROOT.'/categories/card.php?action=create&type='.$type.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?type='.$type).'"><span class="valignmiddle">'.$langs->trans("NewCategory").'</span>';
$newcardbutton.= '<span class="fa fa-plus-circle valignmiddle"></span>';
$newcardbutton.= '</a>';
$newcardbutton='';
if (! empty($user->rights->categorie->creer)) {
$newcardbutton = '<a class="butActionNew" href="'.DOL_URL_ROOT.'/categories/card.php?action=create&type='.$type.'&backtopage='.urlencode($_SERVER["PHP_SELF"].'?type='.$type).'"><span class="valignmiddle">'.$langs->trans("NewCategory").'</span>';
$newcardbutton.= '<span class="fa fa-plus-circle valignmiddle"></span>';
$newcardbutton.= '</a>';
}
print load_fiche_titre($title, $newcardbutton);

View File

@ -7,6 +7,7 @@
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2014 Cedric GROSS <c.gross@kreiz-it.fr>
* Copyright (C) 2015 Alexandre Spangaro <aspangaro.dolibarr@gmail.com>
* Copyright (C) 2019 Ferran Marcet <fmarcet@2byte.es>
*
* 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
@ -246,7 +247,10 @@ if ($action == 'add')
{
$object->label = $langs->transnoentitiesnoconv("Action".$object->type_code)."\n";
}
else $object->label = $cactioncomm->libelle;
else {
$cactioncomm->fetch($object->type_code);
$object->label = $cactioncomm->label;
}
}
}
$object->fk_project = isset($_POST["projectid"])?$_POST["projectid"]:0;

View File

@ -1006,6 +1006,11 @@ if (! empty($hookmanager->resArray['eventarray'])) {
}
}
// Sort events
foreach($eventarray as $keyDate => &$dateeventarray)
{
usort($dateeventarray, 'sort_events_by_date');
}
$maxnbofchar=0;
@ -1700,3 +1705,22 @@ function dol_color_minus($color, $minus, $minusunit = 16)
}
return $newcolor;
}
/**
* Sort events by date
*
* @param object $a Event A
* @param object $b Event B
* @return int < 0 if event A should be before event B, > 0 otherwise, 0 if they have the exact same time slot
*/
function sort_events_by_date($a, $b)
{
if($a->datep != $b->datep)
{
return $a->datep - $b->datep;
}
// If both events have the same start time, longest first
return $b->datef - $a->datef;
}

View File

@ -87,7 +87,7 @@ $limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;
$sortfield = GETPOST("sortfield",'alpha');
$sortorder = GETPOST("sortorder",'alpha');
$page = GETPOST("page",'int');
if ($page == -1 || $page == null) { $page = 0 ; }
if (empty($page) || $page == -1) { $page = 0 ; }
$offset = $limit * $page ;
if (! $sortorder)
{

View File

@ -42,7 +42,7 @@ $limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;
$sortfield = GETPOST("sortfield",'alpha');
$sortorder = GETPOST("sortorder",'alpha');
$page = GETPOST("page",'int');
if ($page == -1 || $page == null) { $page = 0 ; }
if (empty($page) || $page == -1) { $page = 0 ; }
$offset = $limit * $page ;
if (! $sortorder) $sortorder="DESC";
if (! $sortfield) $sortfield="a.datep";

View File

@ -477,7 +477,7 @@ if ($object->id > 0)
print '</td><td>';
if ($action == 'editshipping')
{
$form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?socid='.$object->id,$object->shipping_method_id,'shipping_method_id');
$form->formSelectShippingMethod($_SERVER['PHP_SELF'].'?socid='.$object->id,$object->shipping_method_id,'shipping_method_id', 1);
}
else
{

View File

@ -471,13 +471,13 @@ if (empty($reshook))
if ($result)
{
setEventMessages($langs->trans("MailSuccessfulySent",$mailfile->getValidAddress($object->email_from,2),$mailfile->getValidAddress($object->sendto,2)), null, 'mesgs');
$action = '';
}
else
{
setEventMessages($langs->trans("ResultKo").'<br>'.$mailfile->error.' '.$result, null, 'errors');
$action = 'test';
}
$action='';
}
}
@ -870,7 +870,7 @@ else
}
$text.=$langs->trans('ConfirmSendingEmailing').'<br>';
$text.=$langs->trans('LimitSendingEmailing',$conf->global->MAILING_LIMIT_SENDBYWEB);
print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id,$langs->trans('SendMailing'),$text,'sendallconfirmed',$formquestion,'',1,300);
print $form->formconfirm($_SERVER['PHP_SELF'].'?id='.$object->id, $langs->trans('SendMailing'), $text, 'sendallconfirmed', $formquestion, '', 1, 330, 600);
}
}

View File

@ -320,7 +320,7 @@ if (empty($reshook))
$datep = dol_mktime(12, 0, 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear'));
$date_delivery = dol_mktime(12, 0, 0, GETPOST('date_livraisonmonth'), GETPOST('date_livraisonday'), GETPOST('date_livraisonyear'));
$duration = GETPOST('duree_validite');
$duration = GETPOST('duree_validite', 'int');
if (empty($datep)) {
setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Date")), null, 'errors');
@ -1533,7 +1533,7 @@ if ($action == 'create')
print '</td></tr>';
// Validaty duration
print '<tr><td class="fieldrequired">' . $langs->trans("ValidityDuration") . '</td><td><input name="duree_validite" size="5" value="' . $conf->global->PROPALE_VALIDITY_DURATION . '"> ' . $langs->trans("days") . '</td></tr>';
print '<tr><td class="fieldrequired">' . $langs->trans("ValidityDuration") . '</td><td><input name="duree_validite" class="width50" value="' . (GETPOST('duree_validite', 'int') ? GETPOST('duree_validite', 'int') : $conf->global->PROPALE_VALIDITY_DURATION) . '"> ' . $langs->trans("days") . '</td></tr>';
// Terms of payment
print '<tr><td class="nowrap fieldrequired">' . $langs->trans('PaymentConditionsShort') . '</td><td>';

View File

@ -1,7 +1,8 @@
<?php
/* Copyright (C) 2001-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2008 Raphael Bertrand (Resultic) <raphael.bertrand@resultic.fr>
/* Copyright (C) 2001-2004 Rodolphe Quiedeville <rodolphe@quiedeville.org>
* Copyright (C) 2004-2012 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2008 Raphael Bertrand (Resultic) <raphael.bertrand@resultic.fr>
* Copyright (C) 2019 Frédéric France <frederic.france@netlogic.fr>
*
* 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
@ -127,6 +128,8 @@ if ($action == 'confirm_split' && GETPOST("confirm") == 'yes')
$db->begin();
$discount->fk_facture_source=0; // This is to delete only the require record (that we will recreate with two records) and not all family with same fk_facture_source
// This is to delete only the require record (that we will recreate with two records) and not all family with same fk_invoice_supplier_source
$discount->fk_invoice_supplier_source=0;
$res=$discount->delete($user);
$newid1=$newdiscount1->create($user);
$newid2=$newdiscount2->create($user);

View File

@ -638,11 +638,12 @@ else
print '<tr><td>'.$langs->trans("AccountancyJournal").'</td>';
print '<td>';
$accountingjournal = new AccountingJournal($db);
$accountingjournal->fetch($object->fk_accountancy_journal);
print $accountingjournal->getNomUrl(0,1,1,'',1);
if ($object->fk_accountancy_journal > 0) {
$accountingjournal = new AccountingJournal($db);
$accountingjournal->fetch($object->fk_accountancy_journal);
print $accountingjournal->getNomUrl(0, 1, 1, '', 1);
}
print '</td></tr>';
}

View File

@ -1378,8 +1378,9 @@ if (empty($reshook))
{
// Don't add lines with qty 0 when coming from a shipment including all order lines
if($srcobject->element == 'shipping' && $conf->global->SHIPMENT_GETS_ALL_ORDER_PRODUCTS && $lines[$i]->qty == 0) continue;
// Don't add closed lines when coming from a contract
if($srcobject->element == 'contrat' && $lines[$i]->statut == 5) continue;
// Don't add closed lines when coming from a contract (Set constant to '0,5' to exclude also inactive lines)
if (! isset( $conf->global->CONTRACT_EXCLUDE_SERVICES_STATUS_FOR_INVOICE)) $conf->global->CONTRACT_EXCLUDE_SERVICES_STATUS_FOR_INVOICE = '5';
if ($srcobject->element == 'contrat' && in_array($lines[$i]->statut, explode(',', $conf->global->CONTRACT_EXCLUDE_SERVICES_STATUS_FOR_INVOICE))) continue;
$label=(! empty($lines[$i]->label)?$lines[$i]->label:'');
$desc=(! empty($lines[$i]->desc)?$lines[$i]->desc:$lines[$i]->libelle);
@ -1537,14 +1538,16 @@ if (empty($reshook))
$datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
if (empty($datefacture)) {
$error++;
$mesg = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("Date")) . '</div>';
$mesg = $langs->trans("ErrorFieldRequired", $langs->trans("Date"));
setEventMessages($mesg, null, 'errors');
}
$date_pointoftax = dol_mktime(12, 0, 0, $_POST['date_pointoftaxmonth'], $_POST['date_pointoftaxday'], $_POST['date_pointoftaxyear']);
if (!($_POST['situations'] > 0)) {
$error++;
$mesg = '<div class="error">' . $langs->trans("ErrorFieldRequired", $langs->trans("InvoiceSituation")) . '</div>';
$mesg = $langs->trans("ErrorFieldRequired", $langs->trans("InvoiceSituation"));
setEventMessages($mesg, null, 'errors');
}
if (!$error) {
@ -2270,11 +2273,13 @@ if (empty($reshook))
if (!$object->fetch($id) > 0) dol_print_error($db);
if (!is_null(GETPOST('all_progress')) && GETPOST('all_progress') != "")
{
$all_progress = GETPOST('all_progress', 'int');
foreach ($object->lines as $line)
{
$percent = $line->get_prev_progress($object->id);
if (GETPOST('all_progress') < $percent) {
$mesg = '<div class="warning">' . $langs->trans("CantBeLessThanMinPercent") . '</div>';
if (floatval($all_progress) < floatval($percent)) {
$mesg = $langs->trans("Line") . ' ' . $i . ' '. $line->ref .' : ' . $langs->trans("CantBeLessThanMinPercent");
setEventMessages($mesg, null, 'warnings');
$result = -1;
} else
$object->update_percent($line, $_POST['all_progress']);

View File

@ -875,7 +875,7 @@ class Facture extends CommonInvoice
}
elseif ($this->type == self::TYPE_SITUATION && !empty($conf->global->INVOICE_USE_SITUATION))
{
$this->fetchObjectLinked('', '', $facture->id, 'facture');
$this->fetchObjectLinked('', '', $this->id, 'facture');
foreach ($this->linkedObjectsIds as $typeObject => $Tfk_object)
{
@ -3031,6 +3031,12 @@ class Facture extends CommonInvoice
{
global $mysoc,$user;
// Progress should never be changed for discounts
if(($line->info_bits & 2) == 2)
{
return;
}
include_once(DOL_DOCUMENT_ROOT . '/core/lib/price.lib.php');
// Cap percentages to 100
@ -3047,7 +3053,6 @@ class Facture extends CommonInvoice
$line->multicurrency_total_ttc = $tabprice[18];
$line->update($user);
$this->update_price(1);
$this->db->commit();
}
/**
@ -4492,7 +4497,7 @@ class FactureLigne extends CommonInvoiceLine
$sql.= " '".$this->db->escape($this->localtax1_type)."',";
$sql.= " '".$this->db->escape($this->localtax2_type)."',";
$sql.= ' '.(! empty($this->fk_product)?$this->fk_product:"null").',';
$sql.= " ".$this->product_type.",";
$sql.= " ".((int) $this->product_type).",";
$sql.= " ".price2num($this->remise_percent).",";
$sql.= " ".price2num($this->subprice).",";
$sql.= ' '.(! empty($this->fk_remise_except)?$this->fk_remise_except:"null").',';

View File

@ -262,7 +262,7 @@ if ($search_month_date_when > 0)
if ($search_year_date_when > 0 && empty($search_day_date_when))
$sql.= " AND f.date_when BETWEEN '".$db->idate(dol_get_first_day($search_year_date_when,$search_month_date_when,false))."' AND '".$db->idate(dol_get_last_day($search_year_date_when,$search_month_date_when,false))."'";
else if ($search_year_date_when > 0 && ! empty($search_day_date_when))
$sql.= " AND f.date_date_when_reglement BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_month_date_when, $search_day_date_when, $search_year_date_when))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_month_date_when, $search_day_date_when, $search_year_date_when))."'";
$sql.= " AND f.date_when BETWEEN '".$db->idate(dol_mktime(0, 0, 0, $search_month_date_when, $search_day_date_when, $search_year_date_when))."' AND '".$db->idate(dol_mktime(23, 59, 59, $search_month_date_when, $search_day_date_when, $search_year_date_when))."'";
else
$sql.= " AND date_format(f.date_when, '%m') = '".$db->escape($search_month_date_when)."'";
}

View File

@ -530,7 +530,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
$sql = 'SELECT f.rowid as facid, f.facnumber, f.total_ttc, f.multicurrency_code, f.multicurrency_total_ttc, f.type,';
$sql.= ' f.datef as df, f.fk_soc as socid';
$sql.= ' FROM '.MAIN_DB_PREFIX.'facture as f';
$sql.= ' WHERE f.entity IN ('.getEntity('facture', $conf->entity).')';
$sql.= ' WHERE f.entity IN ('.getEntity('facture').')';
$sql.= ' AND (f.fk_soc = '.$facture->socid;
// Can pay invoices of all child of parent company
if(!empty($conf->global->FACTURE_PAYMENTS_ON_DIFFERENT_THIRDPARTIES_BILLS) && !empty($facture->thirdparty->parent)) {
@ -817,7 +817,7 @@ if ($action == 'create' || $action == 'confirm_paiement' || $action == 'add_paie
*/
if (! GETPOST('action','aZ09'))
{
if ($page == -1) $page = 0 ;
if (empty($page) || $page == -1) $page = 0 ;
$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;
$offset = $limit * $page ;

View File

@ -71,7 +71,7 @@ if ($action == 'add_payment' || ($action == 'confirm_paiement' && $confirm=='yes
$error++;
$action = 'create';
}
if (! empty($conf->banque->enabled) && ! $_POST["accountid"] > 0)
if (! empty($conf->banque->enabled) && ! ($_POST["accountid"] > 0))
{
setEventMessages($langs->trans("ErrorFieldRequired",$langs->transnoentities("AccountToCredit")), null, 'errors');
$error++;

View File

@ -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);

View File

@ -301,17 +301,17 @@ class ChargeSociales extends CommonObject
$sql.= ", date_ech='".$this->db->idate($this->date_ech)."'";
$sql.= ", periode='".$this->db->idate($this->periode)."'";
$sql.= ", amount='".price2num($this->amount,'MT')."'";
$sql.= ", fk_projet='".$this->db->escape($this->fk_project)."'";
$sql.= ", fk_projet=".($this->fk_project>0?$this->db->escape($this->fk_project):"NULL");
$sql.= ", fk_user_modif=".$user->id;
$sql.= " WHERE rowid=".$this->id;
dol_syslog(get_class($this)."::update", LOG_DEBUG);
$resql=$this->db->query($sql);
if (! $resql) {
$error++; $this->errors[]="Error ".$this->db->lasterror();
}
if (! $error)
{
if (! $notrigger)
@ -322,7 +322,7 @@ class ChargeSociales extends CommonObject
// End call triggers
}
}
// Commit or rollback
if ($error)
{
@ -339,8 +339,8 @@ class ChargeSociales extends CommonObject
$this->db->commit();
return 1;
}
}
/**

View File

@ -55,7 +55,7 @@ $result = restrictedArea($user, 'tax', $id, 'chargesociales','charges');
$sortfield = GETPOST("sortfield",'alpha');
$sortorder = GETPOST("sortorder",'alpha');
$page = GETPOST("page",'int');
if ($page == -1) {
if (empty($page) || $page == -1) {
$page = 0;
}
$offset = $conf->liste_limit * $page;

View File

@ -37,7 +37,7 @@ require_once DOL_DOCUMENT_ROOT.'/expensereport/class/paymentexpensereport.class.
// Load translation files required by the page
$langs->loadLangs(array("other","compta","banks","bills","companies","product","trips","admin","accountancy"));
$modecompta = GETPOST('modecompta','alpha');
$modecompta = (GETPOST('modecompta', 'alpha') ? GETPOST('modecompta', 'alpha') : $conf->global->ACCOUNTING_MODE);
// Date range
$year=GETPOST("year",'int');

View File

@ -56,9 +56,10 @@ $result = restrictedArea($user, 'tax', $id, 'vat','charges');
$sortfield = GETPOST("sortfield",'alpha');
$sortorder = GETPOST("sortorder",'alpha');
$page = GETPOST("page",'int');
if ($page == -1) {
if (empty($page) || $page == -1) {
$page = 0;
}
$offset = $conf->liste_limit * $page;
$pageprev = $page - 1;
$pagenext = $page + 1;

View File

@ -78,6 +78,14 @@ $result = restrictedArea($user, 'contact', $id, 'socpeople&societe', '', '', 'ro
// Initialize technical object to manage hooks of page. Note that conf->hooks_modules contains array of hook context
$hookmanager->initHooks(array('contactcard','globalcard'));
if ($id > 0) $object->fetch($id);
if (! ($object->id > 0) && $action == 'view')
{
$langs->load("errors");
print($langs->trans('ErrorRecordNotFound'));
exit;
}
/*
* Actions

View File

@ -3,7 +3,7 @@
* Copyright (C) 2004-2017 Laurent Destailleur <eldy@users.sourceforge.net>
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
* Copyright (C) 2014 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2014-2019 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2015 Claudio Aschieri <c.aschieri@19.coop>
* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
* Copyright (C) 2016-2018 Ferran Marcet <fmarcet@2byte.es>
@ -45,14 +45,14 @@ $confirm=GETPOST('confirm','alpha');
$toselect = GETPOST('toselect', 'array');
$contextpage= GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'contractlist'; // To manage different context of search
$search_name=GETPOST('search_name');
$search_email=GETPOST('search_email');
$search_name=GETPOST('search_name', 'alpha');
$search_email=GETPOST('search_email', 'alpha');
$search_town=GETPOST('search_town','alpha');
$search_zip=GETPOST('search_zip','alpha');
$search_state=trim(GETPOST("search_state"));
$search_country=GETPOST("search_country",'int');
$search_type_thirdparty=GETPOST("search_type_thirdparty",'int');
$search_contract=GETPOST('search_contract');
$search_contract=GETPOST('search_contract','alpha');
$search_ref_customer=GETPOST('search_ref_customer','alpha');
$search_ref_supplier=GETPOST('search_ref_supplier','alpha');
$sall=trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alphanohtml'):GETPOST('sall', 'alphanohtml'));

View File

@ -4,6 +4,7 @@
* Copyright (C) 2005-2012 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
* Copyright (C) 2018 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2019 Juanjo Menent <jmenent@2byte.es>
*
* 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
@ -46,9 +47,9 @@ if (! $sortorder) $sortorder="ASC";
$mode = GETPOST("mode");
$filter=GETPOST("filter");
$search_name=GETPOST("search_name");
$search_contract=GETPOST("search_contract");
$search_service=GETPOST("search_service");
$search_name=GETPOST("search_name", 'alpha');
$search_contract=GETPOST("search_contract", 'alpha');
$search_service=GETPOST("search_service", 'alpha');
$search_status=GETPOST("search_status","alpha");
$statut=GETPOST('statut')?GETPOST('statut'):1;
$search_product_category=GETPOST('search_product_category','int');

View File

@ -118,8 +118,7 @@ if ($action == 'confirm_deletefile' && $confirm == 'yes')
{
require_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php';
$link = new Link($db);
$link->id = $linkid;
$link->fetch();
$link->fetch($linkid);
$res = $link->delete($user);
$langs->load('link');
@ -153,8 +152,7 @@ elseif ($action == 'confirm_updateline' && GETPOST('save','alpha') && GETPOST('l
require_once DOL_DOCUMENT_ROOT . '/core/class/link.class.php';
$langs->load('link');
$link = new Link($db);
$link->id = GETPOST('linkid', 'int');
$f = $link->fetch();
$f = $link->fetch(GETPOST('linkid', 'int'));
if ($f)
{
$link->url = GETPOST('link', 'alpha');
@ -162,7 +160,7 @@ elseif ($action == 'confirm_updateline' && GETPOST('save','alpha') && GETPOST('l
{
$link->url = 'http://' . $link->url;
}
$link->label = GETPOST('label', 'alpha');
$link->label = GETPOST('label', 'alphanohtml');
$res = $link->update($user);
if (!$res)
{

View File

@ -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();
@ -209,7 +210,7 @@ if (! $error && $massaction == 'confirm_presend')
$resaction.='<div class="error">'.$langs->trans('ErrorOnlyProposalNotDraftCanBeSentInMassAction',$objectobj->ref).'</div><br>';
continue; // Payment done or started or canceled
}
if ($objectclass == 'Commande' && $objectoj->statut == Commande::STATUS_DRAFT)
if ($objectclass == 'Commande' && $objectobj->statut == Commande::STATUS_DRAFT)
{
$langs->load("errors");
$nbignored++;
@ -257,19 +258,30 @@ if (! $error && $massaction == 'confirm_presend')
{
// TODO Use future field $objectobj->fullpathdoc to know where is stored default file
// 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';
$filedir=$uploaddir . '/' . dol_sanitizeFileName($objectobj->ref);
$filename = dol_sanitizeFileName($objectobj->ref).'.pdf';
$subdir = '';
// 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;
// For supplier invoices, we use the file provided by supplier, not the one we generate
if ($objectobj->element == 'invoice_supplier')
{
$fileparams = dol_most_recent_file($uploaddir . '/' . get_exdir($objectobj->id,2,0,0,$objectobj,$objectobj->element).$objectobj->ref, preg_quote($objectobj->ref,'/').'([^\-])+');
$file = $fileparams['fullname'];
}
$mime = dol_mimetype($file);
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
{
@ -335,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)
{
@ -352,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);
@ -373,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.='<div class="error">'.$mailfile->error.'</div>';
@ -399,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';
@ -412,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';
@ -438,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
@ -451,7 +494,7 @@ if (! $error && $massaction == 'confirm_presend')
}
}
$nbsent++;
$nbsent++; // Nb of record sent
}
}
else
@ -525,7 +568,7 @@ if ($massaction == 'confirm_createbills')
$objecttmp->cond_reglement_id = $cmd->cond_reglement_id;
$objecttmp->mode_reglement_id = $cmd->mode_reglement_id;
$objecttmp->fk_project = $cmd->fk_project;
$objecttmp->multicurrency_code = $cmd->multicurrency_code;
$datefacture = dol_mktime(12, 0, 0, $_POST['remonth'], $_POST['reday'], $_POST['reyear']);
if (empty($datefacture))
{
@ -725,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='';

View File

@ -43,7 +43,7 @@ if (GETPOST('addfile','alpha'))
$vardir=$conf->user->dir_output."/".$user->id;
$upload_dir_tmp = $vardir.'/temp'; // TODO Add $keytoavoidconflict in upload_dir path
dol_add_file_process($upload_dir_tmp, 0, 0, 'addedfile', '', null, $trackid, 0);
dol_add_file_process($upload_dir_tmp, 1, 0, 'addedfile', '', null, $trackid, 0);
$action='presend';
}
@ -468,7 +468,7 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO
$mesg='<div class="error">';
if ($mailfile->error)
{
$mesg.=$langs->trans('ErrorFailedToSendMail',$from,$sendto);
$mesg.=$langs->transnoentities('ErrorFailedToSendMail',dol_escape_htmltag($from),dol_escape_htmltag($sendto));
$mesg.='<br>'.$mailfile->error;
}
else

View File

@ -517,6 +517,31 @@ class CMailFile
return true;
}
$sendingmode = $this->sendmode;
if ($this->context == 'emailing' && ! empty($conf->global->MAILING_NO_USING_PHPMAIL) && $sendingmode == 'mail')
{
// List of sending methods
$listofmethods=array();
$listofmethods['mail']='PHP mail function';
//$listofmethods['simplemail']='Simplemail class';
$listofmethods['smtps']='SMTP/SMTPS socket library';
// EMailing feature may be a spam problem, so when you host several users/instance, having this option may force each user to use their own SMTP agent.
// You ensure that every user is using its own SMTP server when using the mass emailing module.
$linktoadminemailbefore='';
$linktoadminemailend='';
$this->error = $langs->trans("MailSendSetupIs", $listofmethods[$sendingmode]);
$this->errors[] = $langs->trans("MailSendSetupIs", $listofmethods[$sendingmode]);
$this->error .= '<br>'.$langs->trans("MailSendSetupIs2", $linktoadminemailbefore, $linktoadminemailend, $langs->transnoentitiesnoconv("MAIN_MAIL_SENDMODE"), $listofmethods['smtps']);
$this->errors[] = $langs->trans("MailSendSetupIs2", $linktoadminemailbefore, $linktoadminemailend, $langs->transnoentitiesnoconv("MAIN_MAIL_SENDMODE"), $listofmethods['smtps']);
if (! empty($conf->global->MAILING_SMTP_SETUP_EMAILS_FOR_QUESTIONS))
{
$this->error .= '<br>'.$langs->trans("MailSendSetupIs3", $conf->global->MAILING_SMTP_SETUP_EMAILS_FOR_QUESTIONS);
$this->errors[] = $langs->trans("MailSendSetupIs3", $conf->global->MAILING_SMTP_SETUP_EMAILS_FOR_QUESTIONS);
}
return false;
}
// Check number of recipient is lower or equal than MAIL_MAX_NB_OF_RECIPIENTS_IN_SAME_EMAIL
if (empty($conf->global->MAIL_MAX_NB_OF_RECIPIENTS_TO_IN_SAME_EMAIL)) $conf->global->MAIL_MAX_NB_OF_RECIPIENTS_TO_IN_SAME_EMAIL=10;
$tmparray1 = explode(',', $this->addr_to);

View File

@ -195,6 +195,29 @@ abstract class CommonInvoice extends CommonObject
}
}
/**
* Return amount (with tax) of all converted amount for this credit note
*
* @param int $multicurrency Return multicurrency_amount instead of amount
* @return int <0 if KO, Sum of credit notes and deposits amount otherwise
*/
function getSumFromThisCreditNotesNotUsed($multicurrency=0)
{
require_once DOL_DOCUMENT_ROOT.'/core/class/discount.class.php';
$discountstatic=new DiscountAbsolute($this->db);
$result=$discountstatic->getSumFromThisCreditNotesNotUsed($this, $multicurrency);
if ($result >= 0)
{
return $result;
}
else
{
$this->error=$discountstatic->error;
return -1;
}
}
/**
* Renvoie tableau des ids de facture avoir issus de la facture
*

View File

@ -12,7 +12,7 @@
* Copyright (C) 2015 Alexandre Spangaro <aspangaro.dolibarr@gmail.com>
* Copyright (C) 2016 Bahfir abbes <dolipar@dolipar.org>
* Copyright (C) 2017 ATM Consulting <support@atm-consulting.fr>
* Copyright (C) 2017 Nicolas ZABOURI <info@inovea-conseil.com>
* Copyright (C) 2017-2019 Nicolas ZABOURI <info@inovea-conseil.com>
* Copyright (C) 2017 Rui Strecht <rui.strecht@aliartalentos.com>
* Copyright (C) 2018 Frederic France <frederic.france@netlogic.fr>
*
@ -2615,7 +2615,7 @@ abstract class CommonObject
$MODULE = "";
if ($this->element == 'propal')
$MODULE = "MODULE_DISALLOW_UPDATE_PRICE_PROPOSAL";
elseif ($this->element == 'order')
elseif ($this->element == 'commande' || $this->element == 'order')
$MODULE = "MODULE_DISALLOW_UPDATE_PRICE_ORDER";
elseif ($this->element == 'facture')
$MODULE = "MODULE_DISALLOW_UPDATE_PRICE_INVOICE";
@ -3715,10 +3715,11 @@ abstract class CommonObject
// Output template part (modules that overwrite templates must declare this into descriptor)
// Use global variables + $dateSelector + $seller and $buyer
$dirtpls=array_merge($conf->modules_parts['tpl'],array('/core/tpl'));
$dirtpls=array_merge($conf->modules_parts['tpl'], array('/core/tpl'));
foreach($dirtpls as $reldir)
{
$tpl = dol_buildpath($reldir.'/objectline_create.tpl.php');
if (empty($conf->file->strict_mode)) {
$res=@include $tpl;
} else {
@ -3967,10 +3968,11 @@ abstract class CommonObject
// Output template part (modules that overwrite templates must declare this into descriptor)
// Use global variables + $dateSelector + $seller and $buyer
$dirtpls=array_merge($conf->modules_parts['tpl'],array('/core/tpl'));
$dirtpls=array_merge($conf->modules_parts['tpl'], array('/core/tpl'));
foreach($dirtpls as $reldir)
{
$tpl = dol_buildpath($reldir.'/objectline_view.tpl.php');
if (empty($conf->file->strict_mode)) {
$res=@include $tpl;
} else {
@ -3990,10 +3992,11 @@ abstract class CommonObject
// Output template part (modules that overwrite templates must declare this into descriptor)
// Use global variables + $dateSelector + $seller and $buyer
$dirtpls=array_merge($conf->modules_parts['tpl'],array('/core/tpl'));
$dirtpls=array_merge($conf->modules_parts['tpl'], array('/core/tpl'));
foreach($dirtpls as $reldir)
{
$tpl = dol_buildpath($reldir.'/objectline_edit.tpl.php');
if (empty($conf->file->strict_mode)) {
$res=@include $tpl;
} else {
@ -4186,10 +4189,11 @@ abstract class CommonObject
// Output template part (modules that overwrite templates must declare this into descriptor)
// Use global variables + $dateSelector + $seller and $buyer
$dirtpls=array_merge($conf->modules_parts['tpl'],array('/core/tpl'));
$dirtpls=array_merge($conf->modules_parts['tpl'], array('/core/tpl'));
foreach($dirtpls as $reldir)
{
$tpl = dol_buildpath($reldir.'/originproductline.tpl.php');
if (empty($conf->file->strict_mode)) {
$res=@include $tpl;
} else {

View File

@ -91,7 +91,7 @@ class DiscountAbsolute
$sql.= " FROM ".MAIN_DB_PREFIX."societe_remise_except as sr";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as f ON sr.fk_facture_source = f.rowid";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."facture as fsup ON sr.fk_invoice_supplier_source = fsup.rowid";
$sql.= " WHERE sr.entity = " . $conf->entity;
$sql.= " WHERE sr.entity IN (".getEntity('invoice').")";
if ($rowid) $sql.= " AND sr.rowid=".$rowid;
if ($fk_facture_source) $sql.= " AND sr.fk_facture_source=".$fk_facture_source;
if ($fk_invoice_supplier_source) $sql.= " AND sr.fk_invoice_supplier_source=".$fk_invoice_supplier_source;
@ -568,6 +568,49 @@ class DiscountAbsolute
return -1;
}
}
/**
* Return amount (with tax) of all converted amount for this credit note
*
* @param CommonInvoice $invoice Object invoice
* @param int $multicurrency Return multicurrency_amount instead of amount
* @return int <0 if KO, Sum of credit notes and deposits amount otherwise
*/
function getSumFromThisCreditNotesNotUsed($invoice, $multicurrency=0)
{
dol_syslog(get_class($this)."::getSumCreditNotesUsed", LOG_DEBUG);
if ($invoice->element == 'facture' || $invoice->element == 'invoice')
{
$sql = 'SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount';
$sql.= ' FROM '.MAIN_DB_PREFIX.'societe_remise_except as rc';
$sql.= ' WHERE rc.fk_facture IS NULL AND rc.fk_facture_source = '.$invoice->id;
}
else if ($invoice->element == 'invoice_supplier')
{
$sql = 'SELECT sum(rc.amount_ttc) as amount, sum(rc.multicurrency_amount_ttc) as multicurrency_amount';
$sql.= ' FROM '.MAIN_DB_PREFIX.'societe_remise_except as rc';
$sql.= ' WHERE rc.fk_invoice_supplier IS NULL AND rc.fk_invoice_supplier_source = '.$invoice->id;
}
else
{
$this->error=get_class($this)."::getSumCreditNotesUsed was called with a bad object as a first parameter";
dol_print_error($this->error);
return -1;
}
$resql=$this->db->query($sql);
if ($resql)
{
$obj = $this->db->fetch_object($resql);
if ($multicurrency) return $obj->multicurrency_amount;
else return $obj->amount;
}
else
{
$this->error = $this->db->lasterror();
return -1;
}
}
/**
* Return clickable ref of object (with picto or not)

View File

@ -1194,13 +1194,14 @@ class ExtraFields
if ($value == $obj->rowid)
{
foreach ($fields_label as $field_toshow)
{
$translabel=$langs->trans($obj->$field_toshow);
if ($translabel!=$obj->$field_toshow) {
$labeltoshow=dol_trunc($translabel,18).' ';
}else {
$labeltoshow=dol_trunc($obj->$field_toshow,18).' ';
if (! $notrans) {
foreach ($fields_label as $field_toshow) {
$translabel = $langs->trans($obj->$field_toshow);
if ($translabel != $obj->$field_toshow) {
$labeltoshow = dol_trunc($translabel, 18) . ' ';
} else {
$labeltoshow = dol_trunc($obj->$field_toshow, 18) . ' ';
}
}
}
$out.='<option value="'.$obj->rowid.'" selected>'.$labeltoshow.'</option>';
@ -1829,7 +1830,7 @@ class ExtraFields
function setOptionalsFromPost($extralabels, &$object, $onlykey='')
{
global $_POST, $langs;
$nofillrequired='';// For error when required field left blank
$nofillrequired=0;// For error when required field left blank
$error_field_required = array();
if (is_array($this->attributes[$object->table_element]['label'])) $extralabels=$this->attributes[$object->table_element]['label'];
@ -1860,8 +1861,9 @@ class ExtraFields
if ($this->attributes[$object->table_element]['required'][$key]) // Value is required
{
// Check if empty without using GETPOST, value can be alpha, int, array, etc...
if ((! is_array($_POST["options_".$key]) && empty($_POST["options_".$key]) && $_POST["options_".$key] != '0')
|| (is_array($_POST["options_".$key]) && empty($_POST["options_".$key])))
if ((! is_array($_POST["options_".$key]) && empty($_POST["options_".$key]) && $this->attributes[$object->table_element]['type'][$key] != 'select' && $_POST["options_".$key] != '0')
|| (! is_array($_POST["options_".$key]) && empty($_POST["options_".$key]) && $this->attributes[$object->table_element]['type'][$key] == 'select')
|| (is_array($_POST["options_".$key]) && empty($_POST["options_".$key])))
{
//print 'ccc'.$value.'-'.$this->attributes[$object->table_element]['required'][$key];
$nofillrequired++;

View File

@ -1785,6 +1785,15 @@ class Form
$price_level = (! empty($price_level) ? $price_level : 0);
if(strval($filtertype) === '' && (!empty($conf->product->enabled) || !empty($conf->service->enabled))){
if(!empty($conf->product->enabled) && empty($conf->service->enabled)){
$filtertype = '0';
}
elseif(empty($conf->product->enabled) && !empty($conf->service->enabled)){
$filtertype = '1';
}
}
if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->PRODUIT_USE_SEARCH_TO_SELECT))
{
$placeholder='';

View File

@ -761,7 +761,7 @@ class FormFile
$out.= '<a class="documentdownload paddingright" href="'.$documenturl.'?modulepart='.$modulepart.'&amp;file='.urlencode($relativepath).($param?'&'.$param:'').'"';
$mime=dol_mimetype($relativepath,'',0);
if (preg_match('/text/',$mime)) $out.= ' target="_blank"';
$out.= ' target="_blank">';
$out.= '>';
$out.= img_mime($file["name"],$langs->trans("File").': '.$file["name"]);
$out.= dol_trunc($file["name"], 150);
$out.= '</a>'."\n";
@ -1757,7 +1757,7 @@ class FormFile
print $langs->trans('Link') . ': <input type="text" name="link" value="' . $link->url . '">';
print '</td>';
print '<td>';
print $langs->trans('Label') . ': <input type="text" name="label" value="' . $link->label . '">';
print $langs->trans('Label') . ': <input type="text" name="label" value="' . dol_escape_htmltag($link->label) . '">';
print '</td>';
print '<td align="center">' . dol_print_date(dol_now(), "dayhour", "tzuser") . '</td>';
print '<td align="right"></td>';
@ -1771,7 +1771,7 @@ class FormFile
print '<td>';
print img_picto('', 'object_globe').' ';
print '<a data-ajax="false" href="' . $link->url . '" target="_blank">';
print $link->label;
print dol_escape_htmltag($link->label);
print '</a>';
print '</td>'."\n";
print '<td align="right"></td>';

View File

@ -359,6 +359,7 @@ class FormMail extends Form
if ($this->param['models'] != 'none')
{
$result = $this->fetchAllEMailTemplate($this->param["models"], $user, $outputlangs);
if ($result < 0)
{
setEventMessages($this->error, $this->errors, 'errors');
@ -991,7 +992,6 @@ class FormMail extends Form
$defaultmessage=preg_replace("/^(<br>)+/","",$defaultmessage);
$defaultmessage=preg_replace("/^\n+/","",$defaultmessage);
}
$out.= '<tr>';
$out.= '<td valign="top">';
$out.=$form->textwithpicto($langs->trans('MailText'), $helpforsubstitution, 1, 'help', '', 0, 2, 'substittooltipfrombody');

View File

@ -91,7 +91,7 @@ class FormMargin
$line->pa_ht = $line->subprice * (1 - ($line->remise_percent / 100));
}
$pv = $line->qty * $line->subprice * (1 - $line->remise_percent / 100);
$pv = $line->total_ht;
$pa_ht = ($pv < 0 ? - $line->pa_ht : $line->pa_ht); // We choosed to have line->pa_ht always positive in database, so we guess the correct sign
$pa = $line->qty * $pa_ht;

View File

@ -374,9 +374,9 @@ class FormOther
* @param string $morecss More CSS
* @return string Html combo list code
*/
function select_salesrepresentatives($selected,$htmlname,$user,$showstatus=0,$showempty=1,$morecss='')
function select_salesrepresentatives($selected, $htmlname, $user, $showstatus=0, $showempty=1, $morecss='')
{
global $conf,$langs;
global $conf, $langs;
$langs->load('users');
$out = '';
@ -398,17 +398,44 @@ class FormOther
// Get list of users allowed to be viewed
$sql_usr = "SELECT u.rowid, u.lastname, u.firstname, u.statut, u.login";
$sql_usr.= " FROM ".MAIN_DB_PREFIX."user as u";
$sql_usr.= " WHERE u.entity IN (0,".$conf->entity.")";
if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))
{
if (! empty($user->admin) && empty($user->entity) && $conf->entity == 1) {
$sql_usr.= " WHERE u.entity IS NOT NULL"; // Show all users
} else {
$sql_usr.= " WHERE EXISTS (SELECT ug.fk_user FROM ".MAIN_DB_PREFIX."usergroup_user as ug WHERE u.rowid = ug.fk_user AND ug.entity IN (".getEntity('user')."))";
$sql_usr.= " OR u.entity = 0"; // Show always superadmin
}
}
else
{
$sql_usr.= " WHERE u.entity IN (".getEntity('user').")";
}
if (empty($user->rights->user->user->lire)) $sql_usr.=" AND u.rowid = ".$user->id;
if (! empty($user->societe_id)) $sql_usr.=" AND u.fk_soc = ".$user->societe_id;
if (! empty($user->socid)) $sql_usr.=" AND u.fk_soc = ".$user->socid;
// Add existing sales representatives of thirdparty of external user
if (empty($user->rights->user->user->lire) && $user->societe_id)
if (empty($user->rights->user->user->lire) && $user->socid)
{
$sql_usr.=" UNION ";
$sql_usr.= "SELECT u2.rowid, u2.lastname, u2.firstname, u2.statut, u2.login";
$sql_usr.= " FROM ".MAIN_DB_PREFIX."user as u2, ".MAIN_DB_PREFIX."societe_commerciaux as sc";
$sql_usr.= " WHERE u2.entity IN (0,".$conf->entity.")";
$sql_usr.= " AND u2.rowid = sc.fk_user AND sc.fk_soc=".$user->societe_id;
if (! empty($conf->global->MULTICOMPANY_TRANSVERSE_MODE))
{
if (! empty($user->admin) && empty($user->entity) && $conf->entity == 1) {
$sql_usr.= " WHERE u2.entity IS NOT NULL"; // Show all users
} else {
$sql_usr.= " WHERE EXISTS (SELECT ug2.fk_user FROM ".MAIN_DB_PREFIX."usergroup_user as ug2 WHERE u2.rowid = ug2.fk_user AND ug2.entity IN (".getEntity('user')."))";
}
}
else
{
$sql_usr.= " WHERE u2.entity IN (".getEntity('user').")";
}
$sql_usr.= " AND u2.rowid = sc.fk_user AND sc.fk_soc=".$user->socid;
}
$sql_usr.= " ORDER BY statut DESC, lastname ASC"; // Do not use 'ORDER BY u.statut' here, not compatible with the UNION.
//print $sql_usr;exit;

View File

@ -151,6 +151,8 @@ class Interfaces
$i++;
}
}
closedir($handle);
}
}

View File

@ -329,6 +329,7 @@ class Notify
$sql.= " ".MAIN_DB_PREFIX."societe as s";
$sql.= " WHERE n.fk_contact = c.rowid AND a.rowid = n.fk_action";
$sql.= " AND n.fk_soc = s.rowid";
$sql.= " AND c.statut = 1";
if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode; // Old usage
else $sql.= " AND a.code = '".$notifcode."'"; // New usage
$sql .= " AND s.rowid = ".$object->socid;
@ -342,6 +343,7 @@ class Notify
$sql.= " ".MAIN_DB_PREFIX."c_action_trigger as a,";
$sql.= " ".MAIN_DB_PREFIX."notify_def as n";
$sql.= " WHERE n.fk_user = c.rowid AND a.rowid = n.fk_action";
$sql.= " AND c.statut = 1";
if (is_numeric($notifcode)) $sql.= " AND n.fk_action = ".$notifcode; // Old usage
else $sql.= " AND a.code = '".$notifcode."'"; // New usage

View File

@ -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

View File

@ -91,17 +91,11 @@ function parseTime(timeStr, dt)
dt = new Date();
}
var time = timeStr.match(/(\d+)(?::(\d\d))?\s*(p?)/i);
var time = timeStr.match(/(\d+)(?::(\d\d))?/i);
if (!time) {
return -1;
}
var hours = parseInt(time[1], 10);
if (hours == 12 && !time[3]) {
hours = 0;
}
else {
hours += (hours < 12 && time[3]) ? 12 : 0;
}
dt.setHours(hours);
dt.setMinutes(parseInt(time[2], 10) || 0);

View File

@ -818,7 +818,7 @@ function show_projects($conf, $langs, $db, $object, $backtopage='', $nocreatelin
}
else
{
print '<tr class="oddeven"><td colspan="5" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
print '<tr class="oddeven"><td colspan="8" class="opacitymedium">'.$langs->trans("None").'</td></tr>';
}
$db->free($result);
}

View File

@ -1557,6 +1557,11 @@ function dol_add_file_process($upload_dir, $allowoverwrite=0, $donotupdatesessio
$info = pathinfo($destfile);
$destfile = dol_sanitizeFileName($info['filename'].'.'.strtolower($info['extension']));
// We apply dol_string_nohtmltag also to clean file names (this remove duplicate spaces) because
// this function is also applied when we make try to download file (by the GETPOST(filename, 'alphanohtml') call).
$destfile = dol_string_nohtmltag($destfile);
$destfull = dol_string_nohtmltag($destfull);
$resupload = dol_move_uploaded_file($TFile['tmp_name'][$i], $destfull, $allowoverwrite, 0, $TFile['error'][$i], 0, $varfiles);
if (is_numeric($resupload) && $resupload > 0) // $resupload can be 'ErrorFileAlreadyExists'
@ -1838,10 +1843,15 @@ function dol_convert_file($fileinput, $ext='png', $fileoutput='')
if (empty($fileoutput)) $fileoutput=$fileinput.".".$ext;
$count = $image->getNumberImages();
if (! dol_is_file($fileoutput) || is_writeable($fileoutput))
{
$ret = $image->writeImages($fileoutput, true);
try {
$ret = $image->writeImages($fileoutput, true);
}
catch(Exception $e)
{
dol_syslog($e->getMessage(), LOG_WARNING);
}
}
else
{

View File

@ -1436,6 +1436,7 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r
{
if (empty($conf->global->MAIN_DISABLE_PDF_THUMBS)) // If you experienc trouble with pdf thumb generation and imagick, you can disable here.
{
include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php';
$ret = dol_convert_file($file, 'png', $fileimage);
if ($ret < 0) $error++;
}
@ -6233,6 +6234,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

View File

@ -716,8 +716,8 @@ function get_next_value($db,$mask,$table,$field,$where='',$objsoc='',$date='',$m
global $conf,$user;
if (! is_object($objsoc)) $valueforccc=$objsoc;
else if ($table == "commande_fournisseur" || $table == "facture_fourn" ) $valueforccc=$objsoc->code_fournisseur;
else $valueforccc=$objsoc->code_client;
else if ($table == "commande_fournisseur" || $table == "facture_fourn" ) $valueforccc=dol_string_unaccent($objsoc->code_fournisseur);
else $valueforccc=dol_string_unaccent($objsoc->code_client);
$sharetable = $table;
if ($table == 'facture' || $table == 'invoice') $sharetable = 'invoicenumber'; // for getEntity function
@ -965,6 +965,7 @@ function get_next_value($db,$mask,$table,$field,$where='',$objsoc='',$date='',$m
// Define $maskLike
$maskLike = dol_string_nospecial($mask);
$maskLike = str_replace("%","_",$maskLike);
// Replace protected special codes with matching number of _ as wild card caracter
$maskLike = preg_replace('/\{yyyy\}/i','____',$maskLike);
$maskLike = preg_replace('/\{yy\}/i','__',$maskLike);
@ -1140,7 +1141,7 @@ function get_next_value($db,$mask,$table,$field,$where='',$objsoc='',$date='',$m
// Now we replace the refclient
if ($maskrefclient)
{
//print "maskrefclient=".$maskrefclient." maskwithonlyymcode=".$maskwithonlyymcode." maskwithnocode=".$maskwithnocode."\n<br>";
//print "maskrefclient=".$maskrefclient." maskwithonlyymcode=".$maskwithonlyymcode." maskwithnocode=".$maskwithnocode." maskrefclient_clientcode=".$maskrefclient_clientcode."\n<br>";exit;
$maskrefclient_maskbefore='{'.$maskrefclient.'}';
$maskrefclient_maskafter=$maskrefclient_clientcode.str_pad($maskrefclient_counter,dol_strlen($maskrefclient_maskcounter),"0",STR_PAD_LEFT);
$numFinal = str_replace($maskrefclient_maskbefore,$maskrefclient_maskafter,$numFinal);
@ -1250,6 +1251,10 @@ function check_value($mask,$value)
if (! empty($reg[3]) && preg_match('/^@/',$reg[3])) $maskraz=preg_replace('/^@/','',$reg[3]);
if ($maskraz >= 0)
{
if ($maskraz == 99) {
$maskraz = date('m');
$resetEveryMonth = true;
}
if ($maskraz > 12) return 'ErrorBadMaskBadRazMonth';
// Define reg

View File

@ -144,8 +144,8 @@ function user_prepare_head($object)
if ((! empty($conf->salaries->enabled) && ! empty($user->rights->salaries->read))
|| (! empty($conf->hrm->enabled) && ! empty($user->rights->hrm->employee->read))
|| (! empty($conf->expensereport->enabled) && ! empty($user->rights->expensereport->lire) && $user->id == $object->id)
|| (! empty($conf->holiday->enabled) && ! empty($user->rights->holiday->read) && $user->id == $object->id )
|| (! empty($conf->expensereport->enabled) && ! empty($user->rights->expensereport->lire) && ($user->id == $object->id || $user->rights->expensereport->readall))
|| (! empty($conf->holiday->enabled) && ! empty($user->rights->holiday->read) && ($user->id == $object->id || $user->rights->holiday->read_all))
)
{
// Bank

View File

@ -396,7 +396,11 @@ class doc_generic_shipment_odt extends ModelePdfExpedition
}
}
// Make substitutions into odt of thirdparty
$tmparray=$this->get_substitutionarray_thirdparty($socobject,$outputlangs);
if ($socobject->element == 'contact') {
$tmparray = $this->get_substitutionarray_contact($socobject, $outputlangs);
} else {
$tmparray = $this->get_substitutionarray_thirdparty($socobject, $outputlangs);
}
foreach($tmparray as $key=>$value)
{
try {

View File

@ -1211,24 +1211,6 @@ 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

View File

@ -493,15 +493,24 @@ class ImportCsv extends ModeleImports
if (! empty($objimport->array_import_regex[0][$val]) && ($newval != ''))
{
// If test is "Must exist in a field@table"
if (preg_match('/^(.*)@(.*)$/',$objimport->array_import_regex[0][$val],$reg))
if (preg_match('/^(.+)@([^:]+)(:.+)?$/',$objimport->array_import_regex[0][$val],$reg))
{
$field=$reg[1];
$table=$reg[2];
$filter=!empty($reg[3])?substr($reg[3], 1):'';
$cachekey = $field.'@'.$table;
if(! empty($filter)) $cachekey.= ':'.$filter;
// Load content of field@table into cache array
if (! is_array($this->cachefieldtable[$field.'@'.$table])) // If content of field@table not already loaded into cache
if (! is_array($this->cachefieldtable[$cachekey])) // If content of field@table not already loaded into cache
{
$sql="SELECT ".$field." as aliasfield FROM ".$table;
if(! empty($filter))
{
$sql.= ' WHERE ' . $filter;
}
$resql=$this->db->query($sql);
if ($resql)
{
@ -510,7 +519,7 @@ class ImportCsv extends ModeleImports
while ($i < $num)
{
$obj=$this->db->fetch_object($resql);
if ($obj) $this->cachefieldtable[$field.'@'.$table][]=$obj->aliasfield;
if ($obj) $this->cachefieldtable[$cachekey][]=$obj->aliasfield;
$i++;
}
}
@ -521,9 +530,11 @@ class ImportCsv extends ModeleImports
}
// Now we check cache is not empty (should not) and key is into cache
if (! is_array($this->cachefieldtable[$field.'@'.$table]) || ! in_array($newval,$this->cachefieldtable[$field.'@'.$table]))
if (! is_array($this->cachefieldtable[$cachekey]) || ! in_array($newval,$this->cachefieldtable[$cachekey]))
{
$this->errors[$error]['lib']=$langs->transnoentitiesnoconv('ErrorFieldValueNotIn',$key,$newval,$field,$table);
$tableforerror = $table;
if(! empty($filter)) $tableforerror.= ':'.$filter;
$this->errors[$error]['lib']=$langs->transnoentitiesnoconv('ErrorFieldValueNotIn',$key,$newval,$field,$tableforerror);
$this->errors[$error]['type']='FOREIGNKEY';
$errorforthistable++;
$error++;

View File

@ -519,15 +519,24 @@ class ImportXlsx extends ModeleImports
if (! empty($objimport->array_import_regex[0][$val]) && ($newval != ''))
{
// If test is "Must exist in a field@table"
if (preg_match('/^(.*)@(.*)$/',$objimport->array_import_regex[0][$val],$reg))
if (preg_match('/^(.+)@([^:]+)(:.+)?$/',$objimport->array_import_regex[0][$val],$reg))
{
$field=$reg[1];
$table=$reg[2];
$filter=!empty($reg[3])?substr($reg[3], 1):'';
$cachekey = $field.'@'.$table;
if(! empty($filter)) $cachekey.= ':'.$filter;
// Load content of field@table into cache array
if (! is_array($this->cachefieldtable[$field.'@'.$table])) // If content of field@table not already loaded into cache
if (! is_array($this->cachefieldtable[$cachekey])) // If content of field@table not already loaded into cache
{
$sql="SELECT ".$field." as aliasfield FROM ".$table;
if(! empty($filter))
{
$sql.= ' WHERE ' . $filter;
}
$resql=$this->db->query($sql);
if ($resql)
{
@ -536,7 +545,7 @@ class ImportXlsx extends ModeleImports
while ($i < $num)
{
$obj=$this->db->fetch_object($resql);
if ($obj) $this->cachefieldtable[$field.'@'.$table][]=$obj->aliasfield;
if ($obj) $this->cachefieldtable[$cachekey][]=$obj->aliasfield;
$i++;
}
}
@ -547,9 +556,11 @@ class ImportXlsx extends ModeleImports
}
// Now we check cache is not empty (should not) and key is into cache
if (! is_array($this->cachefieldtable[$field.'@'.$table]) || ! in_array($newval,$this->cachefieldtable[$field.'@'.$table]))
if (! is_array($this->cachefieldtable[$cachekey]) || ! in_array($newval,$this->cachefieldtable[$cachekey]))
{
$this->errors[$error]['lib']=$langs->transnoentitiesnoconv('ErrorFieldValueNotIn',$key,$newval,$field,$table);
$tableforerror = $table;
if(! empty($filter)) $tableforerror.= ':'.$filter;
$this->errors[$error]['lib']=$langs->transnoentitiesnoconv('ErrorFieldValueNotIn',$key,$newval,$field,$tableforerror);
$this->errors[$error]['type']='FOREIGNKEY';
$errorforthistable++;
$error++;

View File

@ -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';

View File

@ -422,8 +422,8 @@ class modCategorie extends DolibarrModules
$this->import_icon[$r]=$this->picto;
$this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon
$this->import_tables_array[$r]=array('cp'=>MAIN_DB_PREFIX.'categorie_product');
$this->import_fields_array[$r]=array('cp.fk_categorie'=>"Category*",'cp.fk_product'=>"Product*"
);
$this->import_fields_array[$r]=array('cp.fk_categorie'=>"Category*",'cp.fk_product'=>"Product*");
$this->import_regex_array[$r]=array('cp.fk_categorie'=>'rowid@'.MAIN_DB_PREFIX.'categorie:type=0');
$this->import_convertvalue_array[$r]=array(
'cp.fk_categorie'=>array('rule'=>'fetchidfromref','classfile'=>'/categories/class/categorie.class.php','class'=>'Categorie','method'=>'fetch','element'=>'category'),
@ -441,7 +441,10 @@ class modCategorie extends DolibarrModules
$this->import_icon[$r]=$this->picto;
$this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon
$this->import_tables_array[$r]=array('cs'=>MAIN_DB_PREFIX.'categorie_societe');
$this->import_fields_array[$r]=array('cs.fk_categorie'=>"Category*",'cs.fk_soc'=>"ThirdParty*"
$this->import_fields_array[$r]=array('cs.fk_categorie'=>"Category*",'cs.fk_soc'=>"ThirdParty*");
$this->import_regex_array[$r]=array(
'cs.fk_categorie'=>'rowid@'.MAIN_DB_PREFIX.'categorie:type=2',
'cs.fk_soc'=>'rowid@'.MAIN_DB_PREFIX.'societe:client>0'
);
$this->import_convertvalue_array[$r]=array(
@ -460,7 +463,10 @@ class modCategorie extends DolibarrModules
$this->import_icon[$r]=$this->picto;
$this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon
$this->import_tables_array[$r]=array('cs'=>MAIN_DB_PREFIX.'categorie_fournisseur');
$this->import_fields_array[$r]=array('cs.fk_categorie'=>"Category*",'cs.fk_soc'=>"Supplier*"
$this->import_fields_array[$r]=array('cs.fk_categorie'=>"Category*",'cs.fk_soc'=>"Supplier*");
$this->import_regex_array[$r]=array(
'cs.fk_categorie'=>'rowid@'.MAIN_DB_PREFIX.'categorie:type=1',
'cs.fk_soc'=>'rowid@'.MAIN_DB_PREFIX.'societe:fournisseur>0'
);
$this->import_convertvalue_array[$r]=array(

View File

@ -246,8 +246,8 @@ class modProjet extends DolibarrModules
$keyforselect='projet'; $keyforelement='project'; $keyforaliasextra='extra';
include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';
// Add fields for tasks
$this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('pt.rowid'=>'RefTask','pt.label'=>'LabelTask','pt.dateo'=>"TaskDateStart",'pt.datee'=>"TaskDateEnd",'pt.duration_effective'=>"DurationEffective",'pt.planned_workload'=>"PlannedWorkload",'pt.progress'=>"Progress",'pt.description'=>"TaskDescription"));
$this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('pt.rowid'=>'projecttask','pt.label'=>'projecttask','pt.dateo'=>"projecttask",'pt.datee'=>"projecttask",'pt.duration_effective'=>"projecttask",'pt.planned_workload'=>"projecttask",'pt.progress'=>"projecttask",'pt.description'=>"projecttask"));
$this->export_fields_array[$r]=array_merge($this->export_fields_array[$r], array('pt.rowid'=>'TaskId', 'pt.ref'=>'RefTask', 'pt.label'=>'LabelTask','pt.dateo'=>"TaskDateStart",'pt.datee'=>"TaskDateEnd",'pt.duration_effective'=>"DurationEffective",'pt.planned_workload'=>"PlannedWorkload",'pt.progress'=>"Progress",'pt.description'=>"TaskDescription"));
$this->export_entities_array[$r]=array_merge($this->export_entities_array[$r], array('pt.rowid'=>'projecttask', 'pt.ref'=>'projecttask', 'pt.label'=>'projecttask','pt.dateo'=>"projecttask",'pt.datee'=>"projecttask",'pt.duration_effective'=>"projecttask",'pt.planned_workload'=>"projecttask",'pt.progress'=>"projecttask",'pt.description'=>"projecttask"));
// Add extra fields for task
$keyforselect='projet_task'; $keyforelement='projecttask'; $keyforaliasextra='extra2';
include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php';

View File

@ -136,8 +136,8 @@ class modReceiptPrinter extends DolibarrModules
// Clean before activation
$this->remove($options);
$sql = array(
"CREATE TABLE IF NOT EXISTS llx_printer_receipt (rowid integer AUTO_INCREMENT PRIMARY KEY, name varchar(128), fk_type integer, fk_profile integer, parameter varchar(128), entity integer) ENGINE=innodb;",
"CREATE TABLE IF NOT EXISTS llx_printer_receipt_template (rowid integer AUTO_INCREMENT PRIMARY KEY, name varchar(128), template text, entity integer) ENGINE=innodb;",
"CREATE TABLE IF NOT EXISTS ".MAIN_DB_PREFIX."printer_receipt (rowid integer AUTO_INCREMENT PRIMARY KEY, name varchar(128), fk_type integer, fk_profile integer, parameter varchar(128), entity integer) ENGINE=innodb;",
"CREATE TABLE IF NOT EXISTS ".MAIN_DB_PREFIX."printer_receipt_template (rowid integer AUTO_INCREMENT PRIMARY KEY, name varchar(128), template text, entity integer) ENGINE=innodb;",
);
return $this->_init($sql,$options);
}

View File

@ -343,7 +343,7 @@ class modStock extends DolibarrModules
'ps.fk_product'=>"PREF123456",'ps.fk_entrepot'=>"ALM001",'ps.reel'=>"10"
);
$this->import_run_sql_after_array[$r]=array( // Because we may change data that are denormalized, we must update dernormalized data after.
'UPDATE llx_product p SET p.stock= (SELECT SUM(ps.reel) FROM llx_product_stock ps WHERE ps.fk_product = p.rowid);'
'UPDATE '.MAIN_DB_PREFIX.'product p SET p.stock= (SELECT SUM(ps.reel) FROM '.MAIN_DB_PREFIX.'product_stock ps WHERE ps.fk_product = p.rowid);'
);
}

View File

@ -273,7 +273,7 @@ class pdf_beluga extends ModelePDFProjects
'table'=>'commande',
'datefieldname'=>'date_commande',
'test'=>$conf->commande->enabled && $user->rights->commande->lire,
'lang'=>'order'),
'lang'=>'orders'),
'invoice'=>array(
'name'=>"CustomersInvoices",
'title'=>"ListInvoicesAssociatedProject",

View File

@ -27,6 +27,7 @@ if (! empty($extrafieldsobjectkey)) // $extrafieldsobject is the $object->table_
if (in_array($typ, array('int','double','real'))) $mode_search=1; // Search on a numeric
if (in_array($typ, array('sellist','link')) && $crit != '0' && $crit != '-1') $mode_search=2; // Search on a foreign key int
if (in_array($typ, array('chkbxlst','checkbox'))) $mode_search=4; // Search on a multiselect field with sql type = text
if (is_array($crit)) $crit = implode(' ', $crit); // natural_search() expects a string
$sql .= natural_search('ef.'.$tmpkey, $crit, $mode_search);
}

View File

@ -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)) ? '<img src="' . DOL_MAIN_URL_ROOT . '/public/emailing/mailing-read.php?tag=' . $object->thirdparty->tag . '&securitykey=' . urlencode($conf->global->MAILING_EMAIL_UNSUBSCRIBE_KEY) . '" width="1" height="1" style="width:1px;height:1px" border="0"/>' : '';
$substitutionarray['__PERSONALIZED__'] = ''; // deprecated

View File

@ -105,8 +105,8 @@ class InterfaceWorkflowManager extends DolibarrTriggers
if ($element->statut == Propal::STATUS_SIGNED || $element->statut == Propal::STATUS_BILLED) $totalonlinkedelements += $element->total_ht;
}
dol_syslog( "Amount of linked proposals = ".$totalonlinkedelements.", of order = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) );
if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) )
{
if ($this->shouldClassify($conf, $totalonlinkedelements, $object->total_ht))
{
foreach($object->linkedObjects['propal'] as $element)
{
$ret=$element->classifyBilled($user);
@ -121,7 +121,8 @@ class InterfaceWorkflowManager extends DolibarrTriggers
if ($action == 'BILL_VALIDATE')
{
dol_syslog( "Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id );
$ret = 0;
// First classify billed the order to allow the proposal classify process
if (! empty($conf->commande->enabled) && ! empty($conf->workflow->enabled) && ! empty($conf->global->WORKFLOW_INVOICE_AMOUNT_CLASSIFY_BILLED_ORDER))
{
@ -134,7 +135,7 @@ class InterfaceWorkflowManager extends DolibarrTriggers
if ($element->statut == Commande::STATUS_VALIDATED || $element->statut == Commande::STATUS_SHIPMENTONPROCESS || $element->statut == Commande::STATUS_CLOSED) $totalonlinkedelements += $element->total_ht;
}
dol_syslog( "Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) );
if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) )
if ($this->shouldClassify($conf, $totalonlinkedelements, $object->total_ht))
{
foreach($object->linkedObjects['commande'] as $element)
{
@ -142,7 +143,6 @@ class InterfaceWorkflowManager extends DolibarrTriggers
}
}
}
return $ret;
}
// Second classify billed the proposal.
@ -157,16 +157,17 @@ class InterfaceWorkflowManager extends DolibarrTriggers
if ($element->statut == Propal::STATUS_SIGNED || $element->statut == Propal::STATUS_BILLED) $totalonlinkedelements += $element->total_ht;
}
dol_syslog( "Amount of linked proposals = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) );
if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) )
{
if ($this->shouldClassify($conf, $totalonlinkedelements, $object->total_ht))
{
foreach($object->linkedObjects['propal'] as $element)
{
$ret=$element->classifyBilled($user);
}
}
}
return $ret;
}
return $ret;
}
// classify billed order & billed propososal
@ -186,8 +187,8 @@ class InterfaceWorkflowManager extends DolibarrTriggers
if ($element->statut == CommandeFournisseur::STATUS_ACCEPTED || $element->statut == CommandeFournisseur::STATUS_ORDERSENT || $element->statut == CommandeFournisseur::STATUS_RECEIVED_PARTIALLY || $element->statut == CommandeFournisseur::STATUS_RECEIVED_COMPLETELY) $totalonlinkedelements += $element->total_ht;
}
dol_syslog( "Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) );
if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) )
{
if ($this->shouldClassify($conf, $totalonlinkedelements, $object->total_ht))
{
foreach($object->linkedObjects['order_supplier'] as $element)
{
$ret=$element->classifyBilled($user);
@ -209,8 +210,8 @@ class InterfaceWorkflowManager extends DolibarrTriggers
if ($element->statut == SupplierProposal::STATUS_SIGNED || $element->statut == SupplierProposal::STATUS_BILLED) $totalonlinkedelements += $element->total_ht;
}
dol_syslog( "Amount of linked supplier proposals = ".$totalonlinkedelements.", of supplier invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) );
if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) )
{
if ($this->shouldClassify($conf, $totalonlinkedelements, $object->total_ht))
{
foreach($object->linkedObjects['supplier_proposal'] as $element)
{
$ret=$element->classifyBilled($user);
@ -237,7 +238,7 @@ class InterfaceWorkflowManager extends DolibarrTriggers
if ($element->statut == Commande::STATUS_VALIDATED || $element->statut == Commande::STATUS_SHIPMENTONPROCESS || $element->statut == Commande::STATUS_CLOSED) $totalonlinkedelements += $element->total_ht;
}
dol_syslog( "Amount of linked orders = ".$totalonlinkedelements.", of invoice = ".$object->total_ht.", egality is ".($totalonlinkedelements == $object->total_ht) );
if ( ($totalonlinkedelements == $object->total_ht) || (! empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) )
if ($this->shouldClassify($conf, $totalonlinkedelements, $object->total_ht))
{
foreach($object->linkedObjects['commande'] as $element)
{
@ -310,4 +311,23 @@ class InterfaceWorkflowManager extends DolibarrTriggers
return 0;
}
/**
* @param Object $conf Dolibarr settings object
* @param float $totalonlinkedelements Sum of total amounts (excl VAT) of
* invoices linked to $object
* @param float $object_total_ht The total amount (excl VAT) of the object
* (an order, a proposal, a bill, etc.)
* @return bool True if the amounts are equal (rounded on total amount)
* True if the module is configured to skip the amount equality check
* False otherwise.
*/
private function shouldClassify($conf, $totalonlinkedelements, $object_total_ht)
{
// if the configuration allows unmatching amounts, allow classification anyway
if (!empty($conf->global->WORKFLOW_CLASSIFY_IF_AMOUNTS_ARE_DIFFERENTS)) {
return true;
}
// if the amount are same, allow classification, else deny
return (price2num($totalonlinkedelements, 'MT') == price2num($object_total_ht, 'MT'));
}
}

View File

@ -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');
@ -551,6 +552,7 @@ if (empty($reshook))
header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id);
exit();
}
setEventMessages($object->error, $object->errors, 'errors');
}
elseif ($action == 'classifyclosed')
@ -561,6 +563,7 @@ if (empty($reshook))
header('Location: ' . $_SERVER["PHP_SELF"] . '?id=' . $object->id);
exit();
}
setEventMessages($object->error, $object->errors, 'errors');
}
/*
@ -1648,7 +1651,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

View File

@ -1073,13 +1073,15 @@ class Expedition extends CommonObject
}
}
/**
* Delete shipment.
* Warning, do not delete a shipment if a delivery is linked to (with table llx_element_element)
*
* @return int >0 if OK, 0 if deletion done but failed to delete files, <0 if KO
*/
function delete()
/**
* Delete shipment.
* Warning, do not delete a shipment if a delivery is linked to (with table llx_element_element)
*
* @param bool $also_update_stock true if the stock should be increased back (false by default)
* @return int >0 if OK, 0 if deletion done but failed to delete files, <0 if KO
* @throws Exception
*/
function delete($also_update_stock = false)
{
global $conf, $langs, $user;
@ -1111,7 +1113,9 @@ class Expedition extends CommonObject
}
// Stock control
if (! $error && $conf->stock->enabled && $conf->global->STOCK_CALCULATE_ON_SHIPMENT && $this->statut > self::STATUS_DRAFT)
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 == self::STATUS_CLOSED && $also_update_stock)))
{
require_once(DOL_DOCUMENT_ROOT."/product/stock/class/mouvementstock.class.php");

View File

@ -894,7 +894,7 @@ if ($id > 0 || ! empty($ref))
print $langs->trans("WarehouseSource");
//print '</td>';
//print '<td>';
print $formproduct->selectWarehouses(! empty($object->warehouse_id)?$object->warehouse_id:-1, 'entrepot_id', '', 1, 0, 0, '', 0, 0, array(), 'minwidth200');
print $formproduct->selectWarehouses(! empty($object->warehouse_id)?$object->warehouse_id:'ifone', 'entrepot_id', '', 1, 0, 0, '', 0, 0, array(), 'minwidth200');
if (count($formproduct->cache_warehouses) <= 0)
{
print ' &nbsp; '.$langs->trans("WarehouseSourceNotDefined").' <a href="'.DOL_URL_ROOT.'/product/stock/card.php?action=create">'.$langs->trans("AddOne").'</a>';

View File

@ -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();
}
}
/*
@ -955,6 +967,34 @@ if (empty($reshook))
}
}
if ($action == 'set_unpaid' && $id > 0 && $user->rights->expensereport->to_paid)
{
$object = new ExpenseReport($db);
$object->fetch($id);
$result = $object->set_unpaid($user);
if ($result > 0)
{
// Define output language
if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE))
{
$outputlangs = $langs;
$newlang = '';
if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id', 'aZ09')) $newlang = GETPOST('lang_id', 'aZ09');
if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang;
if (! empty($newlang)) {
$outputlangs = new Translate("", $conf);
$outputlangs->setDefaultLang($newlang);
}
$model=$object->modelpdf;
$ret = $object->fetch($id); // Reload to get new records
$object->generateDocument($model, $outputlangs, $hidedetails, $hidedesc, $hideref);
}
}
}
if ($action == 'set_paid' && $id > 0 && $user->rights->expensereport->to_paid)
{
$object = new ExpenseReport($db);
@ -1892,7 +1932,7 @@ else
if ($resql)
{
$num = $db->num_rows($resql);
$i = 0; $total = 0;
$i = 0; $totalpaid = 0;
while ($i < $num)
{
$objp = $db->fetch_object($resql);
@ -2337,8 +2377,8 @@ if ($action != 'create' && $action != 'edit')
}
// If status is Appoved
// --------------------
// If status is Approved
// ---------------------
if ($user->rights->expensereport->approve && $object->fk_statut == 5)
{
@ -2382,9 +2422,15 @@ if ($action != 'create' && $action != 'edit')
print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=cancel&id='.$object->id.'">'.$langs->trans('Cancel').'</a></div>';
}
if ($user->rights->expensereport->to_paid && $object->paid && $object->fk_statut == ExpenseReport::STATUS_CLOSED)
{
// Set unpaid
print '<div class="inline-block divButAction"><a class="butAction" href="'.$_SERVER["PHP_SELF"].'?action=set_unpaid&id='.$object->id.'">'.$langs->trans('ClassifyUnPaid').'</a></div>';
}
// Clone
if ($user->rights->expensereport->creer) {
print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&amp;action=clone">' . $langs->trans("ToClone") . '</a></div>';
print '<div class="inline-block divButAction"><a class="butAction" href="' . $_SERVER['PHP_SELF'] . '?id=' . $object->id . '&action=clone">' . $langs->trans("ToClone") . '</a></div>';
}
/* If draft, validated, cancel, and user can create, he can always delete its card before it is approved */

View File

@ -106,6 +106,11 @@ class ExpenseReport extends CommonObject
*/
const STATUS_VALIDATED = 2;
/**
* Classified canceled
*/
const STATUS_CANCELED = 4;
/**
* Classified approved
*/
@ -1205,10 +1210,10 @@ class ExpenseReport extends CommonObject
$this->date_debut = $this->db->jdate($objp->date_debut);
if ($this->fk_statut != 2)
if ($this->fk_statut != self::STATUS_VALIDATED)
{
$sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
$sql.= " SET fk_statut = 2";
$sql.= " SET fk_statut = ".self::STATUS_VALIDATED;
$sql.= ' WHERE rowid = '.$this->id;
dol_syslog(get_class($this)."::set_save_from_refuse sql=".$sql, LOG_DEBUG);
@ -1243,12 +1248,12 @@ class ExpenseReport extends CommonObject
// date approval
$this->date_approve = $now;
if ($this->fk_statut != 5)
if ($this->fk_statut != self::STATUS_APPROVED)
{
$this->db->begin();
$sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
$sql.= " SET ref = '".$this->db->escape($this->ref)."', fk_statut = 5, fk_user_approve = ".$fuser->id.",";
$sql.= " SET ref = '".$this->db->escape($this->ref)."', fk_statut = ".self::STATUS_APPROVED.", fk_user_approve = ".$fuser->id.",";
$sql.= " date_approve='".$this->db->idate($this->date_approve)."'";
$sql.= ' WHERE rowid = '.$this->id;
if ($this->db->query($sql))
@ -1304,10 +1309,10 @@ class ExpenseReport extends CommonObject
$error = 0;
// date de refus
if ($this->fk_statut != 99)
if ($this->fk_statut != self::STATUS_REFUSED)
{
$sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
$sql.= " SET ref = '".$this->db->escape($this->ref)."', fk_statut = 99, fk_user_refuse = ".$fuser->id.",";
$sql.= " SET ref = '".$this->db->escape($this->ref)."', fk_statut = ".self::STATUS_REFUSED.", fk_user_refuse = ".$fuser->id.",";
$sql.= " date_refuse='".$this->db->idate($now)."',";
$sql.= " detail_refuse='".$this->db->escape($details)."',";
$sql.= " fk_user_approve = NULL";
@ -1366,12 +1371,12 @@ class ExpenseReport extends CommonObject
{
$error = 0;
if ($this->fk_c_deplacement_statuts != 5)
if ($this->paid)
{
$this->db->begin();
$sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
$sql.= " SET fk_statut = 5";
$sql.= " SET paid = 0, fk_statut = ".self::STATUS_APPROVED;
$sql.= ' WHERE rowid = '.$this->id;
dol_syslog(get_class($this)."::set_unpaid sql=".$sql, LOG_DEBUG);
@ -1426,12 +1431,12 @@ class ExpenseReport extends CommonObject
{
$error = 0;
$this->date_cancel = $this->db->idate(gmmktime());
if ($this->fk_statut != 4)
if ($this->fk_statut != self::STATUS_CANCELED)
{
$this->db->begin();
$sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element;
$sql.= " SET fk_statut = 4, fk_user_cancel = ".$fuser->id;
$sql.= " SET fk_statut = ".self::STATUS_CANCELED.", fk_user_cancel = ".$fuser->id;
$sql.= ", date_cancel='".$this->db->idate($this->date_cancel)."'";
$sql.= " ,detail_cancel='".$this->db->escape($detail)."'";
$sql.= ' WHERE rowid = '.$this->id;

View File

@ -4,6 +4,7 @@
* Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
* Copyright (C) 2005-2009 Regis Houssin <regis.houssin@capnetworks.com>
* Copyright (C) 2015 Alexandre Spangaro <aspangaro.dolibarr@gmail.com>
* Copyright (C) 2019 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2018 Ferran Marcet <fmarcet@2byte.es>
*
* This program is free software; you can redistribute it and/or modify
@ -45,10 +46,25 @@ $confirm=GETPOST('confirm','alpha');
$toselect = GETPOST('toselect', 'array');
$contextpage=GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'expensereportlist';
$childids = $user->getAllChildIds(1);
// Security check
$socid = GETPOST('socid','int');
if ($user->societe_id) $socid=$user->societe_id;
$result = restrictedArea($user, 'expensereport','','');
$id = GETPOST('id', 'int');
// If we are on the view of a specific user
if ($id > 0)
{
$canread=0;
if ($id == $user->id) $canread=1;
if (! empty($user->rights->expensereport->readall)) $canread=1;
if (! empty($user->rights->expensereport->lire) && in_array($id, $childids)) $canread=1;
if (! $canread)
{
accessforbidden();
}
}
$diroutputmassaction=$conf->expensereport->dir_output . '/temp/massgeneration/'.$user->id;
@ -65,10 +81,9 @@ $pagenext = $page + 1;
if (!$sortorder) $sortorder="DESC";
if (!$sortfield) $sortfield="d.date_debut";
$id = GETPOST('id', 'int');
$sall = trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alphanohtml'):GETPOST('sall', 'alphanohtml'));
$search_ref = GETPOST('search_ref');
$search_ref = GETPOST('search_ref', 'alpha');
$search_user = GETPOST('search_user','int');
$search_amount_ht = GETPOST('search_amount_ht','alpha');
$search_amount_vat = GETPOST('search_amount_vat','alpha');
@ -257,7 +272,7 @@ $sql = "SELECT d.rowid, d.ref, d.fk_user_author, d.total_ht, d.total_tva, d.tota
$sql.= " d.date_debut, d.date_fin, d.date_create, d.tms as date_modif, d.date_valid, d.date_approve, d.note_private, d.note_public,";
$sql.= " u.rowid as id_user, u.firstname, u.lastname, u.login, u.email, u.statut, u.photo";
// Add fields from extrafields
foreach ($extrafields->attribute_label as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key.' as options_'.$key : '');
foreach ($extrafields->attributes['expensereport']['type'] as $key => $val) $sql.=($extrafields->attribute_type[$key] != 'separate' ? ",ef.".$key.' as options_'.$key : '');
// Add fields from hooks
$parameters=array();
$reshook=$hookmanager->executeHooks('printFieldListSelect',$parameters); // Note that $action and $object may have been modified by hook

View File

@ -5,7 +5,7 @@
* Copyright (C) 2011-2012 Juanjo Menent <jmenent@2byte.es>
* Copyright (C) 2013 Cédric Salvador <csalvador@gpcsolutions.fr>
* Copyright (C) 2015 Jean-François Ferry <jfefe@aternatik.fr>
* Copyright (C) 2018 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2018-2019 Ferran Marcet <fmarcet@2byte.es>
*
* 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 '<input type="text" class="flat" name="search_company" value="'.$search_company.'" size="10">';
print '</td>';
}
if (! empty($arrayfields['f.fk_projet']['checked']))
{
print '<td class="liste_titre">';
print '<input type="text" class="flat" name="search_project" value="'.$search_project.'" size="10">';
print '</td>';
}
if (! empty($arrayfields['f.fk_contrat']['checked']))
{
print '<td class="liste_titre">';
print '<input type="text" class="flat" name="search_contract" value="'.$search_contract.'" size="10">';
print '</td>';
}
if (! empty($arrayfields['f.description']['checked']))
{
print '<td class="liste_titre">';
@ -399,21 +447,23 @@ if ($resql)
print "</tr>\n";
print '<tr class="liste_titre">';
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 "</tr>\n";
@ -477,6 +527,29 @@ if ($resql)
print '</td>';
if (! $i) $totalarray['nbfield']++;
}
if (! empty($arrayfields['f.fk_projet']['checked']))
{
print '<td>';
if ($obj->projectid > 0) {
$projectstatic->ref = $obj->projectref;
$projectstatic->id = $obj->projectid;
$projectstatic->title = $obj->projecttitle;
print $projectstatic->getNomUrl(1, '', 44);
}
print '</td>';
if (! $i) $totalarray['nbfield']++;
}
if (! empty($arrayfields['f.fk_contrat']['checked']))
{
print '<td>';
if ($obj->contractid > 0) {
$contratstatic->ref = $obj->contractref;
$contratstatic->id = $obj->contractid;
print $contratstatic->getNomUrl(1, '', 44);
}
print '</td>';
if (! $i) $totalarray['nbfield']++;
}
if (! empty($arrayfields['f.description']['checked']))
{
print '<td>'.dol_trunc(dolGetFirstLineOfText($obj->description),48).'</td>';

View File

@ -31,7 +31,7 @@
*/
if (! defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE','Dolibarr');
if (! defined('DOL_VERSION')) define('DOL_VERSION','8.0.5'); // 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));

View File

@ -1485,7 +1485,7 @@ class CommandeFournisseur extends CommonOrder
$desc=trim($desc);
// Check parameters
if ($qty < 1 && ! $fk_product)
if ($qty < 0 && ! $fk_product)
{
$this->error=$langs->trans("ErrorFieldRequired",$langs->trans("Product"));
return -1;
@ -3363,6 +3363,8 @@ class CommandeFournisseurLigne extends CommonOrderLine
$error=0;
$this->db->begin();
// Mise a jour ligne en base
$sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET";
$sql.= " description='".$this->db->escape($this->desc)."'";

View File

@ -9,7 +9,7 @@
* Copyright (C) 2013 Florian Henry <florian.henry@open-concept.pro>
* Copyright (C) 2014-2016 Marcos García <marcosgdf@gmail.com>
* Copyright (C) 2015 Bahfir Abbes <bafbes@gmail.com>
* Copyright (C) 2015 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2015-2019 Ferran Marcet <fmarcet@2byte.es>
* Copyright (C) 2016 Alexandre Spangaro <aspangaro@zendsi.com>
* Copyright (C) 2018 Nicolas ZABOURI <info@inovea-conseil.com>
*
@ -555,7 +555,7 @@ class FactureFournisseur extends CommonInvoice
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as p ON t.fk_mode_reglement = p.id";
$sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON t.fk_incoterms = i.rowid';
if ($id) $sql.= " WHERE t.rowid=".$id;
if ($ref) $sql.= " WHERE t.ref='".$this->db->escape($ref)."'";
if ($ref) $sql.= " WHERE t.ref='".$this->db->escape($ref)."' AND t.entity IN (".getEntity('supplier_invoice').")";
dol_syslog(get_class($this)."::fetch", LOG_DEBUG);
$resql=$this->db->query($sql);
@ -1318,7 +1318,8 @@ class FactureFournisseur extends CommonInvoice
// We increase stock for product
$up_ht_disc=$this->lines[$i]->pu_ht;
if (! empty($this->lines[$i]->remise_percent) && empty($conf->global->STOCK_EXCLUDE_DISCOUNT_FOR_PMP)) $up_ht_disc=price2num($up_ht_disc * (100 - $this->lines[$i]->remise_percent) / 100, 'MU');
$result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $up_ht_disc, $langs->trans("InvoiceValidatedInDolibarr",$num));
if ($this->type == FactureFournisseur::TYPE_CREDIT_NOTE) $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $up_ht_disc, $langs->trans("InvoiceValidatedInDolibarr",$num));
else $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $up_ht_disc, $langs->trans("InvoiceValidatedInDolibarr",$num));
if ($result < 0) { $error++; }
unset($this->line);
}
@ -1441,7 +1442,8 @@ class FactureFournisseur extends CommonInvoice
$mouvP = new MouvementStock($this->db);
$mouvP->origin = &$this;
// We increase stock for product
$result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceBackToDraftInDolibarr", $this->ref));
if ($this->type == FactureFournisseur::TYPE_CREDIT_NOTE) $result=$mouvP->reception($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceBackToDraftInDolibarr", $this->ref));
else $result=$mouvP->livraison($user, $this->lines[$i]->fk_product, $idwarehouse, $this->lines[$i]->qty, $this->lines[$i]->subprice, $langs->trans("InvoiceBackToDraftInDolibarr", $this->ref));
}
}
}
@ -2579,6 +2581,27 @@ class FactureFournisseur extends CommonInvoice
return ($this->statut == self::STATUS_VALIDATED) && ($this->date_echeance < ($now - $conf->facture->fournisseur->warning_delay));
}
/**
* Is credit note used
*
* @return bool
*/
public function isCreditNoteUsed()
{
global $db;
$isUsed = false;
$sql = "SELECT fk_invoice_supplier FROM ".MAIN_DB_PREFIX."societe_remise_except WHERE fk_invoice_supplier_source=".$this->id;
$resql = $db->query($sql);
if(!empty($resql)){
$obj = $db->fetch_object($resql);
if(!empty($obj->fk_invoice_supplier))$isUsed=true;
}
return $isUsed;
}
}

View File

@ -2391,14 +2391,11 @@ elseif (! empty($object->id))
}
// Create bill
if (! empty($conf->facture->enabled))
if (! empty($conf->fournisseur->enabled) && ($object->statut >= 2 && $object->statut != 7 && $object->billed != 1)) // statut 2 means approved, 7 means canceled
{
if (! empty($conf->fournisseur->enabled) && ($object->statut >= 2 && $object->statut != 7 && $object->billed != 1)) // statut 2 means approved, 7 means canceled
if ($user->rights->fournisseur->facture->creer)
{
if ($user->rights->fournisseur->facture->creer)
{
print '<a class="butAction" href="'.DOL_URL_ROOT.'/fourn/facture/card.php?action=create&amp;origin='.$object->element.'&amp;originid='.$object->id.'&amp;socid='.$object->socid.'">'.$langs->trans("CreateBill").'</a>';
}
print '<a class="butAction" href="'.DOL_URL_ROOT.'/fourn/facture/card.php?action=create&amp;origin='.$object->element.'&amp;originid='.$object->id.'&amp;socid='.$object->socid.'">'.$langs->trans("CreateBill").'</a>';
}
}

View File

@ -245,7 +245,7 @@ if ($action == 'dispatch' && $user->rights->fournisseur->commande->receptionner)
// We ask to move a qty
if (GETPOST($qty) != 0) {
if (! (GETPOST($ent, 'int') > 0)) {
dol_syslog('No dispatch for line ' . $key . ' as no warehouse choosed');
dol_syslog('No dispatch for line ' . $key . ' as no warehouse was chosen.');
$text = $langs->transnoentities('Warehouse') . ', ' . $langs->transnoentities('Line') . ' ' . ($numline);
setEventMessages($langs->trans('ErrorFieldRequired', $text), null, 'errors');
$error ++;
@ -282,7 +282,7 @@ if ($action == 'dispatch' && $user->rights->fournisseur->commande->receptionner)
// We ask to move a qty
if (GETPOST($qty) > 0) {
if (! (GETPOST($ent, 'int') > 0)) {
dol_syslog('No dispatch for line ' . $key . ' as no warehouse choosed');
dol_syslog('No dispatch for line ' . $key . ' as no warehouse was chosen.');
$text = $langs->transnoentities('Warehouse') . ', ' . $langs->transnoentities('Line') . ' ' . ($numline) . '-' . ($reg[1] + 1);
setEventMessages($langs->trans('ErrorFieldRequired', $text), null, 'errors');
$error ++;

View File

@ -216,7 +216,7 @@ if (($action == 'create' || $action == 'add') && ! $error) {
$fk_parent_line = 0;
}
// FIXME Missing $lines[$i]->ref_supplier and $lines[$i]->label into addline and updateline methods. They are filled when coming from order for example.
$result = $object->addline($desc, $lines[$i]->subprice, $lines[$i]->tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->qty, $lines[$i]->fk_product, $lines[$i]->remise_percent, $date_start, $date_end, 0, $lines[$i]->info_bits, 'HT', $product_type, -1, false, 0, $lines[$i]->fk_unit);
$result = $object->addline($desc, $lines[$i]->subprice, $lines[$i]->tva_tx, $lines[$i]->localtax1_tx, $lines[$i]->localtax2_tx, $lines[$i]->qty, $lines[$i]->fk_product, $lines[$i]->remise_percent, $date_start, $date_end, 0, $lines[$i]->info_bits, 'HT', $product_type, -1, false, 0, $lines[$i]->fk_unit, $line[$i]->id);
if ($result > 0) {
$lineid = $result;

View File

@ -906,7 +906,7 @@ if (empty($reshook))
// FIXME Missing special_code into addline and updateline methods
$object->special_code = $lines[$i]->special_code;
// FIXME Missing $lines[$i]->ref_supplier and $lines[$i]->label into addline and updateline methods. They are filled when coming from order for example.
$result = $object->addline(
$desc,
@ -2642,11 +2642,14 @@ else
else $calculationrule=(empty($conf->global->MAIN_ROUNDOFTOTAL_NOT_TOTALOFROUND)?'totalofround':'roundoftotal');
if ($calculationrule == 'totalofround') $calculationrulenum=1;
else $calculationrulenum=2;
$s=$langs->trans("ReCalculate").' ';
$s.='<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=calculate&calculationrule=totalofround">'.$langs->trans("Mode1").'</a>';
$s.=' / ';
$s.='<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=calculate&calculationrule=roundoftotal">'.$langs->trans("Mode2").'</a>';
print $form->textwithtooltip($s, $langs->trans("CalculationRuleDesc",$calculationrulenum).'<br>'.$langs->trans("CalculationRuleDescSupplier"), 2, 1, img_picto('','help'));
if ($object->getVentilExportCompta() == 0) {
$s=$langs->trans("ReCalculate").' ';
$s.='<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=calculate&calculationrule=totalofround">'.$langs->trans("Mode1").'</a>';
$s.=' / ';
$s.='<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=calculate&calculationrule=roundoftotal">'.$langs->trans("Mode2").'</a>';
print $form->textwithtooltip($s, $langs->trans("CalculationRuleDesc",$calculationrulenum).'<br>'.$langs->trans("CalculationRuleDescSupplier"), 2, 1, img_picto('','help'));
}
print '</div></td></tr>';
// Amount Local Taxes

View File

@ -496,7 +496,7 @@ if ($resql)
print_barre_liste($langs->trans("BillsSuppliers").($socid?' '.$soc->name:''), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_accountancy', 0, $newcardbutton, '', $limit);
$topicmail="SendBillRef";
$modelmail="supplier_invoice_send";
$modelmail="invoice_supplier_send";
$objecttmp=new FactureFournisseur($db);
$trackid='sinv'.$object->id;
include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';
@ -833,6 +833,7 @@ if ($resql)
$facturestatic->date_echeance = $db->jdate($obj->datelimite);
$facturestatic->statut = $obj->fk_statut;
$thirdparty->id=$obj->socid;
$thirdparty->name=$obj->name;
$thirdparty->client=$obj->client;
@ -850,6 +851,14 @@ if ($resql)
$totalpay = $paiement + $totalcreditnotes + $totaldeposits;
$remaintopay = $obj->total_ttc - $totalpay;
//If invoice has been converted and the conversion has been used, we dont have remain to pay on invoice
if($facturestatic->type == FactureFournisseur::TYPE_CREDIT_NOTE) {
if($facturestatic->isCreditNoteUsed()){
$remaintopay=-$facturestatic->getSumFromThisCreditNotesNotUsed();
}
}
print '<tr class="oddeven">';
if (! empty($arrayfields['f.ref']['checked']))
{

View File

@ -753,7 +753,7 @@ if (empty($action))
$sortfield = GETPOST("sortfield",'alpha');
$sortorder = GETPOST("sortorder",'alpha');
$page=GETPOST("page",'int');
if ($page == -1 || $page == null) { $page = 0 ; }
if (empty($page) || $page == -1) { $page = 0 ; }
$offset = $limit * $page ;
$pageprev = $page - 1;
$pagenext = $page + 1;

View File

@ -62,15 +62,35 @@ 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
*/
if (GETPOST('cancel', 'alpha'))
{
$action = '';
}
// If create a request
if ($action == 'create')
{
$object = new Holiday($db);
// If no right to create a request
if (! $cancreate)
@ -82,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'));
@ -189,7 +211,34 @@ if ($action == 'create')
}
}
if ($action == 'update')
if ($action == 'update' && GETPOSTISSET('savevalidator') && ! empty($user->rights->holiday->approve))
{
$object->fetch($id);
$object->oldcopy = dol_clone($object);
$object->fk_validator = GETPOST('valideur', 'int');
if ($object->fk_validator != $object->oldcopy->fk_validator)
{
$verif = $object->update($user);
if ($verif <= 0)
{
setEventMessages($object->error, $object->errors, 'warnings');
$action='editvalidator';
}
else
{
header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id);
exit;
}
}
$action = '';
}
if ($action == 'update' && ! GETPOSTISSET('savevalidator'))
{
$date_debut = dol_mktime(0, 0, 0, GETPOST('date_debut_month'), GETPOST('date_debut_day'), GETPOST('date_debut_year'));
$date_fin = dol_mktime(0, 0, 0, GETPOST('date_fin_month'), GETPOST('date_fin_day'), GETPOST('date_fin_year'));
@ -209,7 +258,6 @@ if ($action == 'update')
exit;
}
$object = new Holiday($db);
$object->fetch($id);
// If under validation
@ -293,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
@ -327,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
@ -430,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
@ -525,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
@ -610,7 +654,6 @@ if ($action == 'confirm_draft' && GETPOST('confirm') == 'yes')
{
$error = 0;
$object = new Holiday($db);
$object->fetch($id);
$oldstatus = $object->statut;
@ -641,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
@ -1047,9 +1089,9 @@ else
{
$head=holiday_prepare_head($object);
if ($action == 'edit' && $object->statut == 1)
if (($action == 'edit' && $object->statut == 1) || ($action == 'editvalidator'))
{
$edit = true;
if ($action == 'edit' && $object->statut == 1) $edit = true;
print '<form method="post" action="'.$_SERVER['PHP_SELF'].'?id='.$object->id.'">'."\n";
print '<input type="hidden" name="action" value="update"/>'."\n";
print '<input type="hidden" name="id" value="'.$object->id.'" />'."\n";
@ -1089,7 +1131,7 @@ else
$starthalfday=($object->halfday == -1 || $object->halfday == 2)?'afternoon':'morning';
$endhalfday=($object->halfday == 1 || $object->halfday == 2)?'morning':'afternoon';
if(!$edit)
if (!$edit)
{
print '<tr>';
print '<td class="nowrap">'.$langs->trans('DateDebCP').' ('.$langs->trans("FirstDayOfHoliday").')</td>';
@ -1188,25 +1230,40 @@ else
}
// Validator
if (!$edit) {
if (!$edit && $action != 'editvalidator') {
print '<tr>';
print '<td class="titlefield">';
if ($object->statut == 3 || $object->statut == 4) print $langs->trans('ApprovedBy');
else print $langs->trans('ReviewedByCP');
print '</td>';
print '<td>'.$valideur->getNomUrl(-1).'</td>';
print '<td>'.$valideur->getNomUrl(-1);
$include_users = $object->fetch_users_approver_holiday();
if (in_array($user->id, $include_users) && $object->statut == Holiday::STATUS_VALIDATED)
{
print '<a href="'.$_SERVER["PHP_SELF"].'?id='.$object->id.'&action=editvalidator">'.img_edit($langs->trans("Edit")).'</a>';
}
print '</td>';
print '</tr>';
} else {
print '<tr>';
print '<td class="titlefield">'.$langs->trans('ReviewedByCP').'</td>';
print '<td>';
$include_users = $object->fetch_users_approver_holiday();
if (! in_array($object->fk_validator, $include_users)) // Add the current validator to the list to not lose it when editing.
{
$include_users[]=$object->fk_validator;
}
if (empty($include_users)) print img_warning().' '.$langs->trans("NobodyHasPermissionToValidateHolidays");
else
{
$s=$form->select_dolusers($object->fk_validator, "valideur", 1, ($user->admin ? '' : array($user->id)), 0, $include_users);
$s=$form->select_dolusers($object->fk_validator, "valideur", (($action == 'editvalidator') ? 0 : 1), ($user->admin ? '' : array($user->id)), 0, $include_users);
print $form->textwithpicto($s, $langs->trans("AnyOtherInThisListCanValidate"));
}
if ($action == 'editvalidator')
{
print '<input type="submit" class="button" name="savevalidator" value="'.$langs->trans("Save").'">';
print '<input type="submit" class="button" name="cancel" value="'.$langs->trans("Cancel").'">';
}
print '</td>';
print '</tr>';
}
@ -1285,20 +1342,21 @@ else
print $form->formconfirm($_SERVER["PHP_SELF"]."?id=".$object->id,$langs->trans("TitleSetToDraft"),$langs->trans("ConfirmSetToDraft"),"confirm_draft", '', 1, 1);
}
if ($action == 'edit' && $object->statut == 1)
if (($action == 'edit' && $object->statut == 1) || ($action == 'editvalidator'))
{
print '<div align="center">';
if ($cancreate && $object->statut == 1)
if ($action == 'edit' && $object->statut == 1)
{
print '<input type="submit" value="'.$langs->trans("Save").'" class="button">';
print '<div align="center">';
if ($cancreate && $object->statut == 1)
{
print '<input type="submit" value="'.$langs->trans("Save").'" class="button">';
}
print '</div>';
}
print '</div>';
print '</form>';
}
if (! $edit)
{
print '<div class="tabsAction">';

View File

@ -1132,45 +1132,30 @@ class Holiday extends CommonObject
$result = $this->db->query($sql);
$typeleaves=$this->getTypes(1,1);
foreach($typeleaves as $key => $val)
{
// On ajoute x jours à chaque utilisateurs
$nb_holiday = $val['newByMonth'];
if (empty($nb_holiday)) $nb_holiday=0;
if ($nb_holiday > 0)
// Update each user counter
foreach ($users as $userCounter) {
$nbDaysToAdd = $typeleaves[$userCounter['type']]['newByMonth'];
if(empty($nbDaysToAdd)) continue;
dol_syslog("We update leave type id ".$userCounter['type']." for user id ".$userCounter['rowid'], LOG_DEBUG);
$nowHoliday = $userCounter['nb_holiday'];
$newSolde = $nowHoliday + $nbDaysToAdd;
// We add a log for each user
$this->addLogCP($user->id, $userCounter['rowid'], $langs->trans('HolidaysMonthlyUpdate'), $newSolde, $userCounter['type']);
$result = $this->updateSoldeCP($userCounter['rowid'], $newSolde, $userCounter['type'], $langs->trans('HolidaysMonthlyUpdate'));
if ($result < 0)
{
dol_syslog("We update leavefor everybody for type ".$key, LOG_DEBUG);
$i = 0;
while ($i < $nbUser)
{
$now_holiday = $this->getCPforUser($users[$i]['rowid'], $val['rowid']);
$new_solde = $now_holiday + $nb_holiday;
// We add a log for each user
$this->addLogCP($user->id, $users[$i]['rowid'], $langs->trans('HolidaysMonthlyUpdate'), $new_solde, $val['rowid']);
$i++;
}
// Now we update counter for all users at once
$sql2 = "UPDATE ".MAIN_DB_PREFIX."holiday_users SET";
$sql2.= " nb_holiday = nb_holiday + ".$nb_holiday;
$sql2.= " WHERE fk_type = ".$val['rowid'];
$result= $this->db->query($sql2);
if (! $result)
{
dol_print_error($this->db);
break;
}
$error++;
break;
}
else dol_syslog("No change for leave of type ".$key, LOG_DEBUG);
}
if ($result)
if (! $error)
{
$this->db->commit();
return 1;
@ -1495,7 +1480,7 @@ class Holiday extends CommonObject
$obj = $this->db->fetch_object($resql);
$tab_result[$i]['rowid'] = $obj->rowid;
$tab_result[$i]['rowid'] = $obj->rowid; // rowid of user
$tab_result[$i]['name'] = $obj->lastname; // deprecated
$tab_result[$i]['lastname'] = $obj->lastname;
$tab_result[$i]['firstname'] = $obj->firstname;
@ -1503,7 +1488,7 @@ class Holiday extends CommonObject
$tab_result[$i]['status'] = $obj->statut;
$tab_result[$i]['employee'] = $obj->employee;
$tab_result[$i]['photo'] = $obj->photo;
$tab_result[$i]['fk_user'] = $obj->fk_user;
$tab_result[$i]['fk_user'] = $obj->fk_user; // rowid of manager
//$tab_result[$i]['type'] = $obj->type;
//$tab_result[$i]['nb_holiday'] = $obj->nb_holiday;
@ -1522,7 +1507,7 @@ class Holiday extends CommonObject
else
{
// List of vacation balance users
$sql = "SELECT cpu.fk_user, cpu.fk_type, cpu.nb_holiday, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut, u.fk_user";
$sql = "SELECT cpu.fk_user as rowid, cpu.fk_type, cpu.nb_holiday, u.lastname, u.firstname, u.gender, u.photo, u.employee, u.statut, u.fk_user";
$sql.= " FROM ".MAIN_DB_PREFIX."holiday_users as cpu, ".MAIN_DB_PREFIX."user as u";
$sql.= " WHERE cpu.fk_user = u.rowid";
if ($filters) $sql.=$filters;
@ -1541,7 +1526,7 @@ class Holiday extends CommonObject
{
$obj = $this->db->fetch_object($resql);
$tab_result[$i]['rowid'] = $obj->fk_user;
$tab_result[$i]['rowid'] = $obj->rowid; // rowid of user
$tab_result[$i]['name'] = $obj->lastname; // deprecated
$tab_result[$i]['lastname'] = $obj->lastname;
$tab_result[$i]['firstname'] = $obj->firstname;
@ -1549,9 +1534,9 @@ class Holiday extends CommonObject
$tab_result[$i]['status'] = $obj->statut;
$tab_result[$i]['employee'] = $obj->employee;
$tab_result[$i]['photo'] = $obj->photo;
$tab_result[$i]['fk_user'] = $obj->fk_user;
$tab_result[$i]['fk_user'] = $obj->fk_user; // rowid of manager
$tab_result[$i]['type'] = $obj->type;
$tab_result[$i]['type'] = $obj->fk_type;
$tab_result[$i]['nb_holiday'] = $obj->nb_holiday;
$i++;

View File

@ -60,6 +60,18 @@ if ($user->societe_id > 0) // Protection if external user
}
$result = restrictedArea($user, 'holiday', $id, '');
$id = GETPOST('id','int');
// If we are on the view of a specific user
if ($id > 0)
{
$canread=0;
if ($id == $user->id) $canread=1;
if (! empty($user->rights->holiday->read_all)) $canread=1;
if (! empty($user->rights->holiday->read) && in_array($id, $childids)) $canread=1;
if (! $canread)
{
accessforbidden();
}
}
// Load variable for pagination
$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit;

View File

@ -54,7 +54,7 @@ $sortfield = GETPOST("sortfield");
if (!$sortorder) $sortorder="DESC";
if (!$sortfield) $sortfield="e.rowid";
if ($page == -1) {
if (empty($page) || $page == -1) {
$page = 0 ;
}

View File

@ -560,3 +560,5 @@ UPDATE llx_advtargetemailing SET fk_element = fk_mailing, type_element='mailing'
ALTER TABLE llx_advtargetemailing DROP COLUMN fk_mailing;
DROP TABLE llx_ticket_logs;
ALTER TABLE llx_actioncomm MODIFY COLUMN code varchar(50);

View File

@ -199,6 +199,15 @@ delete from llx_element_element where sourcetype='commande' and fk_source not in
DELETE FROM llx_actioncomm_resources WHERE fk_actioncomm not in (select id from llx_actioncomm);
-- Fix link on parent that were removed
DROP table tmp_user;
CREATE TABLE tmp_user as (select * from llx_user);
UPDATE llx_user SET fk_user = NULL where fk_user NOT IN (select rowid from tmp_user);
update llx_user set fk_user = null where fk_user not in (select rowid from llx_user);
UPDATE llx_product SET canvas = NULL where canvas = 'default@product';
UPDATE llx_product SET canvas = NULL where canvas = 'service@product';

View File

@ -29,7 +29,7 @@ create table llx_actioncomm
datep2 datetime, -- date end
fk_action integer, -- type of action (optional link with id in llx_c_actioncomm or null)
code varchar(32) NULL, -- code of action for automatic action ('AC_OTH_AUTO' for automatic actions, 'AC_EMAILIN_AUTO' for email input, 'AC_xxx' for manual action...)
code varchar(50) NULL, -- code of action for automatic action ('AC_OTH_AUTO' for automatic actions, 'AC_EMAILIN_AUTO' for email input, 'AC_xxx' for manual action...)
datec datetime, -- date creation
tms timestamp, -- date modification

View File

@ -774,7 +774,7 @@ if ($ok && GETPOST('clean_product_stock_batch','alpha'))
if ($resql2)
{
// We update product_stock, so we must field stock into product too.
$sql3='UPDATE llx_product p SET p.stock= (SELECT SUM(ps.reel) FROM llx_product_stock ps WHERE ps.fk_product = p.rowid)';
$sql3='UPDATE '.MAIN_DB_PREFIX.'product p SET p.stock= (SELECT SUM(ps.reel) FROM '.MAIN_DB_PREFIX.'product_stock ps WHERE ps.fk_product = p.rowid)';
$resql3=$db->query($sql3);
if (! $resql3)
{

View File

@ -451,6 +451,11 @@ if ($action == "set")
$buffer=trim($buffer);
if ($buffer)
{
// Replace the prefix in table names
if ($dolibarr_main_db_prefix != 'llx_')
{
$buffer=preg_replace('/llx_/i',$dolibarr_main_db_prefix,$buffer);
}
dolibarr_install_syslog("step2: request: " . $buffer);
print "<!-- Insert line : ".$buffer."<br>-->\n";
$resql=$db->query($buffer,0,'dml');

View File

@ -691,8 +691,8 @@ function migrate_paiements_orphelins_1($db,$langs,$conf)
$sql = "SELECT distinct p.rowid, p.datec, p.amount as pamount, bu.fk_bank, b.amount as bamount,";
$sql.= " bu2.url_id as socid";
$sql.= " FROM (".MAIN_DB_PREFIX."paiement as p, ".MAIN_DB_PREFIX."bank_url as bu, ".MAIN_DB_PREFIX."bank as b)";
$sql.= " LEFT JOIN llx_paiement_facture as pf ON pf.fk_paiement = p.rowid";
$sql.= " LEFT JOIN llx_bank_url as bu2 ON (bu.fk_bank=bu2.fk_bank AND bu2.type = 'company')";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON pf.fk_paiement = p.rowid";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."bank_url as bu2 ON (bu.fk_bank=bu2.fk_bank AND bu2.type = 'company')";
$sql.= " WHERE pf.rowid IS NULL AND (p.rowid=bu.url_id AND bu.type='payment') AND bu.fk_bank = b.rowid";
$sql.= " AND b.rappro = 1";
$sql.= " AND (p.fk_facture = 0 OR p.fk_facture IS NULL)";
@ -818,8 +818,8 @@ function migrate_paiements_orphelins_2($db,$langs,$conf)
$sql = "SELECT distinct p.rowid, p.datec, p.amount as pamount, bu.fk_bank, b.amount as bamount,";
$sql.= " bu2.url_id as socid";
$sql.= " FROM (".MAIN_DB_PREFIX."paiement as p, ".MAIN_DB_PREFIX."bank_url as bu, ".MAIN_DB_PREFIX."bank as b)";
$sql.= " LEFT JOIN llx_paiement_facture as pf ON pf.fk_paiement = p.rowid";
$sql.= " LEFT JOIN llx_bank_url as bu2 ON (bu.fk_bank = bu2.fk_bank AND bu2.type = 'company')";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."paiement_facture as pf ON pf.fk_paiement = p.rowid";
$sql.= " LEFT JOIN ".MAIN_DB_PREFIX."bank_url as bu2 ON (bu.fk_bank = bu2.fk_bank AND bu2.type = 'company')";
$sql.= " WHERE pf.rowid IS NULL AND (p.fk_bank = bu.fk_bank AND bu.type = 'payment') AND bu.fk_bank = b.rowid";
$sql.= " AND (p.fk_facture = 0 OR p.fk_facture IS NULL)";
@ -1135,7 +1135,7 @@ function migrate_contracts_date1($db,$langs,$conf)
print '<br>';
print '<b>'.$langs->trans('MigrationContractsEmptyDatesUpdate')."</b><br>\n";
$sql="update llx_contrat set date_contrat=tms where date_contrat is null";
$sql="update ".MAIN_DB_PREFIX."contrat set date_contrat=tms where date_contrat is null";
dolibarr_install_syslog("upgrade2::migrate_contracts_date1");
$resql = $db->query($sql);
if (! $resql) dol_print_error($db);
@ -1144,7 +1144,7 @@ function migrate_contracts_date1($db,$langs,$conf)
else
print $langs->trans('MigrationContractsEmptyDatesNothingToUpdate')."<br>\n";
$sql="update llx_contrat set datec=tms where datec is null";
$sql="update ".MAIN_DB_PREFIX."contrat set datec=tms where datec is null";
dolibarr_install_syslog("upgrade2::migrate_contracts_date1");
$resql = $db->query($sql);
if (! $resql) dol_print_error($db);
@ -1235,7 +1235,7 @@ function migrate_contracts_date3($db,$langs,$conf)
print '<br>';
print '<b>'.$langs->trans('MigrationContractsIncoherentCreationDateUpdate')."</b><br>\n";
$sql="update llx_contrat set datec=date_contrat where datec is null or datec > date_contrat";
$sql="update ".MAIN_DB_PREFIX."contrat set datec=date_contrat where datec is null or datec > date_contrat";
dolibarr_install_syslog("upgrade2::migrate_contracts_date3");
$resql = $db->query($sql);
if (! $resql) dol_print_error($db);
@ -1262,7 +1262,7 @@ function migrate_contracts_open($db,$langs,$conf)
print '<br>';
print '<b>'.$langs->trans('MigrationReopeningContracts')."</b><br>\n";
$sql = "SELECT c.rowid as cref FROM llx_contrat as c, llx_contratdet as cd";
$sql = "SELECT c.rowid as cref FROM ".MAIN_DB_PREFIX."contrat as c, ".MAIN_DB_PREFIX."contratdet as cd";
$sql.= " WHERE cd.statut = 4 AND c.statut=2 AND c.rowid=cd.fk_contrat";
dolibarr_install_syslog("upgrade2::migrate_contracts_open");
$resql = $db->query($sql);
@ -1995,7 +1995,7 @@ function migrate_modeles($db,$langs,$conf)
if (count($modellist)==0)
{
// Aucun model par defaut.
$sql=" insert into llx_document_model(nom,type) values('crabe','invoice')";
$sql=" insert into ".MAIN_DB_PREFIX."document_model(nom,type) values('crabe','invoice')";
$resql = $db->query($sql);
if (! $resql) dol_print_error($db);
}
@ -2008,7 +2008,7 @@ function migrate_modeles($db,$langs,$conf)
if (count($modellist)==0)
{
// Aucun model par defaut.
$sql=" insert into llx_document_model(nom,type) values('einstein','order')";
$sql=" insert into ".MAIN_DB_PREFIX."document_model(nom,type) values('einstein','order')";
$resql = $db->query($sql);
if (! $resql) dol_print_error($db);
}
@ -2021,7 +2021,7 @@ function migrate_modeles($db,$langs,$conf)
if (count($modellist)==0)
{
// Aucun model par defaut.
$sql=" insert into llx_document_model(nom,type) values('rouget','shipping')";
$sql=" insert into ".MAIN_DB_PREFIX."document_model(nom,type) values('rouget','shipping')";
$resql = $db->query($sql);
if (! $resql) dol_print_error($db);
}

View File

@ -83,6 +83,11 @@ InvoiceDeleted=Invoice deleted
PRODUCT_CREATEInDolibarr=Product %s created
PRODUCT_MODIFYInDolibarr=Product %s modified
PRODUCT_DELETEInDolibarr=Product %s deleted
HOLIDAY_CREATEInDolibarr=Request for leave %s created
HOLIDAY_MODIFYInDolibarr=Request for leave %s modified
HOLIDAY_APPROVEInDolibarr=Request for leave %s approved
HOLIDAY_VALIDATEDInDolibarr=Request for leave %s validated
HOLIDAY_DELETEInDolibarr=Request for leave %s deleted
EXPENSE_REPORT_CREATEInDolibarr=Expense report %s created
EXPENSE_REPORT_VALIDATEInDolibarr=Expense report %s validated
EXPENSE_REPORT_APPROVEInDolibarr=Expense report %s approved

View File

@ -94,6 +94,7 @@ PaymentHigherThanReminderToPay=Payment higher than reminder to pay
HelpPaymentHigherThanReminderToPay=Attention, the payment amount of one or more bills is higher than the rest to pay. <br> Edit your entry, otherwise confirm and think about creating a credit note of the excess received for each overpaid invoices.
HelpPaymentHigherThanReminderToPaySupplier=Attention, the payment amount of one or more bills is higher than the rest to pay. <br> Edit your entry, otherwise confirm and think about creating a credit note of the excess paid for each overpaid invoice.
ClassifyPaid=Classify 'Paid'
ClassifyUnPaid=Classify 'Unpaid'
ClassifyPaidPartially=Classify 'Paid partially'
ClassifyCanceled=Classify 'Abandoned'
ClassifyClosed=Classify 'Closed'

View File

@ -95,6 +95,7 @@ HelpPaymentHigherThanReminderToPay=Attention, le montant de paiement pour une ou
HelpPaymentHigherThanReminderToPaySupplier=Attention, le montant de paiement pour une ou plusieurs factures est supérieur au reste à payer.<br>Corrigez votre saisie, sinon, confirmez et pensez à créer un avoir pour l'excédent pour chaque facture surpayée.
ClassifyPaid=Classer 'Payée'
ClassifyPaidPartially=Classer 'Payée partiellement'
ClassifyUnPaid=Classer 'Non payée'
ClassifyCanceled=Classer 'Abandonnée'
ClassifyClosed=Classer 'Fermée'
ClassifyUnBilled=Classer 'Non facturée'

View File

@ -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…)

View File

@ -65,7 +65,7 @@ RuleForStockManagementIncrease=Règle de gestion des incrémentations de stock (
DeStockOnBill=Décrémenter les stocks physiques sur validation des factures/avoirs clients
DeStockOnValidateOrder=Décrémenterr les stocks physiques sur validation des commandes clients
DeStockOnShipment=Décrémenter les stocks physiques sur validation des expéditions
DeStockOnShipmentOnClosing=Décrémenter les stocks phisiques au classement "clôturée" de l'expédition
DeStockOnShipmentOnClosing=Décrémenter les stocks physiques au classement "clôturée" de l'expédition
ReStockOnBill=Incrémenter les stocks physiques sur validation des factures/avoirs fournisseurs
ReStockOnValidateOrder=Incrémenter les stocks physiques sur approbation des commandes fournisseurs
ReStockOnDispatchOrder=Incrémenter les stocks physiques sur ventilation manuelle dans les entrepôts, après réception de la marchandise

View File

@ -570,7 +570,7 @@ else
}
// Other attributes
if ($action = 'create_delivery') {
if ($action == 'create_delivery') {
// copy from expedition
$expeditionExtrafields = new Extrafields($db);
$expeditionExtrafieldLabels = $expeditionExtrafields->fetch_name_optionals_label($expedition->table_element);
@ -675,7 +675,7 @@ else
$mode = ($object->statut == 0) ? 'edit' : 'view';
$line = new LivraisonLigne($db);
$line->fetch_optionals($object->lines[$i]->id);
if ($action = 'create_delivery') {
if ($action == 'create_delivery') {
$srcLine = new ExpeditionLigne($db);
$expeditionLineExtrafields = new Extrafields($db);
$expeditionLineExtrafieldLabels = $expeditionLineExtrafields->fetch_name_optionals_label($srcLine->table_element);

View File

@ -47,7 +47,7 @@ $result = restrictedArea($user, 'loan', $id, '','');
$sortfield = GETPOST("sortfield",'alpha');
$sortorder = GETPOST("sortorder",'alpha');
$page = GETPOST("page",'int');
if ($page == -1) {
if (empty($page) || $page == -1) {
$page = 0;
}
$offset = $conf->liste_limit * $page;

Some files were not shown because too many files have changed in this diff Show More