diff --git a/ChangeLog b/ChangeLog index b67cbabafb4..649851f526b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -3,6 +3,81 @@ English Dolibarr ChangeLog -------------------------------------------------------------- +***** ChangeLog for 15.0.3 compared to 15.0.2 ***** + +FIX: 15.0: modules cannot declare more than 1 cron job using the same method with different parameters +FIX: 15 fix graph ficheinter status +FIX: #18704 +FIX: #20444 +FIX: #20448 missing preg_replace for vat rate when adding a free line +FIX: #20476 migration postgresql 13.0.x to 14.0.x packaging type +FIX: #20487 missing letter D in constant THIRDPARTIES_DISABLE_RELATED_… +FIX: #20487 missing letter D in constant THIRDPARTIES_DISABLE_RELATED_OBJECT_TAB +FIX: #20527 Accountancy - Unbalanced entry proposed when an employee are declared on a social contribution +FIX: #20527 Accountancy Unbalanced entry proposed when an employee are declared on social contribution +FIX: #20621 signature online with proposal with n page. +FIX: #20696 +FIX: #20828 +FIX: #20886 : manage durations in list_print_total.tpl.php +FIX: #20902 +FIX: #21051 +FIX: #21093 +FIX: #21138 +FIX: #21140 +FIX: #21174 +FIX: #21323 +FIX: #21472 On the bank transfer lists, a change of page switches to the lists of the direct debit module +FIX: #21495 +FIX: #21518 +FIX: Accountancy - Label of VAT account is empty +FIX: Accountancy - Model account list - Problem of CSRF +FIX: Accountancy - Partitioning of the entity on an automatic binding +FIX: add missing thead, th and id on table +FIX: backport commit 5b3fcc5e43979b1b0789bf81fb8f1b2b59c93056, chkbxlst cannot be emptied +FIX: Bank account not set when creating invoice from order +FIX: Bank transfer - Link on code supplier invoice was bad +FIX: Can convert a partially closed down payment when close for +FIX: class center linkedObjectblock order date +FIX: count elements in invoice list (Issue #21444) +FIX: Customer price non numeric warning when 0 vat. +FIX: errors in getLinesArray() +FIX: False alert of WAF when there is "set" into some URL action=update. +FIX: Intervention graph by status on ficheinter Index page +FIX: Intervention url link into Commerce index +FIX: Fix get origin from other than supplier proposal when add a new supplier proposal +FIX: Fix show errors in card +FIX: fourn/commande/card.php Added "$object" parameter to $formfile->showdocuments call +FIX: french traductions for payment methods +FIX: hook for dol_format_address +FIX: Index page for "Sales" give wrong URL link to Intervention +FIX: issue Dolibarr#21495 for v15 +FIX: label and get_substitutionarray_each_var_object on ODT generation +FIX: load product stock in inventory lines +FIX: missing morecss for multiselectarray +FIX: missins time spent list menu +FIX: new member subscription: bank account and payment mode might be hidden +FIX: ODT generation of BOM document +FIX: ODT tags for subobjects {object_subobject_yyy} was not working. +FIX: qty received label in Squille PDF model +FIX: rank duplicate on mass action invoice from multiple orders +FIX: regression + add $forceentity parameter +FIX: regression PR #20713 +FIX: security breach if we have same ref number in multiple entities +FIX: selection of type of invoice +FIX: Send remind to pay invoice only on validated invoices +FIX: Show sellist type of extrafield when none category selected +FIX: signature online with proposal with n page. +FIX: sql error when PRODUCT_USE_SUPPLIER_PACKAGING enabled. +FIX: sql order +FIX: trash icon on crontask list to do not work +FIX: v15 linked object block center order date +FIX: Warning on attribut +FIX: We must remove empty values of $features array in fetchByProductCombination2ValuePairs() because some products can use only several attributes in their variations and not necessarily all. In this case, fetch doesn't work without my correction +FIX: with callback function +FIX: xml file for company with special chars in name +FIX: Zatca QR code must use company name/vat + + ***** ChangeLog for 15.0.2 compared to 15.0.1 ***** FIX: #19777 #20281 diff --git a/build/README b/build/README index 626953f9376..19cf4ad1ec2 100644 --- a/build/README +++ b/build/README @@ -13,32 +13,12 @@ It is here only to build Dolibarr packages, and those generated packages will no There are several tools: +-------------------------------------------------------------------------------------------------- - To build full Dolibarr packages, launch the script > Launch command perl makepack-dolibarr.pl --------------------------------------------------------------------------------------------------- - - -Prerequisites to build tgz, debian and rpm packages: -> apt-get install tar dpkg dpatch p7zip-full rpm zip - - --------------------------------------------------------------------------------------------------- - -Prerequisites to build autoexe DoliWamp package: -> apt-get install wine q4wine -> Launch "wine cmd" to check a drive Z: pointing to / exists. -> Install InnoSetup - For example by running isetup-5.5.8.exe (https://www.jrsoftware.org) https://files.jrsoftware.org/is/5/ -> Install WampServer into "C:\wamp64" to have Apache, PHP and MariaDB - For example by running wampserver3.2.0_x64.exe (https://www.wampserver.com). - See file build/exe/doliwamp.iss to know the doliwamp version currently setup. -> Add path to ISCC into PATH windows var: - Launch wine cmd, then regedit and add entry int HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment\PATH -> To build manually the .exe from Windows (running from makepack-dolibarr.pl script is however recommanded), - open file build/exe/doliwamp.iss and click on button "Compile". - The .exe file will be build into directory build. +See makepack-howto.txt for prerequisites. -------------------------------------------------------------------------------------------------- diff --git a/build/exe/doliwamp/.gitignore b/build/exe/doliwamp/.gitignore index ce74d54f78e..f9a2ea83b34 100644 --- a/build/exe/doliwamp/.gitignore +++ b/build/exe/doliwamp/.gitignore @@ -1 +1 @@ -/doliwamp.tmp.iss +/doliwamp.tmp.iss* diff --git a/build/exe/doliwamp/doliwamp.iss b/build/exe/doliwamp/doliwamp.iss index dbf74a96f67..f2f65ee3abb 100644 --- a/build/exe/doliwamp/doliwamp.iss +++ b/build/exe/doliwamp/doliwamp.iss @@ -24,15 +24,14 @@ OutputBaseFilename=__FILENAMEEXEDOLIWAMP__ ;OutputManifestFile=build\doliwampbuild.log ; Define full path from which all relative path are defined ; You must modify this to put here your dolibarr root directory -;SourceDir=Z:\home\ldestailleur\git\dolibarrxxx SourceDir=..\..\.. AppId=doliwamp -AppPublisher=NLTechno -AppPublisherURL=https://www.nltechno.com +AppPublisher=DoliCloud +AppPublisherURL=https://www.dolicloud.com AppSupportURL=https://www.dolibarr.org AppUpdatesURL=https://www.dolibarr.org AppComments=DoliWamp includes Dolibarr, Apache, PHP and Mysql software. -AppCopyright=Copyright (C) 2008-2020 Laurent Destailleur (NLTechno), Fabian Rodriguez (Le Goût du Libre) +AppCopyright=Copyright (C) 2008-2022 Laurent Destailleur (DoliCloud), Fabian Rodriguez (Le Goût du Libre) DefaultDirName=c:\dolibarr DefaultGroupName=Dolibarr ;LicenseFile=COPYING @@ -81,7 +80,7 @@ Name: "desktopicon"; Description: {cm:CreateDesktopIcon}; GroupDescription: {cm: Name: "{app}\logs" Name: "{app}\tmp" Name: "{app}\dolibarr_documents" -Name: "{app}\bin\apache\apache2.4.41\logs" +Name: "{app}\bin\apache\apache2.4.51\logs" [Files] ; Stop/start @@ -101,17 +100,12 @@ Source: "build\exe\doliwamp\UsedPort.exe"; DestDir: "{app}\"; Flags: ignoreversi ; PhpMyAdmin, Apache, Php, Mysql ; Put here path of Wampserver applications -; Value OK: apache 2.2.6, php 5.2.5 (5.2.11, 5.3.0 and 5.3.1 fails if php_exif, php_pgsql, php_zip is on), mysql 5.0.45 -; Value OK: apache 2.2.11, php 5.3.0 (if no php_exif, php_pgsql, php_zip), mysql 5.0.45 -; Value OK: apache 2.4.9, php 5.5.12, mysql 5.0.45 instead of 5.6.17 (wampserver2.5-Apache-2.4.9-Mysql-5.6.17-php5.5.12-32b.exe) ; Value OK: apache 2.4.41, php 7.3.12, mariadb10.4.10 (wampserver3.2.0_x64.exe) -Source: "C:\wamp64\apps\phpmyadmin4.9.2\*.*"; DestDir: "{app}\apps\phpmyadmin4.9.2"; Flags: ignoreversion recursesubdirs; Excludes: "config.inc.php,wampserver.conf,*.log,*_log,darkblue_orange" -;Source: "C:\Program Files\Wamp\bin\apache\apache2.4.9\*.*"; DestDir: "{app}\bin\apache\apache2.4.9"; Flags: ignoreversion recursesubdirs; Excludes: "php.ini,httpd.conf,wampserver.conf,*.log,*_log" -Source: "C:\wamp64\bin\apache\apache2.4.41\*.*"; DestDir: "{app}\bin\apache\apache2.4.41"; Flags: ignoreversion recursesubdirs; Excludes: "php.ini,httpd.conf,wampserver.conf,*.log,*_log" -;Source: "C:\Program Files\Wamp\bin\php\php5.5.12\*.*"; DestDir: "{app}\bin\php\php5.5.12"; Flags: ignoreversion recursesubdirs; Excludes: "php.ini,phpForApache.ini,wampserver.conf,*.log,*_log" -Source: "C:\wamp64\bin\php\php7.3.12\*.*"; DestDir: "{app}\bin\php\php7.3.12"; Flags: ignoreversion recursesubdirs; Excludes: "php.ini,phpForApache.ini,wampserver.conf,*.log,*_log" -;Source: "C:\Program Files\Wamp\bin\mysql\mysql5.0.45\*.*"; DestDir: "{app}\bin\mysql\mysql5.0.45"; Flags: ignoreversion recursesubdirs; Excludes: "my.ini,data\*,wampserver.conf,*.log,*_log,MySQLInstanceConfig.exe" -Source: "C:\wamp64\bin\mariadb\mariadb10.4.10\*.*"; DestDir: "{app}\bin\mariadb\mariadb10.4.10"; Flags: ignoreversion recursesubdirs; Excludes: "my.ini,data\*,wampserver.conf,*.log,*_log,MySQLInstanceConfig.exe" +; Value OK: apache 2.4.51, php 7.3.33, mariadb10.6.5 (wampserver3.2.6_x64.exe) +Source: "C:\wamp64\apps\phpmyadmin4.9.7\*.*"; DestDir: "{app}\apps\phpmyadmin4.9.7"; Flags: ignoreversion recursesubdirs; Excludes: "config.inc.php,wampserver.conf,*.log,*_log,darkblue_orange" +Source: "C:\wamp64\bin\apache\apache2.4.51\*.*"; DestDir: "{app}\bin\apache\apache2.4.51"; Flags: ignoreversion recursesubdirs; Excludes: "php.ini,httpd.conf,wampserver.conf,*.log,*_log" +Source: "C:\wamp64\bin\php\php7.3.33\*.*"; DestDir: "{app}\bin\php\php7.3.33"; Flags: ignoreversion recursesubdirs; Excludes: "php.ini,phpForApache.ini,wampserver.conf,*.log,*_log" +Source: "C:\wamp64\bin\mariadb\mariadb10.6.5\*.*"; DestDir: "{app}\bin\mariadb\mariadb10.6.5"; Flags: ignoreversion recursesubdirs; Excludes: "my.ini,data\*,wampserver.conf,*.log,*_log,MySQLInstanceConfig.exe" ; Mysql data files (does not overwrite if exists) ; We must copy them because the tool mysql_install_db.exe to generate them at first install does not return to prompt so make install hang @@ -128,12 +122,10 @@ Source: "*.*"; DestDir: "{app}\www\dolibarr"; Flags: ignoreversion; Excludes: ". Source: "build\exe\doliwamp\phpmyadmin.conf.install"; DestDir: "{app}\alias"; Flags: ignoreversion; Source: "build\exe\doliwamp\dolibarr.conf.install"; DestDir: "{app}\alias"; Flags: ignoreversion; Source: "build\exe\doliwamp\config.inc.php.install"; DestDir: "{app}\apps\phpmyadmin4.1.14"; Flags: ignoreversion; -;Source: "build\exe\doliwamp\httpd.conf.install"; DestDir: "{app}\bin\apache\apache2.4.9\conf"; Flags: ignoreversion; -Source: "build\exe\doliwamp\httpd.conf.install"; DestDir: "{app}\bin\apache\apache2.4.41\conf"; Flags: ignoreversion; +Source: "build\exe\doliwamp\httpd.conf.install"; DestDir: "{app}\bin\apache\apache2.4.51\conf"; Flags: ignoreversion; Source: "build\exe\doliwamp\my.ini.install"; DestDir: "{app}\bin\mysql\mysql5.0.45"; Flags: ignoreversion; -Source: "build\exe\doliwamp\my.ini.install"; DestDir: "{app}\bin\mariadb\mariadb10.4.10"; Flags: ignoreversion; -;Source: "build\exe\doliwamp\php.ini.install"; DestDir: "{app}\bin\php\php5.5.12"; Flags: ignoreversion; -Source: "build\exe\doliwamp\php.ini.install"; DestDir: "{app}\bin\php\php7.3.12"; Flags: ignoreversion; +Source: "build\exe\doliwamp\my.ini.install"; DestDir: "{app}\bin\mariadb\mariadb10.6.5"; Flags: ignoreversion; +Source: "build\exe\doliwamp\php.ini.install"; DestDir: "{app}\bin\php\php7.3.33"; Flags: ignoreversion; Source: "build\exe\doliwamp\index.php.install"; DestDir: "{app}\www"; Flags: ignoreversion; Source: "build\exe\doliwamp\install.forced.php.install"; DestDir: "{app}\www\dolibarr\htdocs\install"; Flags: ignoreversion; Source: "build\exe\doliwamp\openssl.conf"; DestDir: "{app}"; Flags: ignoreversion; @@ -240,13 +232,10 @@ procedure InitializeWizard(); begin //version des applis, a modifier pour chaque version de WampServer 2 - //apacheVersion := '2.4.9'; - //phpVersion := '5.5.12' ; - apacheVersion := '2.4.41'; - phpVersion := '7.3.12' ; - //mysqlVersion := '5.0.45'; - mysqlVersion := '10.4.10'; - phpmyadminVersion := '4.1.14'; + apacheVersion := '2.4.51'; + phpVersion := '7.3.33' ; + mysqlVersion := '10.6.5'; + phpmyadminVersion := '4.9.7'; smtpServer := 'localhost'; apachePort := '80'; @@ -380,9 +369,9 @@ begin // Migration of database -// datadir := pathWithSlashes+'/bin/mariadb/marradb10.4.10/data'; -// exedirold := pathWithSlashes+'/bin/mariadb/marradb10.4.10/'; -// exedirnew := pathWithSlashes+'/bin/mariadb/marradb10.4.10/'; +// datadir := pathWithSlashes+'/bin/mariadb/mariadb10.6.5/data'; +// exedirold := pathWithSlashes+'/bin/mariadb/mariadb10.6.5/'; +// exedirnew := pathWithSlashes+'/bin/mariadb/mariadb10.6.5/'; // If we have a new database version, we should only copy old my.ini file into new directory // and change only all basedir= strings to use new version. Like this, data dir is still correct. @@ -1082,7 +1071,7 @@ Filename: "{app}\rundoliwamp.bat"; Description: {cm:LaunchNow}; Flags: shellexec [UninstallDelete] Type: files; Name: "{app}\*.*" -Type: files; Name: "{app}\bin\mariadb\mariadb10.4.10\*.*" +Type: files; Name: "{app}\bin\mariadb\mariadb10.6.5\*.*" Type: filesandordirs; Name: "{app}\alias" Type: filesandordirs; Name: "{app}\apps" Type: filesandordirs; Name: "{app}\bin\apache" diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl index 2cce46146c4..01240ae34d7 100755 --- a/build/makepack-dolibarr.pl +++ b/build/makepack-dolibarr.pl @@ -65,7 +65,7 @@ $DIR||='.'; $DIR =~ s/([^\/\\])[\\\/]+$/$1/; $SOURCE="$DIR/.."; $DESTI="$SOURCE/build"; -if ($SOURCE !~ /^\//) +if ($SOURCE !~ /^\// && $SOURCE !~ /^[a-z]:/i) { print "Error: Launch the script $PROG.$Extension with its full path from /.\n"; print "$PROG.$Extension aborted.\n"; @@ -76,15 +76,23 @@ if (! $ENV{"DESTIBETARC"} || ! $ENV{"DESTISTABLE"}) { print "Error: Missing environment variables.\n"; print "You must define the environment variable DESTIBETARC and DESTISTABLE to point to the\ndirectories where you want to save the generated packages.\n"; + print "$PROG.$Extension aborted.\n"; + print "\n"; + print "You can set them with\n"; + print "On Linux:\n"; + print "export DESTIBETARC='/tmp'; export DESTISTABLE='/tmp';\n"; + print "On Windows:\n"; + print "set DESTIBETARC=c:/tmp\n"; + print "set DESTISTABLE=c:/tmp\n"; + print "\n"; print "Example: DESTIBETARC='/media/HDDATA1_LD/Mes Sites/Web/Dolibarr/dolibarr.org/files/lastbuild'\n"; print "Example: DESTISTABLE='/media/HDDATA1_LD/Mes Sites/Web/Dolibarr/dolibarr.org/files/stable'\n"; - print "$PROG.$Extension aborted.\n"; sleep 2; exit 1; } if (! -d $ENV{"DESTIBETARC"} || ! -d $ENV{"DESTISTABLE"}) { - print "Error: Directory of environment variable DESTIBETARC or DESTISTABLE does not exist.\n"; + print "Error: Directory of environment variable DESTIBETARC ($ENV{'DESTIBETARC'}) or DESTISTABLE ($ENV{'DESTISTABLE'}) does not exist.\n"; print "$PROG.$Extension aborted.\n"; sleep 2; exit 1; @@ -94,7 +102,7 @@ if (! -d $ENV{"DESTIBETARC"} || ! -d $ENV{"DESTISTABLE"}) # -------------- if ("$^O" =~ /linux/i || (-d "/etc" && -d "/var" && "$^O" !~ /cygwin/i)) { $OS='linux'; $CR=''; } elsif (-d "/etc" && -d "/Users") { $OS='macosx'; $CR=''; } -elsif ("$^O" =~ /cygwin/i || "$^O" =~ /win32/i) { $OS='windows'; $CR="\r"; } +elsif ("$^O" =~ /cygwin/i || "$^O" =~ /win32/i || "$^O" =~ /msys/i) { $OS='windows'; $CR="\r"; } if (! $OS) { print "Error: Can't detect your OS.\n"; print "Can't continue.\n"; @@ -390,7 +398,7 @@ if ($nboftargetok) { $olddir=getcwd(); chdir("$SOURCE"); - print "Clean $SOURCE/htdocs\n"; + print "Clean $SOURCE/htdocs/includes/autoload.php\n"; $ret=`rm -f $SOURCE/htdocs/includes/autoload.php`; $ret=`git ls-files . --exclude-standard --others`; @@ -1076,28 +1084,52 @@ if ($nboftargetok) { print "Remove target $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe...\n"; unlink "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe"; - print "Check that in your Wine setup, you have created a Z: drive that point to your / directory.\n"; - + if ($OS eq 'windows') { + print "Check that ISCC.exe is in your PATH.\n"; + } else { + print "Check that in your Wine setup, you have created a Z: drive that point to your / directory.\n"; + } + $SOURCEBACK=$SOURCE; $SOURCEBACK =~ s/\//\\/g; - print "Prepare file \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss from \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.iss\"\n"; - $ret=`cat "$SOURCE/build/exe/doliwamp/doliwamp.iss" | sed -e 's/__FILENAMEEXEDOLIWAMP__/$FILENAMEEXEDOLIWAMP/g' > "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"`; + print "Prepare file \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\" from \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.iss\"\n"; + + #$ret=`cat "$SOURCE/build/exe/doliwamp/doliwamp.iss" | sed -e 's/__FILENAMEEXEDOLIWAMP__/$FILENAMEEXEDOLIWAMP/g' > "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"`; + open(IN, '<' . $SOURCE."/build/exe/doliwamp/doliwamp.iss") or die $!; + open(OUT, '>' . "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss") or die $!; + while() + { + $_ =~ s/__FILENAMEEXEDOLIWAMP__/$FILENAMEEXEDOLIWAMP/g; + print OUT $_; + } + close(IN); + close(OUT); - print "Compil exe $FILENAMEEXEDOLIWAMP.exe file from iss file \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\"\n"; - $cmd= "wine ISCC.exe \"Z:$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\""; + print "Compil exe $FILENAMEEXEDOLIWAMP.exe file from iss file \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\" on OS $OS\n"; + + if ($OS eq 'windows') { + $cmd= "ISCC.exe \"$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\""; + } else { + #$cmd= "wine ISCC.exe \"Z:$SOURCEBACK\\build\\exe\\doliwamp\\doliwamp.tmp.iss\""; + } print "$cmd\n"; $ret= `$cmd`; - #print "$ret\n"; + print "ret=$ret\n"; # Move to final dir print "Move \"$SOURCE\\build\\$FILENAMEEXEDOLIWAMP.exe\" to $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe\n"; rename("$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe","$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe"); print "Move $SOURCE/build/$FILENAMEEXEDOLIWAMP.exe to $NEWDESTI/$FILENAMEEXEDOLIWAMP.exe\n"; - $ret=`mv "$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe" "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe"`; + + use File::Copy; + + #$ret=`mv "$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe" "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe"`; + $ret=move("$SOURCE/build/$FILENAMEEXEDOLIWAMP.exe", "$NEWDESTI/$FILENAMEEXEDOLIWAMP.exe"); print "Remove tmp file $SOURCE/build/exe/doliwamp/doliwamp.tmp.iss\n"; - $ret=`rm "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"`; + #$ret=`rm "$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"`; + $ret=unlink("$SOURCE/build/exe/doliwamp/doliwamp.tmp.iss"); next; } diff --git a/build/makepack-howto.txt b/build/makepack-howto.txt index d4e37e32629..be88302cd1d 100644 --- a/build/makepack-howto.txt +++ b/build/makepack-howto.txt @@ -1,7 +1,34 @@ ----- Dolibarr Makepack How To ----- This documentation describe steps to build a BETA or RELEASE versions -of Dolibarr. There is a chapter for BETA version and a chapter for -RELEASE version. +of Dolibarr. There is a chapter for BETA version and a chapter for RELEASE version. + + +***** Prerequisites For Linux ***** + +Prerequisites to build tgz, debian and rpm packages: +> apt-get install perl tar dpkg dpatch p7zip-full rpm zip php-cli + +Prerequisites to build autoexe DoliWamp package: +> apt-get install wine q4wine +> Launch "wine cmd" to check a drive Z: pointing to / exists. +> Install InnoSetup + For example by running isetup-5.5.8.exe (https://www.jrsoftware.org) https://files.jrsoftware.org/is/5/ +> Install WampServer into "C:\wamp64" to have Apache, PHP and MariaDB + For example by running wampserver3.2.0_x64.exe (https://www.wampserver.com). + See file build/exe/doliwamp.iss to know the doliwamp version currently setup. +> Add path to ISCC into PATH windows var: + Launch wine cmd, then regedit and add entry int HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Session Manager\Environment\PATH +> To build manually the .exe from Windows (running from makepack-dolibarr.pl script is however recommanded), + open file build/exe/doliwamp.iss and click on button "Compile". + The .exe file will be build into directory build. + + +***** Prerequisites For Windows ***** + +Install Perl +Install WampServer-3.2.*-64.exe +isetup-5.5.8.exe + ***** Actions to do a BETA ***** This files describe steps made by Dolibarr packaging team to make a diff --git a/build/rpm/dolibarr_generic.spec b/build/rpm/dolibarr_generic.spec index aeddd5526f8..d8c49176db1 100755 --- a/build/rpm/dolibarr_generic.spec +++ b/build/rpm/dolibarr_generic.spec @@ -54,7 +54,7 @@ BuildRequires: desktop-file-utils Group: Applications/Productivity Requires: apache-base, apache-mod_php, php-cgi, php-cli, php-bz2, php-gd, php-ldap, php-imap, php-mysqli, php-openssl, fonts-ttf-dejavu Requires: mysql, mysql-client -%else%_datadir/dolibarr/htdocs/datapolicy +%else %if 0%{?suse_version} # Voir http://en.opensuse.org/openSUSE:Packaging_Conventions_RPM_Macros Group: Productivity/Office/Management @@ -67,7 +67,7 @@ Requires: httpd, php >= 5.3.0, php-cli, php-gd, php-ldap, php-imap, php-mbstring Requires: mysql-server, mysql Requires: php-mysqli >= 4.1.0 %endif -%endif%_datadir/dolibarr/htdocs/eventorganization +%endif %endif @@ -125,7 +125,7 @@ cui hai bisogno ed essere facile da usare. %if 0%{?sles_version} %{__rm} -rf $RPM_BUILD_ROOT -%{__mkdir} $RPM_BUILD_ROOT%_datadir/dolibarr/htdocs/datapolicy +%{__mkdir} $RPM_BUILD_ROOT% %{__mkdir} $RPM_BUILD_ROOT%{_sysconfdir} %{__mkdir} $RPM_BUILD_ROOT%{_sysconfdir}/%{name} %else diff --git a/htdocs/accountancy/admin/accountmodel.php b/htdocs/accountancy/admin/accountmodel.php index 29c2b7d5510..3707908746c 100644 --- a/htdocs/accountancy/admin/accountmodel.php +++ b/htdocs/accountancy/admin/accountmodel.php @@ -679,7 +679,7 @@ if ($id) { // Can an entry be erased or disabled ? $iserasable = 1; $canbedisabled = 1; $canbemodified = 1; // true by default - $url = $_SERVER["PHP_SELF"].'?'.($page ? 'page='.$page.'&' : '').'sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(!empty($obj->rowid) ? $obj->rowid : (!empty($obj->code) ? $obj->code : '')).'&code='.(!empty($obj->code) ?urlencode($obj->code) : ''); + $url = $_SERVER["PHP_SELF"].'?token='.newToken().($page ? '&page='.$page : '').'&sortfield='.$sortfield.'&sortorder='.$sortorder.'&rowid='.(!empty($obj->rowid) ? $obj->rowid : (!empty($obj->code) ? $obj->code : '')).'&code='.(!empty($obj->code) ?urlencode($obj->code) : ''); if ($param) { $url .= '&'.$param; } diff --git a/htdocs/accountancy/journal/expensereportsjournal.php b/htdocs/accountancy/journal/expensereportsjournal.php index c80586fa3d0..dbd1c892086 100644 --- a/htdocs/accountancy/journal/expensereportsjournal.php +++ b/htdocs/accountancy/journal/expensereportsjournal.php @@ -328,7 +328,7 @@ if ($action == 'writebookkeeping') { foreach ($arrayofvat[$key] as $k => $mt) { if ($mt) { - $accountingaccount->fetch($k, null, true); // TODO Use a cache for label + $accountingaccount->fetch(null, $k, true); // TODO Use a cache for label $account_label = $accountingaccount->label; // get compte id and label diff --git a/htdocs/accountancy/journal/purchasesjournal.php b/htdocs/accountancy/journal/purchasesjournal.php index 8b1ac0d3de3..598a65d8138 100644 --- a/htdocs/accountancy/journal/purchasesjournal.php +++ b/htdocs/accountancy/journal/purchasesjournal.php @@ -451,7 +451,7 @@ if ($action == 'writebookkeeping') { foreach ($arrayofvat[$key] as $k => $mt) { if ($mt) { - $accountingaccount->fetch($k, null, true); // TODO Use a cache for label + $accountingaccount->fetch(null, $k, true); // TODO Use a cache for label $label_account = $accountingaccount->label; $bookkeeping = new BookKeeping($db); diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php index 884c56ee6f2..62eb34162b3 100644 --- a/htdocs/accountancy/journal/sellsjournal.php +++ b/htdocs/accountancy/journal/sellsjournal.php @@ -463,7 +463,7 @@ if ($action == 'writebookkeeping') { foreach ($arrayofvat[$key] as $k => $mt) { if ($mt) { - $accountingaccount->fetch($k, null, true); // TODO Use a cache for label + $accountingaccount->fetch(null, $k, true); // TODO Use a cache for label $label_account = $accountingaccount->label; $bookkeeping = new BookKeeping($db); diff --git a/htdocs/comm/action/class/actioncomm.class.php b/htdocs/comm/action/class/actioncomm.class.php index a5c8a11ade0..627855a94e8 100644 --- a/htdocs/comm/action/class/actioncomm.class.php +++ b/htdocs/comm/action/class/actioncomm.class.php @@ -2065,8 +2065,8 @@ class ActionComm extends CommonObject } if (!empty($conf->global->AGENDA_EXPORT_FIX_TZ)) { - $timestampStart = - ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600); - $timestampEnd = - ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600); + $timestampStart = $timestampStart - ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600); + $timestampEnd = $timestampEnd - ($conf->global->AGENDA_EXPORT_FIX_TZ * 3600); } $urlwithouturlroot = preg_replace('/'.preg_quote(DOL_URL_ROOT, '/').'$/i', '', trim($dolibarr_main_url_root)); diff --git a/htdocs/comm/action/index.php b/htdocs/comm/action/index.php index 419d98dbef8..9b451a47659 100644 --- a/htdocs/comm/action/index.php +++ b/htdocs/comm/action/index.php @@ -109,7 +109,7 @@ $month = GETPOST("month", "int") ?GETPOST("month", "int") : date("m"); $week = GETPOST("week", "int") ?GETPOST("week", "int") : date("W"); $day = GETPOST("day", "int") ?GETPOST("day", "int") : date("d"); $pid = GETPOST("search_projectid", "int", 3) ? GETPOST("search_projectid", "int", 3) : GETPOST("projectid", "int", 3); -$status = GETPOSTISSET("search_status") ? GETPOST("search_status", 'aZ09') : GETPOST("status", 'aZ09'); // status may be 0, 50, 100, 'todo' +$status = GETPOSTISSET("search_status") ? GETPOST("search_status", 'aZ09') : GETPOST("status", 'aZ09'); // status may be 0, 50, 100, 'todo', 'na' or -1 $type = GETPOSTISSET("search_type", 'aZ09') ? GETPOST("search_type", 'aZ09') : GETPOST("type", 'aZ09'); $maxprint = GETPOSTISSET("maxprint") ? GETPOST("maxprint", 'int') : $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW; $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') @@ -760,12 +760,14 @@ if ($type) { if ($status == '0') { $sql .= " AND a.percent = 0"; } -if ($status == '-1') { +if ($status == '-1' || $status == 'na') { + // Not applicable $sql .= " AND a.percent = -1"; -} // Not applicable +} if ($status == '50') { + // Running already started $sql .= " AND (a.percent > 0 AND a.percent < 100)"; -} // Running already started +} if ($status == 'done' || $status == '100') { $sql .= " AND (a.percent = 100)"; } diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php index 82c15392349..78fcfe657db 100644 --- a/htdocs/comm/action/peruser.php +++ b/htdocs/comm/action/peruser.php @@ -99,7 +99,7 @@ $month = GETPOST("month", "int") ?GETPOST("month", "int") : date("m"); $week = GETPOST("week", "int") ?GETPOST("week", "int") : date("W"); $day = GETPOST("day", "int") ?GETPOST("day", "int") : date("d"); $pid = GETPOST("search_projectid", "int", 3) ?GETPOST("search_projectid", "int", 3) : GETPOST("projectid", "int", 3); -$status = GETPOSTISSET("search_status") ? GETPOST("search_status", 'aZ09') : GETPOST("status", 'aZ09'); // status may be 0, 50, 100, 'todo' +$status = GETPOSTISSET("search_status") ? GETPOST("search_status", 'aZ09') : GETPOST("status", 'aZ09'); // status may be 0, 50, 100, 'todo', 'na' or -1 $type = GETPOST("search_type", 'alpha') ?GETPOST("search_type", 'alpha') : GETPOST("type", 'alpha'); $maxprint = ((GETPOST("maxprint", 'int') != '') ?GETPOST("maxprint", 'int') : $conf->global->AGENDA_MAX_EVENTS_DAY_VIEW); $optioncss = GETPOST('optioncss', 'aZ'); // Option for the css output (always '' except when 'print') @@ -626,12 +626,14 @@ if ($type) { if ($status == '0') { $sql .= " AND a.percent = 0"; } -if ($status == '-1') { +if ($status == '-1' || $status == 'na') { + // Not applicable $sql .= " AND a.percent = -1"; -} // Not applicable +} if ($status == '50') { + // Running already started $sql .= " AND (a.percent > 0 AND a.percent < 100)"; -} // Running already started +} if ($status == 'done' || $status == '100') { $sql .= " AND (a.percent = 100)"; } diff --git a/htdocs/comm/propal/card.php b/htdocs/comm/propal/card.php index 94789239d43..cbe2df19026 100644 --- a/htdocs/comm/propal/card.php +++ b/htdocs/comm/propal/card.php @@ -1655,7 +1655,7 @@ if ($action == 'create') { // Mode of payment print ''.$langs->trans('PaymentMode').''; print img_picto('', 'bank').' '; - $form->select_types_paiements((GETPOSTISSET('mode_reglement_id') && (GETPOST('mode_reglement_id') != 0 ? GETPOST('mode_reglement_id', 'int') : $soc->mode_reglement_id)), 'mode_reglement_id', 'CRDT', 0, 1, 0, 0, 1, 'maxwidth200 widthcentpercentminusx'); + $form->select_types_paiements((GETPOSTISSET('mode_reglement_id') && GETPOST('mode_reglement_id') != 0) ? GETPOST('mode_reglement_id', 'int') : $soc->mode_reglement_id, 'mode_reglement_id', 'CRDT', 0, 1, 0, 0, 1, 'maxwidth200 widthcentpercentminusx'); print ''; // Bank Account diff --git a/htdocs/comm/propal/class/propal.class.php b/htdocs/comm/propal/class/propal.class.php index c18e0e7a6df..5b91caa2673 100644 --- a/htdocs/comm/propal/class/propal.class.php +++ b/htdocs/comm/propal/class/propal.class.php @@ -1445,12 +1445,13 @@ class Propal extends CommonObject /** * Load a proposal from database. Get also lines. * - * @param int $rowid id of object to load - * @param string $ref Ref of proposal - * @param string $ref_ext Ref ext of proposal - * @return int >0 if OK, <0 if KO + * @param int $rowid id of object to load + * @param string $ref Ref of proposal + * @param string $ref_ext Ref ext of proposal + * @param int $forceentity Entity id to force + * @return int >0 if OK, <0 if KO */ - public function fetch($rowid, $ref = '', $ref_ext = '') + public function fetch($rowid, $ref = '', $ref_ext = '', $forceentity = 0) { $sql = "SELECT p.rowid, p.ref, p.entity, p.remise, p.remise_percent, p.remise_absolue, p.fk_soc"; $sql .= ", p.total_ttc, p.total_tva, p.localtax1, p.localtax2, p.total_ht"; @@ -1489,10 +1490,15 @@ class Propal extends CommonObject $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_input_reason as dr ON p.fk_input_reason = dr.rowid'; $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON p.fk_incoterms = i.rowid'; - if ($ref) { - $sql .= " WHERE p.entity IN (".getEntity('propal').")"; // Dont't use entity if you use rowid + if (!empty($ref)) { + if (!empty($forceentity)) { + $sql .= " WHERE p.entity = ".(int) $forceentity; // Check only the current entity because we may have the same reference in several entities + } else { + $sql .= " WHERE p.entity IN (".getEntity('propal').")"; + } $sql .= " AND p.ref='".$this->db->escape($ref)."'"; } else { + // Dont't use entity if you use rowid $sql .= " WHERE p.rowid = ".((int) $rowid); } diff --git a/htdocs/comm/remx.php b/htdocs/comm/remx.php index 9322100f732..8ef737bc2eb 100644 --- a/htdocs/comm/remx.php +++ b/htdocs/comm/remx.php @@ -425,12 +425,12 @@ if ($socid > 0) { print ''.$langs->trans("ConsumedBy").''; print ''.$langs->trans("AmountHT").''; if (!empty($conf->multicurrency->enabled)) { - print ''.$langs->trans("MulticurrencyAmountHT").''; + print ''.$langs->trans("MulticurrencyAmountHT").''; } print ''.$langs->trans("VATRate").''; print ''.$langs->trans("AmountTTC").''; if (!empty($conf->multicurrency->enabled)) { - print ''.$langs->trans("MulticurrencyAmountTTC").''; + print ''.$langs->trans("MulticurrencyAmountTTC").''; } print ''.$langs->trans("DiscountOfferedBy").''; print ' '; @@ -563,12 +563,12 @@ if ($socid > 0) { print ''.$langs->trans("ConsumedBy").''; print ''.$langs->trans("AmountHT").''; if (!empty($conf->multicurrency->enabled)) { - print ''.$langs->trans("MulticurrencyAmountHT").''; + print ''.$langs->trans("MulticurrencyAmountHT").''; } print ''.$langs->trans("VATRate").''; print ''.$langs->trans("AmountTTC").''; if (!empty($conf->multicurrency->enabled)) { - print ''.$langs->trans("MulticurrencyAmountTTC").''; + print ''.$langs->trans("MulticurrencyAmountTTC").''; } print ''.$langs->trans("DiscountOfferedBy").''; print ' '; @@ -736,12 +736,12 @@ if ($socid > 0) { print ''.$langs->trans("ConsumedBy").''; print ''.$langs->trans("AmountHT").''; if (!empty($conf->multicurrency->enabled)) { - print ''.$langs->trans("MulticurrencyAmountHT").''; + print ''.$langs->trans("MulticurrencyAmountHT").''; } print ''.$langs->trans("VATRate").''; print ''.$langs->trans("AmountTTC").''; if (!empty($conf->multicurrency->enabled)) { - print ''.$langs->trans("MulticurrencyAmountTTC").''; + print ''.$langs->trans("MulticurrencyAmountTTC").''; } print ''.$langs->trans("Author").''; print ' '; @@ -896,12 +896,12 @@ if ($socid > 0) { print ''.$langs->trans("ConsumedBy").''; print ''.$langs->trans("AmountHT").''; if (!empty($conf->multicurrency->enabled)) { - print ''.$langs->trans("MulticurrencyAmountHT").''; + print ''.$langs->trans("MulticurrencyAmountHT").''; } print ''.$langs->trans("VATRate").''; print ''.$langs->trans("AmountTTC").''; if (!empty($conf->multicurrency->enabled)) { - print ''.$langs->trans("MulticurrencyAmountTTC").''; + print ''.$langs->trans("MulticurrencyAmountTTC").''; } print ''.$langs->trans("Author").''; print ' '; diff --git a/htdocs/compta/facture/card.php b/htdocs/compta/facture/card.php index b31d65fdcaf..eb43da88a4b 100644 --- a/htdocs/compta/facture/card.php +++ b/htdocs/compta/facture/card.php @@ -5439,9 +5439,9 @@ if ($action == 'create') { ) { print ''.$langs->trans('ConvertToReduc').''; } - // For deposit invoice + // For down payment invoice (deposit) if ($object->type == Facture::TYPE_DEPOSIT && $usercancreate && $object->statut > Facture::STATUS_DRAFT && empty($discount->id)) { - if (price2num($object->total_ttc, 'MT') == price2num($sumofpaymentall, 'MT')) { + if (price2num($object->total_ttc, 'MT') == price2num($sumofpaymentall, 'MT') || ($object->type == Facture::STATUS_ABANDONED && in_array($object->close_code, array('bankcharge', 'discount_vat', 'other')))) { // We can close a down payment only if paid amount is same than amount of down payment (by definition) print ''.$langs->trans('ConvertToReduc').''; } else { diff --git a/htdocs/compta/facture/class/facture.class.php b/htdocs/compta/facture/class/facture.class.php index 7164c4e547a..ec8e4a93b80 100644 --- a/htdocs/compta/facture/class/facture.class.php +++ b/htdocs/compta/facture/class/facture.class.php @@ -160,7 +160,7 @@ class Facture extends CommonInvoice public $revenuestamp; /** - * ! Closing after partial payment: discount_vat, badsupplier, abandon + * ! Closing after partial payment: discount_vat, badcustomer or badsupplier, bankcharge, other * ! Closing when no payment: replaced, abandoned * @var string Close code */ @@ -417,7 +417,10 @@ class Facture extends CommonInvoice const STATUS_ABANDONED = 3; const CLOSECODE_DISCOUNTVAT = 'discount_vat'; // Abandonned remain - escompte - const CLOSECODE_BADDEBT = 'badcustomer'; // Abandonned - bad + const CLOSECODE_BADDEBT = 'badcustomer'; // Abandonned remain - bad customer + const CLOSECODE_BANKCHARGE = 'bankcharge'; // Abandonned remain - bank charge + const CLOSECODE_OTHER = 'other'; // Abandonned remain - other + const CLOSECODE_ABANDONED = 'abandon'; // Abandonned - other const CLOSECODE_REPLACED = 'replaced'; // Closed after doing a replacement invoice @@ -5075,6 +5078,7 @@ class Facture extends CommonInvoice $sql .= ", ".MAIN_DB_PREFIX."c_paiement as cp"; } $sql .= " WHERE f.paye = 0"; + $sql .= " AND f.fk_statut = ".self::STATUS_VALIDATED; $sql .= " AND f.date_lim_reglement = '".$this->db->idate($tmpidate, 'gmt')."'"; $sql .= " AND f.entity IN (".getEntity('facture').")"; if (!empty($paymentmode) && $paymentmode != 'all') { diff --git a/htdocs/compta/facture/list.php b/htdocs/compta/facture/list.php index 124560d425b..657a9a4e1d2 100644 --- a/htdocs/compta/facture/list.php +++ b/htdocs/compta/facture/list.php @@ -846,9 +846,9 @@ $sql .= ' f.rowid DESC '; $nbtotalofrecords = ''; if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) { /* This old and fast method to get and count full list returns all record so use a high amount of memory. - $result = $db->query($sql); - $nbtotalofrecords = $db->num_rows($result); - */ + $result = $db->query($sql); + $nbtotalofrecords = $db->num_rows($result); + */ /* The fast and low memory method to get and count full list converts the sql into a sql count */ if ($sall || $search_product_category > 0 || $search_user > 0) { $sqlforcount = preg_replace('/^SELECT[a-zA-Z0-9\._\s\(\),=<>\:\-\']+\sFROM/', 'SELECT COUNT(DISTINCT f.rowid) as nbtotalofrecords FROM', $sql); @@ -1078,8 +1078,8 @@ if ($resql) { $arrayofmassactions['makepayment'] = img_picto('', 'payment', 'class="pictofixedwidth"').$langs->trans("MakePaymentAndClassifyPayed"); } if ($conf->prelevement->enabled && !empty($user->rights->prelevement->bons->creer)) { - $langs->load("withdrawals"); - $arrayofmassactions['withdrawrequest'] = img_picto('', 'payment', 'class="pictofixedwidth"').$langs->trans("MakeWithdrawRequest"); + $langs->load("withdrawals"); + $arrayofmassactions['withdrawrequest'] = img_picto('', 'payment', 'class="pictofixedwidth"').$langs->trans("MakeWithdrawRequest"); } if ($user->rights->facture->supprimer) { if (!empty($conf->global->INVOICE_CAN_REMOVE_DRAFT_ONLY)) { @@ -1266,11 +1266,11 @@ if ($resql) { print ''; print '
'; /* - print $langs->trans('From').' '; - print $form->selectDate($search_datelimit_start ? $search_datelimit_start : -1, 'search_datelimit_start', 0, 0, 1); - print '
'; - print '
'; - print $langs->trans('to').' ';*/ + print $langs->trans('From').' '; + print $form->selectDate($search_datelimit_start ? $search_datelimit_start : -1, 'search_datelimit_start', 0, 0, 1); + print '
'; + print '
'; + print $langs->trans('to').' ';*/ print $form->selectDate($search_datelimit_end ? $search_datelimit_end : -1, 'search_datelimit_end', 0, 0, 1, '', 1, 0, 0, '', '', '', '', 1, '', $langs->trans("Before")); print '
'.$langs->trans("Alert"); print '
'; @@ -1686,12 +1686,12 @@ if ($resql) { $facturestatic->note_public = $obj->note_public; $facturestatic->note_private = $obj->note_private; if (!empty($conf->global->INVOICE_USE_SITUATION) && !empty($conf->global->INVOICE_USE_RETAINED_WARRANTY)) { - $facturestatic->retained_warranty = $obj->retained_warranty; - $facturestatic->retained_warranty_date_limit = $obj->retained_warranty_date_limit; - $facturestatic->situation_final = $obj->retained_warranty_date_limit; - $facturestatic->situation_final = $obj->retained_warranty_date_limit; - $facturestatic->situation_cycle_ref = $obj->situation_cycle_ref; - $facturestatic->situation_counter = $obj->situation_counter; + $facturestatic->retained_warranty = $obj->retained_warranty; + $facturestatic->retained_warranty_date_limit = $obj->retained_warranty_date_limit; + $facturestatic->situation_final = $obj->retained_warranty_date_limit; + $facturestatic->situation_final = $obj->retained_warranty_date_limit; + $facturestatic->situation_cycle_ref = $obj->situation_cycle_ref; + $facturestatic->situation_counter = $obj->situation_counter; } $companystatic->id = $obj->socid; $companystatic->name = $obj->name; @@ -1990,14 +1990,14 @@ if ($resql) { // Amount HT if (!empty($arrayfields['f.total_ht']['checked'])) { - print ''.price($obj->total_ht)."\n"; + print ''.price($obj->total_ht)."\n"; if (!$i) { $totalarray['nbfield']++; } if (!$i) { $totalarray['pos'][$totalarray['nbfield']] = 'f.total_ht'; } - $totalarray['val']['f.total_ht'] += $obj->total_ht; + $totalarray['val']['f.total_ht'] += $obj->total_ht; } // Amount VAT if (!empty($arrayfields['f.total_tva']['checked'])) { @@ -2159,16 +2159,16 @@ if ($resql) { // Currency rate if (!empty($arrayfields['f.multicurrency_tx']['checked'])) { - print ''; - $form->form_multicurrency_rate($_SERVER['PHP_SELF'].'?id='.$obj->rowid, $obj->multicurrency_tx, 'none', $obj->multicurrency_code); - print "\n"; + print ''; + $form->form_multicurrency_rate($_SERVER['PHP_SELF'].'?id='.$obj->rowid, $obj->multicurrency_tx, 'none', $obj->multicurrency_code); + print "\n"; if (!$i) { $totalarray['nbfield']++; } } // Amount HT if (!empty($arrayfields['f.multicurrency_total_ht']['checked'])) { - print ''.price($obj->multicurrency_total_ht)."\n"; + print ''.price($obj->multicurrency_total_ht)."\n"; if (!$i) { $totalarray['nbfield']++; } diff --git a/htdocs/compta/prelevement/class/bonprelevement.class.php b/htdocs/compta/prelevement/class/bonprelevement.class.php index 8cfdcf7e02b..d87317e2420 100644 --- a/htdocs/compta/prelevement/class/bonprelevement.class.php +++ b/htdocs/compta/prelevement/class/bonprelevement.class.php @@ -1488,7 +1488,7 @@ class BonPrelevement extends CommonObject fputs($this->file, ' '.$i.''.$CrLf); fputs($this->file, ' '.$this->total.''.$CrLf); fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ''))).''.$CrLf); + fputs($this->file, ' '.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ' '))).''.$CrLf); fputs($this->file, ' '.$CrLf); fputs($this->file, ' '.$CrLf); fputs($this->file, ' '.$CrLf); @@ -1604,7 +1604,7 @@ class BonPrelevement extends CommonObject fputs($this->file, ' '.$i.''.$CrLf); fputs($this->file, ' '.$this->total.''.$CrLf); fputs($this->file, ' '.$CrLf); - fputs($this->file, ' '.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ''))).''.$CrLf); + fputs($this->file, ' '.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ' '))).''.$CrLf); fputs($this->file, ' '.$CrLf); fputs($this->file, ' '.$CrLf); fputs($this->file, ' '.$CrLf); @@ -1854,16 +1854,16 @@ class BonPrelevement extends CommonObject $XML_DEBITOR .= ' '.$CrLf; $XML_DEBITOR .= ' '.$CrLf; $XML_DEBITOR .= ' '.$CrLf; - $XML_DEBITOR .= ' '.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($row_nom), ''))).''.$CrLf; + $XML_DEBITOR .= ' '.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($row_nom), ' '))).''.$CrLf; $XML_DEBITOR .= ' '.$CrLf; $XML_DEBITOR .= ' '.$row_country_code.''.$CrLf; $addressline1 = strtr($row_address, array(CHR(13) => ", ", CHR(10) => "")); $addressline2 = strtr($row_zip.(($row_zip && $row_town) ? ' ' : ''.$row_town), array(CHR(13) => ", ", CHR(10) => "")); if (trim($addressline1)) { - $XML_DEBITOR .= ' '.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline1), ''), 70, 'right', 'UTF-8', 1)).''.$CrLf; + $XML_DEBITOR .= ' '.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline1), ' '), 70, 'right', 'UTF-8', 1)).''.$CrLf; } if (trim($addressline2)) { - $XML_DEBITOR .= ' '.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline2), ''), 70, 'right', 'UTF-8', 1)).''.$CrLf; + $XML_DEBITOR .= ' '.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline2), ' '), 70, 'right', 'UTF-8', 1)).''.$CrLf; } $XML_DEBITOR .= ' '.$CrLf; $XML_DEBITOR .= ' '.$CrLf; @@ -1908,14 +1908,14 @@ class BonPrelevement extends CommonObject $XML_CREDITOR .= ' '.round($row_somme, 2).''.$CrLf; $XML_CREDITOR .= ' '.$CrLf; /* - $XML_CREDITOR .= ' '.$CrLf; - $XML_CREDITOR .= ' '.$CrLf; - $XML_CREDITOR .= ' '.$Rum.''.$CrLf; - $XML_CREDITOR .= ' '.$DtOfSgntr.''.$CrLf; - $XML_CREDITOR .= ' false'.$CrLf; - $XML_CREDITOR .= ' '.$CrLf; - $XML_CREDITOR .= ' '.$CrLf; - */ + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$Rum.''.$CrLf; + $XML_CREDITOR .= ' '.$DtOfSgntr.''.$CrLf; + $XML_CREDITOR .= ' false'.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + $XML_CREDITOR .= ' '.$CrLf; + */ //$XML_CREDITOR .= ' SLEV'.$CrLf; $XML_CREDITOR .= ' '.$CrLf; $XML_CREDITOR .= ' '.$CrLf; @@ -1923,16 +1923,16 @@ class BonPrelevement extends CommonObject $XML_CREDITOR .= ' '.$CrLf; $XML_CREDITOR .= ' '.$CrLf; $XML_CREDITOR .= ' '.$CrLf; - $XML_CREDITOR .= ' '.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($row_nom)))).''.$CrLf; + $XML_CREDITOR .= ' '.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($row_nom), ' '))).''.$CrLf; $XML_CREDITOR .= ' '.$CrLf; $XML_CREDITOR .= ' '.$row_country_code.''.$CrLf; $addressline1 = strtr($row_address, array(CHR(13) => ", ", CHR(10) => "")); $addressline2 = strtr($row_zip.(($row_zip && $row_town) ? ' ' : ''.$row_town), array(CHR(13) => ", ", CHR(10) => "")); if (trim($addressline1)) { - $XML_CREDITOR .= ' '.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline1), ''), 70, 'right', 'UTF-8', 1)).''.$CrLf; + $XML_CREDITOR .= ' '.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline1), ' '), 70, 'right', 'UTF-8', 1)).''.$CrLf; } if (trim($addressline2)) { - $XML_CREDITOR .= ' '.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline2), ''), 70, 'right', 'UTF-8', 1)).''.$CrLf; + $XML_CREDITOR .= ' '.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline2), ' '), 70, 'right', 'UTF-8', 1)).''.$CrLf; } $XML_CREDITOR .= ' '.$CrLf; $XML_CREDITOR .= ' '.$CrLf; @@ -2096,16 +2096,16 @@ class BonPrelevement extends CommonObject $XML_SEPA_INFO .= ' '.$CrLf; $XML_SEPA_INFO .= ' '.$dateTime_ETAD.''.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ''))).''.$CrLf; + $XML_SEPA_INFO .= ' '.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ' '))).''.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf; $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; $addressline1 = strtr($configuration->global->MAIN_INFO_SOCIETE_ADDRESS, array(CHR(13) => ", ", CHR(10) => "")); $addressline2 = strtr($configuration->global->MAIN_INFO_SOCIETE_ZIP.(($configuration->global->MAIN_INFO_SOCIETE_ZIP || ' '.$configuration->global->MAIN_INFO_SOCIETE_TOWN) ? ' ' : '').$configuration->global->MAIN_INFO_SOCIETE_TOWN, array(CHR(13) => ", ", CHR(10) => "")); if ($addressline1) { - $XML_SEPA_INFO .= ' '.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline1), ''), 70, 'right', 'UTF-8', 1)).''.$CrLf; + $XML_SEPA_INFO .= ' '.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline1), ' '), 70, 'right', 'UTF-8', 1)).''.$CrLf; } if ($addressline2) { - $XML_SEPA_INFO .= ' '.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline2), ''), 70, 'right', 'UTF-8', 1)).''.$CrLf; + $XML_SEPA_INFO .= ' '.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline2), ' '), 70, 'right', 'UTF-8', 1)).''.$CrLf; } $XML_SEPA_INFO .= ' '.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf; @@ -2120,11 +2120,11 @@ class BonPrelevement extends CommonObject $XML_SEPA_INFO .= ' '.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf; /* $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale)))).''.$CrLf; + $XML_SEPA_INFO .= ' '.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ' '))).''.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf; $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; - $XML_SEPA_INFO .= ' '.dolEscapeXML(dol_string_nospecial(dol_string_unaccent($conf->global->MAIN_INFO_SOCIETE_ADDRESS), '')).''.$CrLf; - $XML_SEPA_INFO .= ' '.dolEscapeXML(dol_string_nospecial(dol_string_unaccent($conf->global->MAIN_INFO_SOCIETE_ZIP.' '.$conf->global->MAIN_INFO_SOCIETE_TOWN), '')).''.$CrLf; + $XML_SEPA_INFO .= ' '.dolEscapeXML(dol_string_nospecial(dol_string_unaccent($conf->global->MAIN_INFO_SOCIETE_ADDRESS), ' ')).''.$CrLf; + $XML_SEPA_INFO .= ' '.dolEscapeXML(dol_string_nospecial(dol_string_unaccent($conf->global->MAIN_INFO_SOCIETE_ZIP.' '.$conf->global->MAIN_INFO_SOCIETE_TOWN), ' ')).''.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf;*/ $XML_SEPA_INFO .= ' SLEV'.$CrLf; // Field "Responsible of fees". Must be SLEV @@ -2162,16 +2162,16 @@ class BonPrelevement extends CommonObject } $XML_SEPA_INFO .= ' '.dol_print_date($dateTime_ETAD, 'dayrfc').''.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ''))).''.$CrLf; + $XML_SEPA_INFO .= ' '.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ' '))).''.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf; $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; $addressline1 = strtr($configuration->global->MAIN_INFO_SOCIETE_ADDRESS, array(CHR(13) => ", ", CHR(10) => "")); $addressline2 = strtr($configuration->global->MAIN_INFO_SOCIETE_ZIP.(($configuration->global->MAIN_INFO_SOCIETE_ZIP || ' '.$configuration->global->MAIN_INFO_SOCIETE_TOWN) ? ' ' : '').$configuration->global->MAIN_INFO_SOCIETE_TOWN, array(CHR(13) => ", ", CHR(10) => "")); if ($addressline1) { - $XML_SEPA_INFO .= ' '.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline1), ''), 70, 'right', 'UTF-8', 1)).''.$CrLf; + $XML_SEPA_INFO .= ' '.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline1), ' '), 70, 'right', 'UTF-8', 1)).''.$CrLf; } if ($addressline2) { - $XML_SEPA_INFO .= ' '.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline2), ''), 70, 'right', 'UTF-8', 1)).''.$CrLf; + $XML_SEPA_INFO .= ' '.dolEscapeXML(dol_trunc(dol_string_nospecial(dol_string_unaccent($addressline2), ' '), 70, 'right', 'UTF-8', 1)).''.$CrLf; } $XML_SEPA_INFO .= ' '.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf; @@ -2186,26 +2186,26 @@ class BonPrelevement extends CommonObject $XML_SEPA_INFO .= ' '.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf; /* $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale)))).''.$CrLf; + $XML_SEPA_INFO .= ' '.dolEscapeXML(strtoupper(dol_string_nospecial(dol_string_unaccent($this->raison_sociale), ' '))).''.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf; $XML_SEPA_INFO .= ' '.$country[1].''.$CrLf; - $XML_SEPA_INFO .= ' '.dolEscapeXML(dol_string_nospecial(dol_string_unaccent($conf->global->MAIN_INFO_SOCIETE_ADDRESS), '')).''.$CrLf; - $XML_SEPA_INFO .= ' '.dolEscapeXML(dol_string_nospecial(dol_string_unaccent($conf->global->MAIN_INFO_SOCIETE_ZIP.' '.$conf->global->MAIN_INFO_SOCIETE_TOWN), '')).''.$CrLf; + $XML_SEPA_INFO .= ' '.dolEscapeXML(dol_string_nospecial(dol_string_unaccent($conf->global->MAIN_INFO_SOCIETE_ADDRESS), ' ')).''.$CrLf; + $XML_SEPA_INFO .= ' '.dolEscapeXML(dol_string_nospecial(dol_string_unaccent($conf->global->MAIN_INFO_SOCIETE_ZIP.' '.$conf->global->MAIN_INFO_SOCIETE_TOWN), ' ')).''.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf; $XML_SEPA_INFO .= ' '.$CrLf;*/ $XML_SEPA_INFO .= ' SLEV'.$CrLf; // Field "Responsible of fees". Must be SLEV /*$XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$this->emetteur_ics.''.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' SEPA'.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf; - $XML_SEPA_INFO .= ' '.$CrLf;*/ + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$this->emetteur_ics.''.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' SEPA'.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf; + $XML_SEPA_INFO .= ' '.$CrLf;*/ } } else { fputs($this->file, 'INCORRECT EMETTEUR '.$XML_SEPA_INFO.$CrLf); @@ -2343,59 +2343,59 @@ class BonPrelevement extends CommonObject } /* - if ($mode == 'direct_debit') { - $sql = "SELECT b.rowid, f.datedue as datefin"; - $sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; - $sql .= " WHERE f.entity IN (".getEntity('facture').")"; - $sql .= " AND f.total_ttc > 0"; - } else { - $sql = "SELECT b.rowid, f.datedue as datefin"; - $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; - $sql .= " WHERE f.entity IN (".getEntity('facture_fourn').")"; - $sql .= " AND f.total_ttc > 0"; - } + if ($mode == 'direct_debit') { + $sql = "SELECT b.rowid, f.datedue as datefin"; + $sql .= " FROM ".MAIN_DB_PREFIX."facture as f"; + $sql .= " WHERE f.entity IN (".getEntity('facture').")"; + $sql .= " AND f.total_ttc > 0"; + } else { + $sql = "SELECT b.rowid, f.datedue as datefin"; + $sql .= " FROM ".MAIN_DB_PREFIX."facture_fourn as f"; + $sql .= " WHERE f.entity IN (".getEntity('facture_fourn').")"; + $sql .= " AND f.total_ttc > 0"; + } - $resql = $this->db->query($sql); - if ($resql) { - $langs->load("banks"); - $now = dol_now(); + $resql = $this->db->query($sql); + if ($resql) { + $langs->load("banks"); + $now = dol_now(); - $response = new WorkboardResponse(); - if ($mode == 'direct_debit') { - $response->warning_delay = $conf->prelevement->warning_delay / 60 / 60 / 24; - $response->label = $langs->trans("PendingDirectDebitToComplete"); - $response->labelShort = $langs->trans("PendingDirectDebitToCompleteShort"); - $response->url = DOL_URL_ROOT.'/compta/prelevement/index.php?leftmenu=checks&mainmenu=bank'; - } else { - $response->warning_delay = $conf->paymentbybanktransfer->warning_delay / 60 / 60 / 24; - $response->label = $langs->trans("PendingCreditTransferToComplete"); - $response->labelShort = $langs->trans("PendingCreditTransferToCompleteShort"); - $response->url = DOL_URL_ROOT.'/compta/paymentbybanktransfer/index.php?leftmenu=checks&mainmenu=bank'; - } - $response->img = img_object('', "payment"); + $response = new WorkboardResponse(); + if ($mode == 'direct_debit') { + $response->warning_delay = $conf->prelevement->warning_delay / 60 / 60 / 24; + $response->label = $langs->trans("PendingDirectDebitToComplete"); + $response->labelShort = $langs->trans("PendingDirectDebitToCompleteShort"); + $response->url = DOL_URL_ROOT.'/compta/prelevement/index.php?leftmenu=checks&mainmenu=bank'; + } else { + $response->warning_delay = $conf->paymentbybanktransfer->warning_delay / 60 / 60 / 24; + $response->label = $langs->trans("PendingCreditTransferToComplete"); + $response->labelShort = $langs->trans("PendingCreditTransferToCompleteShort"); + $response->url = DOL_URL_ROOT.'/compta/paymentbybanktransfer/index.php?leftmenu=checks&mainmenu=bank'; + } + $response->img = img_object('', "payment"); - while ($obj = $this->db->fetch_object($resql)) { - $response->nbtodo++; + while ($obj = $this->db->fetch_object($resql)) { + $response->nbtodo++; - if ($this->db->jdate($obj->datefin) < ($now - $conf->withdraw->warning_delay)) { - $response->nbtodolate++; - } - } + if ($this->db->jdate($obj->datefin) < ($now - $conf->withdraw->warning_delay)) { + $response->nbtodolate++; + } + } - $response->nbtodo = 0; - $response->nbtodolate = 0; - // Return workboard only if quantity is not 0 - if ($response->nbtodo) { - return $response; - } else { - return 0; - } - } else { - dol_print_error($this->db); - $this->error = $this->db->error(); - return -1; - } - */ + $response->nbtodo = 0; + $response->nbtodolate = 0; + // Return workboard only if quantity is not 0 + if ($response->nbtodo) { + return $response; + } else { + return 0; + } + } else { + dol_print_error($this->db); + $this->error = $this->db->error(); + return -1; + } + */ return 0; } } diff --git a/htdocs/compta/prelevement/list.php b/htdocs/compta/prelevement/list.php index ae92286dfec..d9cb6f6fb7d 100644 --- a/htdocs/compta/prelevement/list.php +++ b/htdocs/compta/prelevement/list.php @@ -1,8 +1,9 @@ - * Copyright (C) 2005-2016 Laurent Destailleur - * Copyright (C) 2005-2009 Regis Houssin - * Copyright (C) 2010-2018 Juanjo Menent +/* Copyright (C) 2005 Rodolphe Quiedeville + * Copyright (C) 2005-2016 Laurent Destailleur + * Copyright (C) 2005-2009 Regis Houssin + * Copyright (C) 2010-2018 Juanjo Menent + * Copyright (C) 2022 Alexandre Spangaro * * 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 @@ -108,7 +109,7 @@ llxHeader('', $langs->trans("WithdrawalsLines")); $sql = "SELECT p.rowid, p.ref, p.statut as status, p.datec"; $sql .= " , f.rowid as facid, f.ref as invoiceref, f.total_ttc"; -$sql .= " , s.rowid as socid, s.nom as name, s.code_client, s.email"; +$sql .= " , s.rowid as socid, s.nom as name, s.code_client, s.code_fournisseur, s.email"; $sql .= " , pl.amount, pl.statut as statut_ligne, pl.rowid as rowid_ligne"; $sql .= " FROM ".MAIN_DB_PREFIX."prelevement_bons as p"; $sql .= " , ".MAIN_DB_PREFIX."prelevement_lignes as pl"; @@ -139,7 +140,7 @@ if ($search_bon) { } if ($type == 'bank-transfer') { if ($search_code) { - $sql .= natural_search("s.code_fourn", $search_code); + $sql .= natural_search("s.code_fournisseur", $search_code); } } else { if ($search_code) { @@ -172,6 +173,9 @@ if ($result) { $param = "&statut=".urlencode($statut); $param .= "&search_bon=".urlencode($search_bon); + if ($type == 'bank-transfer') { + $param .= '&type=bank-transfer'; + } if ($limit > 0 && $limit != $conf->liste_limit) { $param .= '&limit='.urlencode($limit); } @@ -204,7 +208,7 @@ if ($result) { print ''; print ' '; print ''; - print ''; + print ''; print ' '; print ' '; print ''; @@ -214,8 +218,12 @@ if ($result) { print ''; $columntitle = "WithdrawalsReceipts"; + $columntitlethirdparty = "CustomerCode"; + $columncodethirdparty = "s.code_client"; if ($type == 'bank-transfer') { $columntitle = "BankTransferReceipts"; + $columntitlethirdparty = "SupplierCode"; + $columncodethirdparty = "s.code_fournisseur"; } print ''; @@ -223,7 +231,7 @@ if ($result) { print_liste_field_titre("Line", $_SERVER["PHP_SELF"], '', '', $param, '', $sortfield, $sortorder); print_liste_field_titre("Bill", $_SERVER["PHP_SELF"], "f.ref", '', $param, '', $sortfield, $sortorder); print_liste_field_titre("Company", $_SERVER["PHP_SELF"], "s.nom", '', $param, '', $sortfield, $sortorder); - print_liste_field_titre("CustomerCode", $_SERVER["PHP_SELF"], "s.code_client", '', $param, '', $sortfield, $sortorder, 'center '); + print_liste_field_titre($columntitlethirdparty, $_SERVER["PHP_SELF"], $columncodethirdparty, '', $param, '', $sortfield, $sortorder, 'center '); print_liste_field_titre("Date", $_SERVER["PHP_SELF"], "p.datec", "", $param, '', $sortfield, $sortorder, 'center '); print_liste_field_titre("Amount", $_SERVER["PHP_SELF"], "pl.amount", "", $param, '', $sortfield, $sortorder, 'right '); print_liste_field_titre(''); @@ -256,9 +264,17 @@ if ($result) { print ''; print ''; - print ''; - print img_object($langs->trans("ShowBill"), "bill"); - print ' '.$obj->invoiceref."\n"; + $link_to_bill = '/compta/facture/card.php?facid='; + $link_title = 'Invoice'; + $link_picto = 'bill'; + if ($type == 'bank-transfer') { + $link_to_bill = '/fourn/facture/card.php?facid='; + $link_title = 'SupplierInvoice'; + $link_picto = 'supplier_invoice'; + } + print ''; + print img_object($langs->trans($link_title), $link_picto); + print ' '.$obj->invoiceref."\n"; print ''; print ''; @@ -266,7 +282,15 @@ if ($result) { print $company->getNomUrl(1); print "\n"; - print ''.$obj->code_client."\n"; + + print ''; + $link_to_tab = '/comm/card.php?socid='; + $link_code = $obj->code_client; + if ($type == 'bank-transfer') { + $link_to_tab = '/fourn/card.php?socid='; + $link_code = $obj->code_fournisseur; + } + print ''.$link_code."\n"; print ''.dol_print_date($db->jdate($obj->datec), 'day')."\n"; diff --git a/htdocs/compta/prelevement/orders_list.php b/htdocs/compta/prelevement/orders_list.php index c80acb39f8e..ee370b9532e 100644 --- a/htdocs/compta/prelevement/orders_list.php +++ b/htdocs/compta/prelevement/orders_list.php @@ -132,6 +132,9 @@ if ($result) { if (!empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) { $param .= '&contextpage='.urlencode($contextpage); } + if ($type == 'bank-transfer') { + $param .= '&type=bank-transfer'; + } if ($limit > 0 && $limit != $conf->liste_limit) { $param .= '&limit='.urlencode($limit); } diff --git a/htdocs/core/actions_massactions.inc.php b/htdocs/core/actions_massactions.inc.php index b98ce37d8f1..c2d1f7344c4 100644 --- a/htdocs/core/actions_massactions.inc.php +++ b/htdocs/core/actions_massactions.inc.php @@ -74,6 +74,7 @@ if (!$error && $massaction == 'confirm_presend') { $nbignored = 0; $langs->load("mails"); include_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + include_once DOL_DOCUMENT_ROOT.'/core/lib/signature.lib.php'; $listofobjectid = array(); $listofobjectthirdparties = array(); @@ -642,6 +643,8 @@ if ($massaction == 'confirm_createbills') { // Create bills from orders. $db->begin(); + $nbOrders = is_array($orders) ? count($orders) : 1; + foreach ($orders as $id_order) { $cmd = new Commande($db); if ($cmd->fetch($id_order) <= 0) { @@ -774,6 +777,8 @@ if ($massaction == 'confirm_createbills') { // Create bills from orders. $objecttmp->context['createfromclone']; + $rankedLine = ($nbOrders > 1) ? -1 : $lines[$i]->rang; + $result = $objecttmp->addline( $desc, $lines[$i]->subprice, @@ -791,7 +796,9 @@ if ($massaction == 'confirm_createbills') { // Create bills from orders. 'HT', 0, $product_type, - $lines[$i]->rang, + //we have define the max rank for each line which makes it possible not to have a duplicate on the rank field in the case of several orders + //-1 will give us the right number + $rankedLine, // rank $lines[$i]->special_code, $objecttmp->origin, $lines[$i]->rowid, diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 5fc162634a8..e51409ef81b 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -1759,7 +1759,7 @@ class ExtraFields } } } - $value = '
    '.implode(' ', $toprint).'
'; + if (!empty($toprint)) $value = '
    '.implode(' ', $toprint).'
'; } else { dol_syslog(get_class($this).'::showOutputField error '.$this->db->lasterror(), LOG_WARNING); } @@ -1950,7 +1950,7 @@ class ExtraFields if (!empty($onlykey) && $onlykey != '@GETPOSTISSET' && $key != $onlykey) { continue; } - if (!empty($onlykey) && $onlykey == '@GETPOSTISSET' && !GETPOSTISSET('options_'.$key) && $this->attributes[$object->table_element]['type'][$key] != 'boolean') { + if (!empty($onlykey) && $onlykey == '@GETPOSTISSET' && !GETPOSTISSET('options_'.$key) && (! in_array($this->attributes[$object->table_element]['type'][$key], array('boolean', 'chkbxlst')))) { //when unticking boolean field, it's not set in POST continue; } diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index 6b3ced3e621..6be210d507f 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -843,12 +843,12 @@ function show_projects($conf, $langs, $db, $object, $backtopage = '', $nocreatel print ''; // Ref - print ''; + print ''; print $projecttmp->getNomUrl(1); print ''; // Label - print ''.$obj->title.''; + print ''.dol_escape_htmltag($obj->title).''; // Date start print ''.dol_print_date($db->jdate($obj->do), "day").''; // Date end diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index ffc88c157ff..8bc9a453ab2 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -5187,9 +5187,10 @@ function print_fleche_navigation($page, $file, $options = '', $nextpage = 0, $be * @param boolean $addpercent Add a percent % sign in output * @param int $info_bits Miscellaneous information on vat (0=Default, 1=French NPR vat) * @param int $usestarfornpr -1=Never show, 0 or 1=Use '*' for NPR vat rates + * @param int $html Used for html output * @return string String with formated amounts ('19,6' or '19,6%' or '8.5% (NPR)' or '8.5% *' or '19,6 (CODEX)') */ -function vatrate($rate, $addpercent = false, $info_bits = 0, $usestarfornpr = 0) +function vatrate($rate, $addpercent = false, $info_bits = 0, $usestarfornpr = 0, $html = 0) { $morelabel = ''; @@ -5197,9 +5198,11 @@ function vatrate($rate, $addpercent = false, $info_bits = 0, $usestarfornpr = 0) $rate = str_replace('%', '', $rate); $addpercent = true; } + $reg = array(); if (preg_match('/\((.*)\)/', $rate, $reg)) { $morelabel = ' ('.$reg[1].')'; $rate = preg_replace('/\s*'.preg_quote($morelabel, '/').'/', '', $rate); + $morelabel = ' '.($html ? '' : '').'('.$reg[1].')'.($html ? '' : ''); } if (preg_match('/\*/', $rate)) { $rate = str_replace('*', '', $rate); diff --git a/htdocs/core/lib/invoice.lib.php b/htdocs/core/lib/invoice.lib.php index c64c63fc0dd..552658f091d 100644 --- a/htdocs/core/lib/invoice.lib.php +++ b/htdocs/core/lib/invoice.lib.php @@ -1165,6 +1165,7 @@ function getCustomerInvoiceUnpaidOpenTable($maxCount = 500, $socid = 0) $i++; $total += $obj->total_ht; $total_ttc += $obj->total_ttc; + $totalam += $obj->am; continue; } diff --git a/htdocs/core/lib/signature.lib.php b/htdocs/core/lib/signature.lib.php index c57807800d7..6a8d824872d 100644 --- a/htdocs/core/lib/signature.lib.php +++ b/htdocs/core/lib/signature.lib.php @@ -26,7 +26,7 @@ */ function showOnlineSignatureUrl($type, $ref) { - global $conf, $langs; + global $langs; // Load translation files required by the page $langs->loadLangs(array("payment", "paybox")); @@ -59,7 +59,8 @@ function showOnlineSignatureUrl($type, $ref) */ function getOnlineSignatureUrl($mode, $type, $ref = '', $localorexternal = 1) { - global $conf, $db, $langs, $dolibarr_main_url_root; + global $conf, $dolibarr_main_url_root; + global $object; $ref = str_replace(' ', '', $ref); $out = ''; @@ -90,7 +91,7 @@ function getOnlineSignatureUrl($mode, $type, $ref = '', $localorexternal = 1) if ($mode == 1) { $out .= "hash('".$securekeyseed."' + '".$type."' + proposal_ref)"; } else { - $out .= '&securekey='.dol_hash($securekeyseed.$type.$ref, '0'); + $out .= '&securekey='.dol_hash($securekeyseed.$type.$ref.$object->entity, '0'); } /* if ($mode == 1) { @@ -120,7 +121,7 @@ function getOnlineSignatureUrl($mode, $type, $ref = '', $localorexternal = 1) // For multicompany if (!empty($out) && !empty($conf->multicompany->enabled)) { - $out .= "&entity=".$conf->entity; // Check the entity because we may have the same reference in several entities + $out .= "&entity=".$object->entity; // Check the entity of object because we may have the same reference in several entities } return $out; diff --git a/htdocs/core/modules/modIncoterm.class.php b/htdocs/core/modules/modIncoterm.class.php index 9ef50fe3aac..ffa71e9cbf6 100644 --- a/htdocs/core/modules/modIncoterm.class.php +++ b/htdocs/core/modules/modIncoterm.class.php @@ -93,7 +93,8 @@ class modIncoterm extends DolibarrModules 'tabfieldvalue'=>array("code,libelle"), // List of fields (list of fields to edit a record) 'tabfieldinsert'=>array("code,libelle"), // List of fields (list of fields for insert) 'tabrowid'=>array("rowid"), // Name of columns with primary key (try to always name it 'rowid') - 'tabcond'=>array($conf->incoterm->enabled) + 'tabcond'=>array($conf->incoterm->enabled), + 'tabhelp' => array(array()) ); $this->boxes = array(); // List of boxes diff --git a/htdocs/core/modules/modPartnership.class.php b/htdocs/core/modules/modPartnership.class.php index aab042ba386..ecc60d3429e 100644 --- a/htdocs/core/modules/modPartnership.class.php +++ b/htdocs/core/modules/modPartnership.class.php @@ -231,7 +231,8 @@ class modPartnership extends DolibarrModules // Name of columns with primary key (try to always name it 'rowid') 'tabrowid'=>array("rowid"), // Condition to show each dictionary - 'tabcond'=>array($conf->partnership->enabled) + 'tabcond'=>array($conf->partnership->enabled), + 'tabhelp' => array(array()) ); // Boxes/Widgets diff --git a/htdocs/core/modules/modResource.class.php b/htdocs/core/modules/modResource.class.php index da1fdcbf016..eb237702c93 100644 --- a/htdocs/core/modules/modResource.class.php +++ b/htdocs/core/modules/modResource.class.php @@ -239,22 +239,26 @@ class modResource extends DolibarrModules $this->export_code[$r] = $this->rights_class.'_'.$r; $this->export_label[$r] = "ResourceSingular"; // Translation key (used only if key ExportDataset_xxx_z not found) $this->export_permission[$r] = array(array("resource", "read")); - $this->export_fields_array[$r] = array('r.rowid'=>'IdResource', 'r.ref'=>'ResourceFormLabel_ref', 'c.code'=>'ResourceTypeCode', 'c.label'=>'ResourceType', 'r.description'=>'ResourceFormLabel_description', 'r.note_private'=>"NotePrivate", 'r.note_public'=>"NotePublic", 'r.asset_number'=>'AssetNumber', 'r.datec'=>"DateCreation", 'r.tms'=>"DateLastModification"); + + $this->export_fields_array[$r] = array('r.rowid'=>'IdResource', 'r.ref'=>'ResourceFormLabel_ref', 'c.rowid'=>'ResourceTypeID', 'c.code'=>'ResourceTypeCode', 'c.label'=>'ResourceTypeLabel', 'r.description'=>'ResourceFormLabel_description', 'r.note_private'=>"NotePrivate", 'r.note_public'=>"NotePublic", 'r.asset_number'=>'AssetNumber', 'r.datec'=>"DateCreation", 'r.tms'=>"DateLastModification"); $this->export_TypeFields_array[$r] = array('r.rowid'=>'List:resource:ref', 'r.ref'=>'Text', 'r.asset_number'=>'Text', 'r.description'=>'Text', 'c.code'=>'Text', 'c.label'=>'List:c_type_resource:label', 'r.datec'=>'Date', 'r.tms'=>'Date', 'r.note_private'=>'Text', 'r.note_public'=>'Text'); $this->export_entities_array[$r] = array('r.rowid'=>'resource', 'r.ref'=>'resource', 'c.code'=>'resource', 'c.label'=>'resource', 'r.description'=>'resource', 'r.note_private'=>"resource", 'r.resource'=>"resource", 'r.asset_number'=>'resource', 'r.datec'=>"resource", 'r.tms'=>"resource"); + $keyforselect = 'resource'; $keyforelement = 'resource'; $keyforaliasextra = 'extra'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; $this->export_dependencies_array[$r] = array('resource'=>array('r.rowid')); // We must keep this until the aggregate_array is used. To add unique key if we ask a field of a child to avoid the DISTINCT to discard them. $this->export_sql_start[$r] = 'SELECT DISTINCT '; $this->export_sql_end[$r] = ' FROM '.MAIN_DB_PREFIX.'resource as r'; - $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_type_resource as c ON c.rowid=r.fk_code_type_resource'; + $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_type_resource as c ON c.code = r.fk_code_type_resource'; $this->export_sql_end[$r] .= ' LEFT JOIN '.MAIN_DB_PREFIX.'resource_extrafields as extra ON extra.fk_object = r.rowid'; $this->export_sql_end[$r] .= ' WHERE r.entity IN ('.getEntity('resource').')'; + // Imports //-------- $r = 0; diff --git a/htdocs/expedition/shipment.php b/htdocs/expedition/shipment.php index bfa48e9aa0f..3f3608a946c 100644 --- a/htdocs/expedition/shipment.php +++ b/htdocs/expedition/shipment.php @@ -611,7 +611,7 @@ if ($id > 0 || !empty($ref)) { * Lines or orders with quantity shipped and remain to ship * Note: Qty shipped are already available into $object->expeditions[fk_product] */ - print ''; + print '
'; $sql = "SELECT cd.rowid, cd.fk_product, cd.product_type as type, cd.label, cd.description,"; $sql .= " cd.price, cd.tva_tx, cd.subprice,"; @@ -636,18 +636,19 @@ if ($id > 0 || !empty($ref)) { if ($resql) { $num = $db->num_rows($resql); $i = 0; - + print ''; print ''; - print ''; - print ''; - print ''; - print ''; + print ''; + print ''; + print ''; + print ''; if (!empty($conf->stock->enabled)) { - print ''; + print ''; } else { - print ''; + print ''; } print "\n"; + print ''; $toBeShipped = array(); $toBeShippedTotal = 0; diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index 2e811445c90..8770c23ce42 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -263,7 +263,7 @@ if (empty($reshook)) { if ((empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->expensereport->creer)) || (!empty($conf->global->MAIN_USE_ADVANCED_PERMS) && empty($user->rights->expensereport->creer) && empty($user->rights->expensereport->writeall_advance))) { $error++; - setEventMessages($langs->trans("NotEnoughPermission"), null, 'errors'); + setEventMessages($langs->trans("NotEnoughPermissions"), null, 'errors'); } if (!$error) { if (empty($conf->global->MAIN_USE_ADVANCED_PERMS) || empty($user->rights->expensereport->writeall_advance)) { diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php index 760c25e4db8..ed03f603a18 100644 --- a/htdocs/expensereport/list.php +++ b/htdocs/expensereport/list.php @@ -482,7 +482,7 @@ if ($resql) { if ($canedit) { print ''.$langs->trans("AddTrip").''; } else { - print ''.$langs->trans("AddTrip").''; + print ''.$langs->trans("AddTrip").''; } print ''; diff --git a/htdocs/fourn/class/fournisseur.product.class.php b/htdocs/fourn/class/fournisseur.product.class.php index 6b11d31c2ff..d1ca876b7cc 100644 --- a/htdocs/fourn/class/fournisseur.product.class.php +++ b/htdocs/fourn/class/fournisseur.product.class.php @@ -960,7 +960,7 @@ class ProductFournisseur extends Product public function display_price_product_fournisseur($showunitprice = 1, $showsuptitle = 1, $maxlen = 0, $notooltip = 0, $productFournList = array()) { // phpcs:enable - global $langs; + global $conf, $langs; $out = ''; $langs->load("suppliers"); @@ -978,7 +978,7 @@ class ProductFournisseur extends Product } $out .= '
'.$langs->trans("Description").''.$langs->trans("QtyOrdered").''.$langs->trans("QtyShipped").''.$langs->trans("KeepToShip").''.$langs->trans("Description").''.$langs->trans("QtyOrdered").''.$langs->trans("QtyShipped").''.$langs->trans("KeepToShip").''.$langs->trans("RealStock").''.$langs->trans("RealStock").'  
'; } else { - $out = ($showunitprice ? price($this->fourn_unitprice * (1 - $this->fourn_remise_percent / 100) + $this->fourn_remise).' '.$langs->trans("HT").'   (' : ''); + $out = ($showunitprice ? price($this->fourn_unitprice * (1 - $this->fourn_remise_percent / 100) + $this->fourn_remise, 0, $langs, 1, -1, -1, $conf->currency).' '.$langs->trans("HT").'   (' : ''); $out .= ($showsuptitle ? ''.$langs->trans("Supplier").': ' : '').$this->getSocNomUrl(1, 'supplier', $maxlen, $notooltip).' / '.$langs->trans("SupplierRef").': '.$this->ref_supplier; $out .= ($showunitprice ? ')' : ''); } diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index 35e5257fce0..b9d6e199015 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -590,7 +590,7 @@ if (empty($reshook)) { $localtax1_tx, $localtax2_tx, $idprod, - 0, // We already have the $idprod always defined + $productsupplier->product_fourn_price_id, $ref_supplier, $remise_percent, $price_base_type, @@ -2665,7 +2665,7 @@ if ($action == 'create') { $delallowed = $usercancreate; $modelpdf = (!empty($object->model_pdf) ? $object->model_pdf : (empty($conf->global->COMMANDE_SUPPLIER_ADDON_PDF) ? '' : $conf->global->COMMANDE_SUPPLIER_ADDON_PDF)); - print $formfile->showdocuments('commande_fournisseur', $objref, $filedir, $urlsource, $genallowed, $delallowed, $modelpdf, 1, 0, 0, 0, 0, '', '', '', $object->thirdparty->default_lang); + print $formfile->showdocuments('commande_fournisseur', $objref, $filedir, $urlsource, $genallowed, $delallowed, $modelpdf, 1, 0, 0, 0, 0, '', '', '', $object->thirdparty->default_lang, '', $object); $somethingshown = $formfile->numoffiles; // Show links to link elements diff --git a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql index 2ec43548bb6..44b1a6b5185 100644 --- a/htdocs/install/mysql/migration/13.0.0-14.0.0.sql +++ b/htdocs/install/mysql/migration/13.0.0-14.0.0.sql @@ -85,7 +85,8 @@ UPDATE llx_const set value = __ENCRYPT('eldy')__ WHERE __DECRYPT('value')__ = 'c DELETE FROM llx_user_param where param = 'MAIN_THEME' and value in ('auguria', 'amarok', 'cameleo'); ALTER TABLE llx_product_fournisseur_price ADD COLUMN packaging real DEFAULT NULL; -ALTER TABLE llx_product_fournisseur_price MODIFY COLUMN packaging real DEFAULT NULL; +-- VMYSQL4.3 ALTER TABLE llx_product_fournisseur_price MODIFY COLUMN packaging real DEFAULT NULL; +-- VPGSQL8.2 ALTER TABLE llx_product_fournisseur_price MODIFY COLUMN packaging real DEFAULT NULL USING packaging::real; -- For v14 diff --git a/htdocs/langs/en_US/main.lang b/htdocs/langs/en_US/main.lang index 6cb069d53c3..b31a8335fb5 100644 --- a/htdocs/langs/en_US/main.lang +++ b/htdocs/langs/en_US/main.lang @@ -344,7 +344,7 @@ KiloBytes=Kilobytes MegaBytes=Megabytes GigaBytes=Gigabytes TeraBytes=Terabytes -UserAuthor=Ceated by +UserAuthor=Created by UserModif=Updated by b=b. Kb=Kb @@ -709,6 +709,7 @@ FeatureDisabled=Feature disabled MoveBox=Move widget Offered=Offered NotEnoughPermissions=You don't have permission for this action +UserNotInHierachy=This action is reserved to the supervisors of this user SessionName=Session name Method=Method Receive=Receive diff --git a/htdocs/langs/fr_FR/bills.lang b/htdocs/langs/fr_FR/bills.lang index d1a0dbbbe92..a250e2f383e 100644 --- a/htdocs/langs/fr_FR/bills.lang +++ b/htdocs/langs/fr_FR/bills.lang @@ -81,14 +81,14 @@ PaymentsReports=Rapports de règlements PaymentsAlreadyDone=Versements déjà effectués PaymentsBackAlreadyDone=Remboursements déjà effectués PaymentRule=Mode de paiement -PaymentMode=Payment method -PaymentModes=Payment methods -DefaultPaymentMode=Default Payment method +PaymentMode=Mode de règlement +PaymentModes=Modes de règlement +DefaultPaymentMode=Mode de règlement par défaut DefaultBankAccount=Compte bancaire par défaut -IdPaymentMode=Payment method (id) -CodePaymentMode=Payment method (code) -LabelPaymentMode=Payment method (label) -PaymentModeShort=Payment method +IdPaymentMode=Mode de règlement (id) +CodePaymentMode=Mode de règlement (code) +LabelPaymentMode=Mode de règlement (label) +PaymentModeShort=Mode règlement PaymentTerm=Condition de règlement PaymentConditions=Conditions de règlement PaymentConditionsShort=Conditions de règlement diff --git a/htdocs/main.inc.php b/htdocs/main.inc.php index 1d09b9f9887..b97312859b9 100644 --- a/htdocs/main.inc.php +++ b/htdocs/main.inc.php @@ -130,7 +130,7 @@ function testSqlAndScriptInject($val, $type) $inj += preg_match('/user\s*\(/i', $val); // avoid to use function user() or mysql_user() that return current database login $inj += preg_match('/information_schema/i', $val); // avoid to use request that read information_schema database $inj += preg_match('/array("rowid", "rowid", "rowid"), // Condition to show each dictionary - 'tabcond'=>array($conf->mymodule->enabled, $conf->mymodule->enabled, $conf->mymodule->enabled) + 'tabcond'=>array($conf->mymodule->enabled, $conf->mymodule->enabled, $conf->mymodule->enabled), + // Tooltip for every fields of dictionaries: DO NOT PUT AN EMPTY ARRAY + 'tabhelp'=>array(array('field1' => 'field1tooltip', 'field2' => 'field2tooltip'), array('field1' => 'field1tooltip', 'field2' => 'field2tooltip'), ...), + ); */ diff --git a/htdocs/product/inventory/inventory.php b/htdocs/product/inventory/inventory.php index 6a6d4c345ce..fd82300fdda 100644 --- a/htdocs/product/inventory/inventory.php +++ b/htdocs/product/inventory/inventory.php @@ -103,6 +103,7 @@ if ($cancel) { $action = ''; } + $parameters = array(); $reshook = $hookmanager->executeHooks('doActions', $parameters, $object, $action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) { diff --git a/htdocs/product/price.php b/htdocs/product/price.php index ab3086bfd0b..e83816b84ce 100644 --- a/htdocs/product/price.php +++ b/htdocs/product/price.php @@ -1177,7 +1177,7 @@ if (!empty($conf->global->PRODUIT_MULTIPRICES) || !empty($conf->global->PRODUIT_ if (empty($positiverates)) { $positiverates = '0'; } - echo vatrate($positiverates.($object->default_vat_code ? ' ('.$object->default_vat_code.')' : ''), '%', $object->tva_npr); + echo vatrate($positiverates.($object->default_vat_code ? ' ('.$object->default_vat_code.')' : ''), '%', $object->tva_npr, 0, 1); /* if ($object->default_vat_code) { diff --git a/htdocs/product/stock/replenish.php b/htdocs/product/stock/replenish.php index 51836c75715..86b91f73e2b 100644 --- a/htdocs/product/stock/replenish.php +++ b/htdocs/product/stock/replenish.php @@ -137,7 +137,7 @@ if ($reshook < 0) { * Actions */ -if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha') || GETPOST('valid')) { // Both test are required to be compatible with all browsers +if (GETPOST('button_removefilter_x', 'alpha') || GETPOST('button_removefilter.x', 'alpha') || GETPOST('button_removefilter', 'alpha')) { // Both test are required to be compatible with all browsers $search_ref = ''; $search_label = ''; $sall = ''; @@ -669,6 +669,8 @@ if ($search_ref || $search_label || $sall || $salert || $draftorder || GETPOST(' if ($limit > 0 && $limit != $conf->liste_limit) { $filters .= '&limit='.urlencode($limit); } +if (!empty($includeproductswithoutdesiredqty)) $filters .= '&includeproductswithoutdesiredqty='.urlencode($includeproductswithoutdesiredqty); +if (!empty($salert)) $filters .= '&salert='.urlencode($salert); $param = (isset($type) ? '&type='.urlencode($type) : ''); $param .= '&fourn_id='.urlencode($fourn_id).'&search_label='.urlencode($search_label).'&includeproductswithoutdesiredqty='.urlencode($includeproductswithoutdesiredqty).'&salert='.urlencode($salert).'&draftorder='.urlencode($draftorder); @@ -676,6 +678,8 @@ $param .= '&search_ref='.urlencode($search_ref); $param .= '&mode='.urlencode($mode); $param .= '&fk_supplier='.urlencode($fk_supplier); $param .= '&fk_entrepot='.urlencode($fk_entrepot); +if (!empty($includeproductswithoutdesiredqty)) $param .= '&includeproductswithoutdesiredqty='.urlencode($includeproductswithoutdesiredqty); +if (!empty($salert)) $param .= '&salert='.urlencode($salert); $stocklabel = $langs->trans('Stock'); $stocklabelbis = $langs->trans('Stock'); diff --git a/htdocs/projet/tasks/list.php b/htdocs/projet/tasks/list.php index 697969c6060..4af49c7a3d5 100644 --- a/htdocs/projet/tasks/list.php +++ b/htdocs/projet/tasks/list.php @@ -322,7 +322,7 @@ $sql .= " t.rowid as id, t.ref, t.label, t.planned_workload, t.duration_effectiv $sql .= " t.description, t.fk_task_parent"; $sql .= " ,t.budget_amount"; // We'll need these fields in order to filter by categ -if ($search_categ) { +if ($search_categ > 0) { $sql .= ", cs.fk_categorie, cs.fk_project"; } // Add sum fields @@ -342,7 +342,7 @@ $sql .= $hookmanager->resPrint; $sql .= " FROM ".MAIN_DB_PREFIX."projet as p"; $sql .= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s on p.fk_soc = s.rowid"; // We'll need this table joined to the select in order to filter by categ -if (!empty($search_categ)) { +if ($search_categ > 0) { $sql .= ' LEFT JOIN '.MAIN_DB_PREFIX."categorie_project as cs ON p.rowid = cs.fk_project"; // We'll need this table joined to the select in order to filter by categ } $sql .= ", ".MAIN_DB_PREFIX."projet_task as t"; diff --git a/htdocs/public/onlinesign/newonlinesign.php b/htdocs/public/onlinesign/newonlinesign.php index d1020dc2c1d..9ebea80aeb3 100644 --- a/htdocs/public/onlinesign/newonlinesign.php +++ b/htdocs/public/onlinesign/newonlinesign.php @@ -126,7 +126,7 @@ $creditor = $mysoc->name; $type = $source; if ($source == 'proposal') { $object = new Propal($db); - $object->fetch(0, $ref); + $object->fetch(0, $ref, '', $entity); } else { accessforbidden('Bad value for source'); exit; @@ -139,7 +139,7 @@ if ($source == 'proposal') { $securekeyseed = $conf->global->PROPOSAL_ONLINE_SIGNATURE_SECURITY_TOKEN; } -if (!dol_verifyHash($securekeyseed.$type.$ref, $SECUREKEY, '0')) { +if (!dol_verifyHash($securekeyseed.$type.$ref.$object->entity, $SECUREKEY, '0')) { http_response_code(403); print 'Bad value for securitykey. Value provided '.dol_escape_htmltag($SECUREKEY).' does not match expected value for ref='.dol_escape_htmltag($ref); exit(-1); @@ -288,18 +288,8 @@ $error = 0; // Signature on commercial proposal if ($source == 'proposal') { $found = true; - $langs->load("proposal"); - require_once DOL_DOCUMENT_ROOT.'/comm/propal/class/propal.class.php'; - - $proposal = new Propal($db); - $result = $proposal->fetch('', $ref); - if ($result <= 0) { - $mesg = $proposal->error; - $error++; - } else { - $result = $proposal->fetch_thirdparty($proposal->socid); - } + $result = $object->fetch_thirdparty($object->socid); // Creditor @@ -315,39 +305,39 @@ if ($source == 'proposal') { print '
'.$langs->trans("ThirdParty"); print ''; print img_picto('', 'company', 'class="pictofixedwidth"'); - print '
'.$proposal->thirdparty->name.''; + print ''.$object->thirdparty->name.''; print ''."\n"; // Amount print ''.$langs->trans("Amount"); print ''; - print ''.price($proposal->total_ttc, 0, $langs, 1, -1, -1, $conf->currency).''; + print ''.price($object->total_ttc, 0, $langs, 1, -1, -1, $conf->currency).''; print ''."\n"; // Object - $text = ''.$langs->trans("SignatureProposalRef", $proposal->ref).''; + $text = ''.$langs->trans("SignatureProposalRef", $object->ref).''; print ''.$langs->trans("Designation"); print ''.$text; - if ($proposal->status == $proposal::STATUS_VALIDATED) { - $directdownloadlink = $proposal->getLastMainDocLink('proposal'); + if ($object->status == $object::STATUS_VALIDATED) { + $directdownloadlink = $object->getLastMainDocLink('proposal'); if ($directdownloadlink) { print '
'; - print img_mime($proposal->last_main_doc, ''); + print img_mime($object->last_main_doc, ''); print $langs->trans("DownloadDocument").''; } } else { - $last_main_doc_file = $proposal->last_main_doc; + $last_main_doc_file = $object->last_main_doc; - if ($proposal->status == $proposal::STATUS_NOTSIGNED) { - $directdownloadlink = $proposal->getLastMainDocLink('proposal'); + if ($object->status == $object::STATUS_NOTSIGNED) { + $directdownloadlink = $object->getLastMainDocLink('proposal'); if ($directdownloadlink) { print '
'; - print img_mime($proposal->last_main_doc, ''); + print img_mime($object->last_main_doc, ''); print $langs->trans("DownloadDocument").''; } - } elseif ($proposal->status == $proposal::STATUS_SIGNED || $proposal->status == $proposal::STATUS_BILLED) { + } elseif ($object->status == $object::STATUS_SIGNED || $object->status == $object::STATUS_BILLED) { if (preg_match('/_signed-(\d+)/', $last_main_doc_file)) { // If the last main doc has been signed $last_main_doc_file_not_signed = preg_replace('/_signed-(\d+)/', '', $last_main_doc_file); @@ -355,10 +345,10 @@ if ($source == 'proposal') { $datefilenotsigned = dol_filemtime($last_main_doc_file_not_signed); if (empty($datefilenotsigned) || $datefilesigned > $datefilenotsigned) { - $directdownloadlink = $proposal->getLastMainDocLink('proposal'); + $directdownloadlink = $object->getLastMainDocLink('proposal'); if ($directdownloadlink) { print '
'; - print img_mime($proposal->last_main_doc, ''); + print img_mime($object->last_main_doc, ''); print $langs->trans("DownloadDocument").''; } } @@ -367,7 +357,7 @@ if ($source == 'proposal') { } print ''; - print ''; + print ''; print ''."\n"; // TODO Add link to download PDF (similar code than for invoice) diff --git a/htdocs/public/test/test_exec.php b/htdocs/public/test/test_exec.php index 732bfefa824..026a8d12b7b 100644 --- a/htdocs/public/test/test_exec.php +++ b/htdocs/public/test/test_exec.php @@ -41,14 +41,16 @@ if (!defined("NOSESSION")) { define("NOSESSION", '1'); } +print "*** SHOW SESSION STATUS
\n"; print "Legend:
\n"; print 'PHP_SESSION_DISABLED='.PHP_SESSION_DISABLED."
\n"; print 'PHP_SESSION_NONE='.PHP_SESSION_NONE."
\n"; print 'PHP_SESSION_ACTIVE='.PHP_SESSION_ACTIVE."
\n"; print '
'; -print 'session_status='.session_status().' (before main.inc.php)'; -print '
'; +print 'session_status='.session_status().' (before main.inc.php)
'; + +print '

'."\n"; require '../../main.inc.php'; @@ -62,7 +64,8 @@ if ($dolibarr_main_prod) { * View */ -echo "Test
\n"; +print "*** TEST READ OF /tmp/test.txt FILE
\n"; + $out=''; $ret=0; @@ -78,14 +81,21 @@ if ($f) { print '

'."\n"; + +print "*** TEST READ OF /test.txt FILE AND LS /dev/std*
\n"; + exec('cat /test.txt; ls /dev/std*; sleep 1;', $out, $ret); -print $ret."
\n"; +print "ret=".$ret."
\n"; print_r($out); +print '
'; print '

'."\n"; + +print "*** TRY TO RUN CLAMDSCAN
\n"; + $ret = 0; $out = null; exec('/usr/bin/clamdscan --fdpass filethatdoesnotexists.php', $out, $ret); -print $ret."
\n"; +print "ret=".$ret."
\n"; print_r($out); diff --git a/htdocs/societe/card.php b/htdocs/societe/card.php index 3ef501aeac6..16e9b0b54ef 100644 --- a/htdocs/societe/card.php +++ b/htdocs/societe/card.php @@ -554,9 +554,8 @@ if (empty($reshook)) { } //var_dump($object->array_languages);exit; - if (GETPOST('deletephoto')) { - $object->logo = ''; - } elseif (!empty($_FILES['photo']['name'])) { + if (!empty($_FILES['photo']['name'])) { + $current_logo = $object->logo; $object->logo = dol_sanitizeFileName($_FILES['photo']['name']); } @@ -786,6 +785,13 @@ if (empty($reshook)) { } if ($file_OK) { if (image_format_supported($_FILES['photo']['name']) > 0) { + if ($current_logo != $object->logo) { + $fileimg = $dir.'/'.$current_logo; + $dirthumbs = $dir.'/thumbs'; + dol_delete_file($fileimg); + dol_delete_dir_recursive($dirthumbs); + } + dol_mkdir($dir); if (@is_dir($dir)) { diff --git a/htdocs/supplier_proposal/list.php b/htdocs/supplier_proposal/list.php index ad35c8f9914..8f7094ee486 100644 --- a/htdocs/supplier_proposal/list.php +++ b/htdocs/supplier_proposal/list.php @@ -302,7 +302,7 @@ $sql .= " p.rowid as project_id, p.ref as project_ref,"; if (empty($user->rights->societe->client->voir) && !$socid) { $sql .= " sc.fk_soc, sc.fk_user,"; } -$sql .= " u.firstname, u.lastname, u.photo, u.login, u.statut as status, u.admin, u.employee, u.email as uemail"; +$sql .= " u.firstname, u.lastname, u.photo, u.login, u.statut as ustatus, u.admin, u.employee, u.email as uemail"; // Add fields from extrafields if (!empty($extrafields->attributes[$object->table_element]['label'])) { foreach ($extrafields->attributes[$object->table_element]['label'] as $key => $val) { diff --git a/htdocs/user/bank.php b/htdocs/user/bank.php index 59f593f5b74..d2379388cb4 100644 --- a/htdocs/user/bank.php +++ b/htdocs/user/bank.php @@ -692,7 +692,7 @@ if ($action != 'edit' && $action != 'create') { // If not bank account yet, $ac if ($permissiontoaddbankaccount) { $morehtmlright = dolGetButtonTitle($langs->trans('Add'), '', 'fa fa-plus-circle', $_SERVER["PHP_SELF"].'?id='.$object->id.'&action=create'); } else { - $morehtmlright = dolGetButtonTitle($langs->trans('Add'), 'NotEnoughPermission', 'fa fa-plus-circle', '', '', -2); + $morehtmlright = dolGetButtonTitle($langs->trans('Add'), $langs->trans('NotEnoughPermissions'), 'fa fa-plus-circle', '', '', -2); } } else { $morehtmlright = dolGetButtonTitle($langs->trans('Add'), 'AlreadyOneBankAccount', 'fa fa-plus-circle', '', '', -2); diff --git a/htdocs/variants/class/ProductCombination.class.php b/htdocs/variants/class/ProductCombination.class.php index 986d3c3e7e8..22ba9f938e1 100644 --- a/htdocs/variants/class/ProductCombination.class.php +++ b/htdocs/variants/class/ProductCombination.class.php @@ -608,6 +608,10 @@ class ProductCombination $prodcomb2val = new ProductCombination2ValuePair($this->db); $prodcomb = new ProductCombination($this->db); + $features = array_filter($features, function ($v) { + return !empty($v); + }); + foreach ($features as $attr => $attr_val) { $actual_comp[$attr] = $attr_val; } diff --git a/test/phpunit/SecurityTest.php b/test/phpunit/SecurityTest.php index b33ec06504a..0815509b391 100644 --- a/test/phpunit/SecurityTest.php +++ b/test/phpunit/SecurityTest.php @@ -217,9 +217,17 @@ class SecurityTest extends PHPUnit\Framework\TestCase $result=testSqlAndScriptInject($test, 1); $this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject for SQL1b. Should find an attack on GET param and did not.'); + $test = '... update ... set ... ='; + $result=testSqlAndScriptInject($test, 1); + $this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject for SQL2a. Should find an attack on GET param and did not.'); + + $test = 'action=update& ... set ... ='; + $result=testSqlAndScriptInject($test, 1); + $this->assertEquals(0, $result, 'Error on testSqlAndScriptInject for SQL2b. Should not find an attack on GET param and did.'); + $test = '... union ... selection '; $result=testSqlAndScriptInject($test, 1); - $this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject for SQL2. Should find an attack on GET param and did not.'); + $this->assertEquals($expectedresult, $result, 'Error on testSqlAndScriptInject for SQL2c. Should find an attack on GET param and did not.'); $test = 'javascript:'; $result=testSqlAndScriptInject($test, 0);