diff --git a/.travis.yml b/.travis.yml index 8d5a54b0548..10a2b6e8347 100644 --- a/.travis.yml +++ b/.travis.yml @@ -37,6 +37,7 @@ php: - '5.6' - '7.0' - '7.1' +- '7.2' #- hhvm only with dist: trusty - nightly @@ -71,6 +72,8 @@ matrix: env: DB=postgresql - php: '7.0' env: DB=postgresql + - php: '7.1' + env: DB=postgresql - php: hhvm env: DB=postgresql - php: nightly @@ -123,7 +126,10 @@ install: if [ "$TRAVIS_PHP_VERSION" = '5.3' ] || [ "$TRAVIS_PHP_VERSION" = '5.4' ] || [ "$TRAVIS_PHP_VERSION" = '5.5' ]; then composer -n require phpunit/phpunit ^4 fi - if [ "$TRAVIS_PHP_VERSION" = '5.6' ] || [ "$TRAVIS_PHP_VERSION" = '7.0' ] || [ "$TRAVIS_PHP_VERSION" = '7.1' ] || [ "$TRAVIS_PHP_VERSION" = 'nightly' ]; then + if [ "$TRAVIS_PHP_VERSION" = '5.6' ] || [ "$TRAVIS_PHP_VERSION" = '7.0' ] || [ "$TRAVIS_PHP_VERSION" = '7.1' ]; then + composer -n require phpunit/phpunit ^5 + fi + if [ "$TRAVIS_PHP_VERSION" = '7.2' ] || [ "$TRAVIS_PHP_VERSION" = 'nightly' ]; then composer -n require phpunit/phpunit ^5 fi echo @@ -163,7 +169,7 @@ before_script: #echo 'extension = apc.so' >> ~/.phpenv/versions/$PHP_VERSION_NAME/etc/php.ini echo echo "Enabling Memcached for PHP <= 5.4" - # Documentation says it should be available for all PHP versions but it's not for 5.5 and 5.6, 7.0, 7.1 and nightly! + # Documentation says it should be available for all PHP versions but it's not for 5.5 and 5.6, 7.0, 7.1, 7.2 and nightly! echo 'extension = memcached.so' >> ~/.phpenv/versions/$PHP_VERSION_NAME/etc/php.ini fi phpenv rehash @@ -237,7 +243,7 @@ before_script: echo "Setting up Apache + FPM" # enable php-fpm cp ~/.phpenv/versions/$PHP_VERSION_NAME/etc/php-fpm.conf.default ~/.phpenv/versions/$PHP_VERSION_NAME/etc/php-fpm.conf - if [ "$TRAVIS_PHP_VERSION" = '7.0' ] || [ "$TRAVIS_PHP_VERSION" = '7.1' ] || [ "$TRAVIS_PHP_VERSION" = 'nightly' ]; then + if [ "$TRAVIS_PHP_VERSION" = '7.0' ] || [ "$TRAVIS_PHP_VERSION" = '7.1' ] || [ "$TRAVIS_PHP_VERSION" = '7.2' ] || [ "$TRAVIS_PHP_VERSION" = 'nightly' ]; then # Copy the included pool cp ~/.phpenv/versions/$PHP_VERSION_NAME/etc/php-fpm.d/www.conf.default ~/.phpenv/versions/$PHP_VERSION_NAME/etc/php-fpm.d/www.conf fi @@ -332,6 +338,7 @@ script: - | echo "Unit testing" + phpunit --version # Ensure we catch errors. Set this to +e if you want to go to the end to see dolibarr.log file. set -e phpunit -d memory_limit=-1 -c test/phpunit/phpunittest.xml test/phpunit/AllTests.php diff --git a/ChangeLog b/ChangeLog index 0de3ed5df3a..56c0d1fd06b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -2,6 +2,27 @@ English Dolibarr ChangeLog -------------------------------------------------------------- +***** ChangeLog for 6.0.4 compared to 6.0.3 ***** +FIX: #7737 +FIX: #7751 +FIX: #7756 Add better error message +FIX: #7786 +FIX: #7806 +FIX: #7824 +FIX: add line bad price and ref +FIX: A lot of several fix on local taxes and NPR tax +FIX: createfromorder +FIX: CSS for IE10 +FIX: external user cannot be set as internal +FIX: Filter type on actioncomm with multiselect doesn't work +FIX: list of donation not filtered on multicompany +FIX: list of module not complete when module mb_strlen not available +FIX: Locatax were not propagated when cloning order or proposal +FIX: Searching translation should not be case sensitive +FIX: Search into language is ok for file into external modules two. +FIX: test for filter fk_status +FIX: too much users on holiday list +FIX: Wrong alias sql ***** ChangeLog for 7.0.0 compared to 6.0.* ***** @@ -13,22 +34,31 @@ NEW: complete_head_from_modules() in ldap_prepare_head() WARNING: +If you enabled (for test) the experimental BlockedLog module before 7.0, you must purge the table llx_blockedlog because +way to save data for final version has changed. + Following changes may create regressions for some external modules, but were necessary to make Dolibarr better: * The methode "cloture" on contract were renamed into "closeAll". -* The substitution key for reference of object is now __REF__ whatever is the object (it replaces __ORDERREF__, +* The method "is_erasable" of invoice return a value <= 0 if not erasable (value is meaning) instead of always 0. +* The substitution key for reference of objects is now __REF__ whatever is the object (it replaces __ORDERREF__, __PROPALREF__, ...) * The substition key __SIGNATURE__ was renamed into __USER_SIGNATURE__ to follow naming conventions. * Substitution keys with syntax %XXX% were renamed into __XXX__ to match others. +* Removed old deprecated REST API (APIs found into '/root' section of the REST API explorer in Dolibarr v6). * Some REST API to access setup features, like dictionaries (country, town, extrafields, ...) were moved into a common API "/setup". * The REST API /documents were renamed into /documents/download and /documents/upload. -* Page bank/index.php and bank/bankentries.php were renamed into bank/list.php and bank/bankentries_list.php to - follow page naming conventions (so default filter/sort order features can also work). +* Page bank/index.php, bank/bankentries.php and comm/actions/listactions.php were renamed into + bank/list.php, bank/bankentries_list.php and comm/actions/list.php to follow page naming + conventions (so default filter/sort order features can also work for this pages). * The trigger ORDER_SUPPLIER_STATUS_ONPROCESS was renamed into ORDER_SUPPLIER_STATUS_ORDERED. * The trigger ORDER_SUPPLIER_STATUS_RECEIVED_ALL was renamed into ORDER_SUPPLIER_STATUS_RECEIVED_COMPLETELY. * The parameter note into method cloture() is added at end of private note (previously in v6, it replaced). -* The parameter $user is now mandatory for method createFromOrder and createFromPropal. +* The parameter $user is now mandatory for method createFromOrder and createFromPropal. * Removed js library 'fileupload' that was not used by core code. +* Jquery plugin tableDnd updated. You now need to use decodeURI on the return value of tableDnDSerialize() + and add 'td.' to the beginning of the dragHandle match string. +* IE8 and earlier and Firefox 12 and earlier (< 2012) are no more supported. ***** ChangeLog for 6.0.3 compared to 6.0.2 ***** diff --git a/build/exe/doliwamp/Languages/MyEnglish.isl b/build/exe/doliwamp/Languages/MyEnglish.isl index 6e70f3c12f3..11d2e4456bd 100644 --- a/build/exe/doliwamp/Languages/MyEnglish.isl +++ b/build/exe/doliwamp/Languages/MyEnglish.isl @@ -43,3 +43,5 @@ DoliWampWillStartApacheMysql=DoliWamp installer will now start or restart Apache OldVersionFoundAndMoveInNew=An old database version has been found and moved to be used by new Dolibarr version OldVersionFoundButFailedToMoveInNew=An old database version has been found but could not be moved to be used with new Dolibarr version +DLLMissing=The "Visual C++ Redistributable for Visual Studio 2012" component is missing. Please install the 32-bit version (vcredit_x86.exe) first from https://www.microsoft.com/en-us/download/details.aspx?id=30679 and restart DoliWamp installation/upgrade. +ContinueAnyway=Continue anyway (install process may fails without this prerequisite) diff --git a/build/exe/doliwamp/doliwamp.iss b/build/exe/doliwamp/doliwamp.iss index fbd821b367c..7dcb8c738bd 100644 --- a/build/exe/doliwamp/doliwamp.iss +++ b/build/exe/doliwamp/doliwamp.iss @@ -202,10 +202,30 @@ var value: String; function InitializeSetup(): Boolean; begin Result := MsgBox(CustomMessage('YouWillInstallDoliWamp')+#13#13+CustomMessage('ThisAssistantInstallOrUpgrade')+#13#13+CustomMessage('IfYouHaveTechnicalKnowledge')+#13#13+CustomMessage('ButIfYouLook')+#13#13+CustomMessage('DoYouWantToStart'), mbConfirmation, MB_YESNO) = IDYES; + + if Result then + begin + + //---------------------------------------------- + // Test if msvcr110 DLL has been installed + //---------------------------------------------- + + if not FileExists ('c:/windows/system32/msvcr110.dll') and not FileExists ('c:/windows/sysWOW64/msvcr110.dll') and not FileExists ('c:/winnt/system32/msvcr110.dll') and not FileExists ('c:/winnt/sysWOW64/msvcr110.dll') then + begin + // TODO - offer to install the component by opening the URL in the default browser, abort installation if user doesn't accept + Result := MsgBox(CustomMessage('DLLMissing')+#13#13+CustomMessage('ContinueAnyway'), mbConfirmation, MB_YESNO) = IDYES; + + end; + // Pb seems similar with msvcp110.dll + //vcredist_x64.exe + + end; + end; procedure InitializeWizard(); begin + //version des applis, a modifier pour chaque version de WampServer 2 apacheVersion := '2.4.9'; phpVersion := '5.5.12' ; @@ -217,6 +237,7 @@ begin mysqlPort := '3306'; newPassword := 'changeme'; + firstinstall := true; @@ -344,18 +365,6 @@ begin exedirold := pathWithSlashes+'/bin/mysql/mysql5.0.45'; exedirnew := pathWithSlashes+'/bin/mysql/mysql5.0.45'; - - //---------------------------------------------- - // Test if msvcr110 DLL has been installed - //---------------------------------------------- - - if not FileExists ('c:/windows/system32/msvcr110.dll') and not FileExists ('c:/windows/sysWOW64/msvcr110.dll') and not FileExists ('c:/winnt/system32/msvcr110.dll') and not FileExists ('c:/winnt/sysWOW64/msvcr110.dll') then - begin - // TODO - offer to install the component by opening the URL in the default browser, abort installation if user doesn't accept - MsgBox('The "Visual C++ Redistributable for Visual Studio 2012" component is missing. Please install the 32-bit version (vcredit_x86.exe) first from http://www.microsoft.com/en-us/download/details.aspx?id=30679 and restart DoliWamp installation/upgrade.',mbInformation,MB_OK); - end; - // Pb seems similar with msvcp110.dll - //vcredist_x64.exe // If we have a new database version, we should only copy old my.ini file into new directory diff --git a/build/exe/doliwamp/index.php.install b/build/exe/doliwamp/index.php.install index 700f0707de2..1c657b35977 100644 --- a/build/exe/doliwamp/index.php.install +++ b/build/exe/doliwamp/index.php.install @@ -535,7 +535,7 @@ a:hover {
  • {$langues[$langue]['autreLangue1']} - {$langues[$langue]['autreLangue2']}


  • -
  • Provided by NLTechno
  • +
  • Provided by NLTechno

  • @@ -580,7 +580,7 @@ a:hover { diff --git a/build/generate_filelist_xml.php b/build/generate_filelist_xml.php index 0d3d90d54d4..e6336e30e97 100755 --- a/build/generate_filelist_xml.php +++ b/build/generate_filelist_xml.php @@ -131,7 +131,7 @@ $iterator1 = new RecursiveIteratorIterator($dir_iterator1); $files = new RegexIterator($iterator1, '#^(?:[A-Z]:)?(?:/(?!(?:'.($includecustom?'':'custom\/|').'documents\/|conf\/|install\/))[^/]+)+/[^/]+\.(?:php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$#i'); */ $regextoinclude='\.(php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$'; -$regextoexclude='('.($includecustom?'':'custom|').'documents|conf|install)$'; // Exclude dirs +$regextoexclude='('.($includecustom?'':'custom|').'documents|conf|install|public\/test|Shared\/PCLZip|nusoap\/lib\/Mail|php\/example|php\/test|geoip\/sample.*\.php|ckeditor\/samples|ckeditor\/adapters)$'; // Exclude dirs $files = dol_dir_list(DOL_DOCUMENT_ROOT, 'files', 1, $regextoinclude, $regextoexclude, 'fullname'); $dir=''; $needtoclose=0; diff --git a/build/makepack-dolibarr.pl b/build/makepack-dolibarr.pl index 2802e55c702..bc755ef52a3 100755 --- a/build/makepack-dolibarr.pl +++ b/build/makepack-dolibarr.pl @@ -556,9 +556,6 @@ if ($nboftargetok) { $ret=`rm -f $BUILDROOT/$PROJECT/.cvsignore $BUILDROOT/$PROJECT/*/.cvsignore $BUILDROOT/$PROJECT/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/*/*/.cvsignore $BUILDROOT/$PROJECT/*/*/*/*/*/*/.cvsignore`; $ret=`rm -f $BUILDROOT/$PROJECT/.gitignore $BUILDROOT/$PROJECT/*/.gitignore $BUILDROOT/$PROJECT/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/*/*/.gitignore $BUILDROOT/$PROJECT/*/*/*/*/*/*/.gitignore`; $ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/geoip/sample*.*`; - $ret=`rm -f $BUILDROOT/$PROJECT/htdocs/includes/jquery/plugins/jqueryFileTree/connectors/jqueryFileTree.pl`; # Avoid errors into rpmlint - $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/jquery/plugins/template`; # Package not valid for most linux distributions (errors reported into compile.js). Package should be embed by modules to avoid problems. - $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/phpmailer`; # Package not valid for most linux distributions (errors reported into file LICENSE). Package should be embed by modules to avoid problems. $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/ckeditor/ckeditor/adapters`; # Keep this removal in case we embed libraries $ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/ckeditor/ckeditor/samples`; # Keep this removal in case we embed libraries #$ret=`rm -fr $BUILDROOT/$PROJECT/htdocs/includes/ckeditor/_source`; # _source must be kept into tarball diff --git a/build/rpm/dolibarr_fedora.spec b/build/rpm/dolibarr_fedora.spec index 55898481691..077aaeb9483 100755 --- a/build/rpm/dolibarr_fedora.spec +++ b/build/rpm/dolibarr_fedora.spec @@ -213,7 +213,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/user %_datadir/dolibarr/htdocs/variants %_datadir/dolibarr/htdocs/webservices -%_datadir/dolibarr/htdocs/websites +%_datadir/dolibarr/htdocs/website %_datadir/dolibarr/htdocs/*.ico %_datadir/dolibarr/htdocs/*.patch %_datadir/dolibarr/htdocs/*.php diff --git a/build/rpm/dolibarr_generic.spec b/build/rpm/dolibarr_generic.spec index e5b346278ab..5b39bac7761 100755 --- a/build/rpm/dolibarr_generic.spec +++ b/build/rpm/dolibarr_generic.spec @@ -293,7 +293,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/user %_datadir/dolibarr/htdocs/variants %_datadir/dolibarr/htdocs/webservices -%_datadir/dolibarr/htdocs/websites +%_datadir/dolibarr/htdocs/website %_datadir/dolibarr/htdocs/*.ico %_datadir/dolibarr/htdocs/*.patch %_datadir/dolibarr/htdocs/*.php diff --git a/build/rpm/dolibarr_mandriva.spec b/build/rpm/dolibarr_mandriva.spec index 3c8a5097c0e..1034615c80a 100755 --- a/build/rpm/dolibarr_mandriva.spec +++ b/build/rpm/dolibarr_mandriva.spec @@ -210,7 +210,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/user %_datadir/dolibarr/htdocs/variants %_datadir/dolibarr/htdocs/webservices -%_datadir/dolibarr/htdocs/websites +%_datadir/dolibarr/htdocs/website %_datadir/dolibarr/htdocs/*.ico %_datadir/dolibarr/htdocs/*.patch %_datadir/dolibarr/htdocs/*.php diff --git a/build/rpm/dolibarr_opensuse.spec b/build/rpm/dolibarr_opensuse.spec index c77661fe420..eb1887f229f 100755 --- a/build/rpm/dolibarr_opensuse.spec +++ b/build/rpm/dolibarr_opensuse.spec @@ -221,7 +221,7 @@ done >>%{name}.lang %_datadir/dolibarr/htdocs/user %_datadir/dolibarr/htdocs/variants %_datadir/dolibarr/htdocs/webservices -%_datadir/dolibarr/htdocs/websites +%_datadir/dolibarr/htdocs/website %_datadir/dolibarr/htdocs/*.ico %_datadir/dolibarr/htdocs/*.patch %_datadir/dolibarr/htdocs/*.php diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt index fa84aedc26a..f28df995c45 100644 --- a/dev/dolibarr_changes.txt +++ b/dev/dolibarr_changes.txt @@ -116,4 +116,29 @@ to get if ($className == 'Luracast\Restler\string') return; if ($className == 'Luracast\Restler\mixed') return; ... - \ No newline at end of file + +Change also file Luracast/Restler/explorer/index.html + ++With swagger 2: + +* Add line into Util.php to complete function + + public static function getShortName($className) + { + // @CHANGE LDR + if (! is_string($className)) return; + //var_dump($className); + + + +PARSEDOWN +--------- + +* Fix to avoid fatal error when mb_strlen not available: + + // @CHANGE LDR Fix when mb_strlen is not available + //$shortage = 4 - mb_strlen($line, 'utf-8') % 4; + if (function_exists('mb_strlen')) $len = mb_strlen($line, 'utf-8'); + else $len = strlen($line); + $shortage = 4 - $len % 4; + \ No newline at end of file diff --git a/dev/resources/iso-normes/accountancy_rules.txt b/dev/resources/iso-normes/accountancy_rules.txt new file mode 100644 index 00000000000..15e07ffbea1 --- /dev/null +++ b/dev/resources/iso-normes/accountancy_rules.txt @@ -0,0 +1,14 @@ + +Gestion escompte: + +Sur une facture de 120 € TTC : +707xxx 100 € HT +44571x 20 € TVA +411xxx 120 € TTC + +Le client règle rapidement et on lui accorde un escompte de 3% (120 € * 3% = 3.6 € TTC), on aura donc : +665000 3,00 € HT +44571x 0,60 € TVA +411xxx 3.60 € TVA + +Et ça marche à l’inverse avec un fournisseur sauf que l’on est en 775000 au lieu de 665000 pour escompte obtenus. diff --git a/dev/resources/iso-normes/sample_FEC_file.txt b/dev/resources/iso-normes/sample_FEC_file.txt index 8ca50c92617..4285a9403a5 100644 --- a/dev/resources/iso-normes/sample_FEC_file.txt +++ b/dev/resources/iso-normes/sample_FEC_file.txt @@ -11,3 +11,25 @@ Banque Banque 17306 20170119 5121CRA CR AGRICOLE A01 20170119 ZDAV courtage s/ Banque Banque 17306 20170119 401ZDAV SANDRA DAVILA A01 20170119 ZDAV courtage s/ ventes 508,00 0,00 20170119 Banque Banque 17307 20170119 401ZDAV SANDRA DAVILA A01 20170119 ZDAV courtage s/ ventes 508,00 0,00 20170131 Banque Banque 17307 20170119 5121CRA CR AGRICOLE A01 20170119 ZDAV courtage s/ ventes 0,00 508,00 20170131 + + + + + + +Other example +JournalCode JournalLib EcritureNum EcritureDate CompteNum CompteLib CompAuxNum CompAuxLib PieceRef PieceDate EcritureLib Debit Credit EcritureLet DateLet ValidDate Montantdevise Idevise +FAC Factures clients AB6/FAC/2017/0045 20171120 41110000 Clients - Ventes de biens ou de prestations de services ID 2892 2 Et 3 Dimensions - 20171120 / 1 0 0 0 20171120 +FAC Factures clients AB6/FAC/2017/0052 20171120 70710000 Marchandises (ou groupe) A ID 2892 2 Et 3 Dimensions - 20171120 [AX] Activités Annexes 0 0 1 0 20171120 +FAC Factures clients AB6/FAC/2017/0052 20171120 70710000 Marchandises (ou groupe) A ID 2892 2 Et 3 Dimensions - 20171120 [AX] Activités Annexes 0 0 1 0 20171120 +FAC Factures clients AB6/FAC/2017/0052 20171120 41110000 Clients - Ventes de biens ou de prestations de services ID 2892 2 Et 3 Dimensions - 20171120 / 2 0 0 0 20171120 +OUV Balance initiale Balance initiale BRED 20171101 51215000 BRED - 20171101 / 6201 0 0 0 20171101 +OUV Balance initiale Balance initiale Crédit Coopératif Nation 20171101 51211000 Crédit Coopératif Nation - 20171101 / 1364 20 0 0 20171101 +OUV Balance initiale Balance initiale TVA collectée (Taux Intermédiaire) 20171101 44571200 TVA collectée (Taux Intermédiaire) - 20171101 / 0 0 147 4 20171101 +OUV Balance initiale Balance initiale TVA déductible intracommunautaire 20171101 44566200 TVA déductible intracommunautaire - 20171101 / 18 0 0 0 20171101 +OUV Balance initiale Balance initiale Capital souscrit - non appelé 20171101 10110000 Capital souscrit - non appelé - 20171101 / 10 0 0 0 20171101 +OUV Balance initiale Balance initiale Réserves statutaires ou contractuelles 20171101 10630000 Réserves statutaires ou contractuelles - 20171101 / 0 0 10 0 20171101 +OUV Balance initiale Balance initiale Frais entrepreneurs 20171101 46750000 Frais entrepreneurs - 20171101 / 0 0 100 0 20171101 +OUV Balance initiale Balance initiale Fournissseurs réglés par Coopaname 20171101 40100000 Fournissseurs réglés par Coopaname - 20171101 / 0 0 4123 20 20171101 +OUV Balance initiale Balance initiale TVA sur autres biens et services 20171101 44566000 TVA sur autres biens et services - 20171101 / 507 70 0 0 20171101 +OUV Balance initiale Balance initiale TVA en attente à 20% 20171101 44572200 TVA en attente à 20% - 20171101 / 200 0 0 0 20171101 diff --git a/dev/tools/fixaltlanguages.sh b/dev/tools/fixaltlanguages.sh index 65171f9acea..955552940a9 100755 --- a/dev/tools/fixaltlanguages.sh +++ b/dev/tools/fixaltlanguages.sh @@ -46,13 +46,20 @@ then then aaupper="GR" fi + if [ $bb = "EG" ] + then + aaupper="SA" + fi + bblower=`echo $dirshort | nawk -F"_" '{ print tolower($2) }'` + + echo "***** Process language "$aa"_"$bb if [ "$aa" != "$bblower" -a "$dirshort" != "en_US" ] then reflang="htdocs/langs/"$aa"_"$aaupper if [ -d $reflang -a $aa"_"$bb != $aa"_"$aaupper ] then - echo "***** Process language "$aa"_"$bb" - Search original into "$reflang + echo "***** Search original into "$reflang echo $dirshort is an alternative language of $reflang echo ./dev/translation/strip_language_file.php $aa"_"$aaupper $aa"_"$bb $2 ./dev/translation/strip_language_file.php $aa"_"$aaupper $aa"_"$bb $2 diff --git a/doc/images/dolibarr_screenshot1_1680x1050.png b/doc/images/dolibarr_screenshot1_1680x1050.png new file mode 100644 index 00000000000..46b6367f784 Binary files /dev/null and b/doc/images/dolibarr_screenshot1_1680x1050.png differ diff --git a/doc/images/dolibarr_screenshot4_1680x1050.png b/doc/images/dolibarr_screenshot4_1680x1050.png new file mode 100644 index 00000000000..afb2828b08a Binary files /dev/null and b/doc/images/dolibarr_screenshot4_1680x1050.png differ diff --git a/doc/images/dolibarr_screenshot9_1680x1050.png b/doc/images/dolibarr_screenshot9_1680x1050.png new file mode 100644 index 00000000000..7708245441a Binary files /dev/null and b/doc/images/dolibarr_screenshot9_1680x1050.png differ diff --git a/htdocs/accountancy/admin/account.php b/htdocs/accountancy/admin/account.php index 4dcc4be7b01..98ecd8e327c 100644 --- a/htdocs/accountancy/admin/account.php +++ b/htdocs/accountancy/admin/account.php @@ -229,7 +229,7 @@ if ($resql) $htmlbuttonadd = '' . $langs->trans("Addanaccount") . ''; - print_barre_liste($langs->trans('ListAccounts'), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_accountancy', 0, $htmlbuttonadd, '', $limit); + print_barre_liste($langs->trans('ListAccounts'), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, $nbtotalofrecords, 'title_accountancy', 0, $htmlbuttonadd, '', $limit); // Box to select active chart of account print $langs->trans("Selectchartofaccounts") . " : "; @@ -258,6 +258,7 @@ if ($resql) print ""; print ajax_combobox("chartofaccounts"); print ''; + print '
    '; print '
    '; diff --git a/htdocs/accountancy/admin/categories.php b/htdocs/accountancy/admin/categories.php index b281078a6bf..7ab463e3179 100644 --- a/htdocs/accountancy/admin/categories.php +++ b/htdocs/accountancy/admin/categories.php @@ -86,9 +86,11 @@ if ($action == 'delete') { $form = new Form($db); $formaccounting = new FormAccounting($db); -llxheader('', $langs->trans('AccountAccounting')); +llxheader('', $langs->trans('AccountingCategory')); -print load_fiche_titre($langs->trans('AccountingCategory')); +$linkback = ''.$langs->trans("BackToList").''; + +print load_fiche_titre($langs->trans('AccountingCategory'), $linkback); print '
    ' . "\n"; print ''; @@ -110,7 +112,7 @@ if (! empty($cat_id)) if ($return < 0) { setEventMessages(null, $accountingcategory->errors, 'errors'); } - print '' . $langs->trans("AddAccountFromBookKeepingWithNoCategories") . ''; + print '' . $langs->trans("AddAccountFromBookKeepingWithNoCategories") . ''; print ''; $arraykeyvalue=array(); diff --git a/htdocs/accountancy/admin/categories_list.php b/htdocs/accountancy/admin/categories_list.php index 488123acc70..ad8b563e477 100644 --- a/htdocs/accountancy/admin/categories_list.php +++ b/htdocs/accountancy/admin/categories_list.php @@ -418,18 +418,15 @@ if ($action == 'disable_favorite') $form = new Form($db); $formadmin=new FormAdmin($db); -llxHeader(); +llxHeader('', $langs->trans('AccountingCategory')); $titre=$langs->trans($tablib[$id]); $linkback=''; $titlepicto='title_setup'; -print load_fiche_titre($titre,$linkback,$titlepicto); +print load_fiche_titre($titre, $linkback, $titlepicto); -if ($id == 32) -{ - print $langs->trans("AccountingAccountGroupsDesc", $langs->transnoentitiesnoconv("ByPersonalizedAccountGroups")).'

    '; -} +print $langs->trans("AccountingAccountGroupsDesc", $langs->transnoentitiesnoconv("ByPersonalizedAccountGroups")).'

    '; // Confirmation de la suppression de la ligne if ($action == 'delete') @@ -658,7 +655,6 @@ if ($id) if ($fieldlist[$field]=='libelle' || $fieldlist[$field]=='label') { $valuetoshow=$langs->trans("Label"); - if ($id != 25) $valuetoshow.="*"; } if ($fieldlist[$field]=='country') { $valuetoshow=$langs->trans("Country"); } if ($fieldlist[$field]=='region_id' || $fieldlist[$field]=='country_id') { $showfield=0; } @@ -807,10 +803,12 @@ if ($id) else print ' '; // Link to setup the group - print ''; + print ''; if (empty($obj->formula)) { - print ''.$langs->trans("Setup").''; + print ''; + print $langs->trans("ListOfAccounts"); + print ''; } print ''; } diff --git a/htdocs/accountancy/admin/export.php b/htdocs/accountancy/admin/export.php index 4a9625972b8..bdf0a7c1826 100644 --- a/htdocs/accountancy/admin/export.php +++ b/htdocs/accountancy/admin/export.php @@ -138,7 +138,6 @@ $form = new Form($db); // $linkback = '' . $langs->trans("BackToModuleList") . ''; print load_fiche_titre($langs->trans('ConfigAccountingExpert'), $linkback, 'title_setup'); - print "\n".''; + llxFooter(); $db->close(); \ No newline at end of file diff --git a/htdocs/accountancy/expensereport/card.php b/htdocs/accountancy/expensereport/card.php index fee9e0b0057..3b59847d84d 100644 --- a/htdocs/accountancy/expensereport/card.php +++ b/htdocs/accountancy/expensereport/card.php @@ -38,6 +38,9 @@ $langs->load("accountancy"); $langs->load("trips"); $action = GETPOST('action', 'alpha'); +$cancel = GETPOST('cancel', 'alpha'); +$backtopage = GETPOST('backtopage', 'alpha'); + $codeventil = GETPOST('codeventil'); $id = GETPOST('id'); @@ -45,12 +48,15 @@ $id = GETPOST('id'); if ($user->societe_id > 0) accessforbidden(); + /* * Actions */ -if ($action == 'ventil' && $user->rights->accounting->bind->write) { - if (! GETPOST('cancel', 'alpha')) { +if ($action == 'ventil' && $user->rights->accounting->bind->write) +{ + if (! $cancel) + { if ($codeventil < 0) $codeventil = 0; $sql = " UPDATE " . MAIN_DB_PREFIX . "expensereport_det"; @@ -64,6 +70,11 @@ if ($action == 'ventil' && $user->rights->accounting->bind->write) { else { setEventMessages($langs->trans("RecordModifiedSuccessfully"), null, 'mesgs'); + if ($backtopage) + { + header("Location: ".$backtopage); + exit(); + } } } else { header("Location: ./lines.php"); @@ -111,6 +122,7 @@ if (! empty($id)) { print '' . "\n"; print ''; print ''; + print ''; print load_fiche_titre($langs->trans('ExpenseReportsVentilation'), '', 'title_setup'); diff --git a/htdocs/accountancy/expensereport/index.php b/htdocs/accountancy/expensereport/index.php index d7d8d6d2bec..623011feaa7 100644 --- a/htdocs/accountancy/expensereport/index.php +++ b/htdocs/accountancy/expensereport/index.php @@ -310,7 +310,6 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) // This part of code looks strange. print_fiche_titre($langs->trans("OtherInfo"), '', ''); - print "
    \n"; print '
    '; print ''; print ''; diff --git a/htdocs/accountancy/expensereport/lines.php b/htdocs/accountancy/expensereport/lines.php index 750a5bc9f25..406e6bcb7c7 100644 --- a/htdocs/accountancy/expensereport/lines.php +++ b/htdocs/accountancy/expensereport/lines.php @@ -328,7 +328,7 @@ if ($result) { print ''; - print ''; diff --git a/htdocs/accountancy/expensereport/list.php b/htdocs/accountancy/expensereport/list.php index 35460f6d48f..0e4b9b05ac9 100644 --- a/htdocs/accountancy/expensereport/list.php +++ b/htdocs/accountancy/expensereport/list.php @@ -92,6 +92,8 @@ if (! $user->rights->accounting->bind->write) $formaccounting = new FormAccounting($db); $accounting = new AccountingAccount($db); +$chartaccountcode = dol_getIdFromCode($db, $conf->global->CHARTOFACCOUNTS, 'accounting_system', 'rowid', 'pcg_version'); + /* * Action @@ -182,18 +184,24 @@ $formother = new FormOther($db); llxHeader('', $langs->trans("ExpenseReportsVentilation")); +if (empty($chartaccountcode)) +{ + print $langs->trans("ErrorChartOfAccountSystemNotSelected"); + llxFooter(); + $db->close(); + exit; +} + // Expense report lines $sql = "SELECT er.ref, er.rowid as erid, er.date_debut,"; -$sql .= " erd.rowid, erd.fk_c_type_fees, erd.comments, erd.total_ht as price, erd.fk_code_ventilation, erd.tva_tx as tva_tx_line, erd.vat_src_code, erd.date,"; -$sql .= " f.id as type_fees_id, f.code as type_fees_code, f.label as type_fees_label, f.accountancy_code as code_buy,"; -$sql .= " aa.rowid as aarowid"; -$sql .= " FROM " . MAIN_DB_PREFIX . "expensereport as er"; -$sql .= " INNER JOIN " . MAIN_DB_PREFIX . "expensereport_det as erd ON er.rowid = erd.fk_expensereport"; -$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "c_type_fees as f ON f.id = erd.fk_c_type_fees"; -$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON f.accountancy_code = aa.account_number"; -$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_system as accsys ON accsys.pcg_version = aa.fk_pcg_version"; -$sql .= " WHERE er.fk_statut > 4 AND erd.fk_code_ventilation <= 0"; -$sql .= " AND (accsys.rowid='" . $conf->global->CHARTOFACCOUNTS . "' OR f.accountancy_code IS NULL OR f.accountancy_code ='')"; +$sql.= " erd.rowid, erd.fk_c_type_fees, erd.comments, erd.total_ht as price, erd.fk_code_ventilation, erd.tva_tx as tva_tx_line, erd.vat_src_code, erd.date,"; +$sql.= " f.id as type_fees_id, f.code as type_fees_code, f.label as type_fees_label, f.accountancy_code as code_buy,"; +$sql.= " aa.rowid as aarowid"; +$sql.= " FROM " . MAIN_DB_PREFIX . "expensereport as er"; +$sql.= " INNER JOIN " . MAIN_DB_PREFIX . "expensereport_det as erd ON er.rowid = erd.fk_expensereport"; +$sql.= " LEFT JOIN " . MAIN_DB_PREFIX . "c_type_fees as f ON f.id = erd.fk_c_type_fees"; +$sql.= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON p.accountancy_code = aa.account_number AND aa.fk_pcg_version = '" . $chartaccountcode."'"; +$sql.= " WHERE er.fk_statut > 4 AND erd.fk_code_ventilation <= 0"; // Add search filter like if (strlen(trim($search_expensereport))) { $sql .= natural_search("er.ref",$search_expensereport); @@ -266,7 +274,7 @@ if ($result) { //'presend'=>$langs->trans("SendByMail"), //'builddoc'=>$langs->trans("PDFMerge"), ); - //if ($user->rights->mymodule->supprimer) $arrayofmassactions['delete']=$langs->trans("Delete"); + //if ($user->rights->mymodule->supprimer) $arrayofmassactions['predelete']=$langs->trans("Delete"); //if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array(); $massactionbutton=$form->selectMassAction('ventil', $arrayofmassactions, 1); @@ -284,6 +292,12 @@ if ($result) { print $langs->trans("DescVentilTodoExpenseReport") . '

    '; + /*$topicmail="Information"; + $modelmail="project"; + $objecttmp=new Project($db); + $trackid='prj'.$object->id; + include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';*/ + if ($msg) print $msg.'
    '; $moreforfilter = ''; @@ -380,11 +394,11 @@ if ($result) { // Suggested accounting account print ''; print ''; print ""; @@ -399,5 +413,17 @@ if ($result) { print $db->error(); } +// Add code to auto check the box when we select an account +print ''; + llxFooter(); $db->close(); diff --git a/htdocs/accountancy/journal/bankjournal.php b/htdocs/accountancy/journal/bankjournal.php index 8f17fad4e17..925628c8fa7 100644 --- a/htdocs/accountancy/journal/bankjournal.php +++ b/htdocs/accountancy/journal/bankjournal.php @@ -7,6 +7,7 @@ * Copyright (C) 2013-2017 Alexandre Spangaro * Copyright (C) 2013-2014 Florian Henry * Copyright (C) 2013-2014 Olivier Geffroy + * Copyright (C) 2017 Frédéric France * * 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 @@ -118,10 +119,15 @@ $sql .= " WHERE ba.fk_accountancy_journal=" . $id_journal; $sql .= ' AND b.amount != 0 AND ba.entity IN ('.getEntity('bank_account', 0).')'; // We don't share object for accountancy if ($date_start && $date_end) $sql .= " AND b.dateo >= '" . $db->idate($date_start) . "' AND b.dateo <= '" . $db->idate($date_end) . "'"; +// Already in bookkeeping or not if ($in_bookkeeping == 'already') +{ $sql .= " AND (b.rowid IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='bank') )"; +} if ($in_bookkeeping == 'notyet') +{ $sql .= " AND (b.rowid NOT IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='bank') )"; +} $sql .= " ORDER BY b.datev"; //print $sql; @@ -401,6 +407,9 @@ if (! $error && $action == 'writebookkeeping') { $errorforline = 0; + $totalcredit = 0; + $totaldebit = 0; + $db->begin(); // Introduce a protection. Total of tabtp must be total of tabbq @@ -459,6 +468,9 @@ if (! $error && $action == 'writebookkeeping') { $bookkeeping->subledger_account = ''; } + $totaldebit += $bookkeeping->debit; + $totalcredit += $bookkeeping->credit; + $result = $bookkeeping->create($user); if ($result < 0) { if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') // Already exists @@ -565,6 +577,9 @@ if (! $error && $action == 'writebookkeeping') { } } + $totaldebit += $bookkeeping->debit; + $totalcredit += $bookkeeping->credit; + $result = $bookkeeping->create($user); if ($result < 0) { if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') // Already exists @@ -584,6 +599,13 @@ if (! $error && $action == 'writebookkeeping') { } } + if ($totaldebit != $totalcredit) + { + $error++; + $errorforline++; + setEventMessages('Try to insert a non balanced transaction in book for '.$ref.'. Canceled. Surely a bug.', null, 'errors'); + } + if (! $errorforline) { $db->commit(); @@ -596,8 +618,8 @@ if (! $error && $action == 'writebookkeeping') { $MAXNBERRORS=5; if ($error >= $MAXNBERRORS) { - setEventMessages($langs->trans("ErrorTooManyErrorsProcessStopped").' (>'.$MAXNBERRORS.')', null, 'errors'); - break; // Break in the foreach + setEventMessages($langs->trans("ErrorTooManyErrorsProcessStopped").' (>'.$MAXNBERRORS.')', null, 'errors'); + break; // Break in the foreach } } } @@ -626,7 +648,7 @@ if (! $error && $action == 'writebookkeeping') { $param.='&date_endday='.$date_endday; $param.='&date_endmonth='.$date_endmonth; $param.='&date_endyear='.$date_endyear; - $param.='&in_bookeeping='.$in_bookeeping; + $param.='&in_bookkeeping='.$in_bookkeeping; header("Location: ".$_SERVER['PHP_SELF'].($param?'?'.$param:'')); exit; } @@ -674,7 +696,7 @@ if ($action == 'exportcsv') { // ISO and not UTF8 ! // Bank foreach ( $tabbq[$key] as $k => $mt ) { - print '"' . $journal . '"' . $sep; + print '"' . $key . '"' . $sep; print '"' . $date . '"' . $sep; print '"' . $val["type_payment"] . '"' . $sep; print '"' . length_accountg(html_entity_decode($k)) . '"' . $sep; @@ -686,7 +708,8 @@ if ($action == 'exportcsv') { // ISO and not UTF8 ! print '"' . $val['bank_account_ref'] . ' - ' . utf8_decode($companystatic->name) . '"' . $sep; } print '"' . ($mt >= 0 ? price($mt) : '') . '"' . $sep; - print '"' . ($mt < 0 ? price(- $mt) : '') . '"'; + print '"' . ($mt < 0 ? price(- $mt) : '') . '"' . $sep; + print '"' . $journal . '"' . $sep; print "\n"; } @@ -694,7 +717,7 @@ if ($action == 'exportcsv') { // ISO and not UTF8 ! if (is_array($tabtp[$key])) { foreach ( $tabtp[$key] as $k => $mt ) { if ($mt) { - print '"' . $journal . '"' . $sep; + print '"' . $key . '"' . $sep; print '"' . $date . '"' . $sep; print '"' . $val["type_payment"] . '"' . $sep; print '"' . length_accounta(html_entity_decode($k)) . '"' . $sep; @@ -712,13 +735,14 @@ if ($action == 'exportcsv') { // ISO and not UTF8 ! print '"' . $langs->trans('ThirdParty') . " - " . utf8_decode($companystatic->name) . '"' . $sep; } print '"' . ($mt < 0 ? price(- $mt) : '') . '"' . $sep; - print '"' . ($mt >= 0 ? price($mt) : '') . '"'; + print '"' . ($mt >= 0 ? price($mt) : '') . '"' . $sep; + print '"' . $journal . '"' . $sep; print "\n"; } } } else { foreach ( $tabbq[$key] as $k => $mt ) { - print '"' . $journal . '"' . $sep; + print '"' . $key . '"' . $sep; print '"' . $date . '"' . $sep; print '"' . $val["type_payment"] . '"' . $sep; print '"' . length_accountg($conf->global->ACCOUNTING_ACCOUNT_SUSPENSE) . '"' . $sep; @@ -730,7 +754,8 @@ if ($action == 'exportcsv') { // ISO and not UTF8 ! print '"' . $val['bank_account_ref'] . ' - ' . utf8_decode($companystatic->name) . '"' . $sep; } print '"' . ($mt < 0 ? price(- $mt) : '') . '"' . $sep; - print '"' . ($mt >= 0 ? price($mt) : '') . '"'; + print '"' . ($mt >= 0 ? price($mt) : '') . '"' . $sep; + print '"' . $journal . '"' . $sep; print "\n"; } } @@ -769,15 +794,15 @@ if (empty($action) || $action == 'view') { // Test that setup is complete - $sql='SELECT COUNT(rowid) as nb FROM '.MAIN_DB_PREFIX.'bank_account WHERE fk_accountancy_journal IS NULL'; - $resql=$db->query($sql); + $sql = 'SELECT COUNT(rowid) as nb FROM '.MAIN_DB_PREFIX.'bank_account WHERE fk_accountancy_journal IS NULL'; + $resql = $db->query($sql); if ($resql) { - $obj=$db->fetch_object($resql); + $obj = $db->fetch_object($resql); if ($obj->nb > 0) { print '
    '.img_warning().' '.$langs->trans("TheJournalCodeIsNotDefinedOnSomeBankAccount"); - print ' : '.$langs->trans("AccountancyAreaDescBank", 9, ''.$langs->transnoentitiesnoconv("MenuBankCash").''); + print ' : '.$langs->trans("AccountancyAreaDescBank", 9, ''.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("BankAccounts").''); } } else dol_print_error($db); @@ -793,8 +818,9 @@ if (empty($action) || $action == 'view') { print '
    '; - print ''; print ''; + if ($in_bookkeeping == 'notyet') print ''; + else print '' . $langs->trans("WriteBookKeeping") . ''; print '
    '; // TODO Avoid using js. We can use a direct link with $param @@ -1004,141 +1030,88 @@ function getSourceDocRef($val, $typerecord) // Defined the docref into $ref (We start with $val['ref'] by default and we complete according to other data) // WE MUST HAVE SAME REF FOR ALL LINES WE WILL RECORD INTO THE BOOKKEEPING - $reflabel = $val['ref']; - if ($reflabel == '(SupplierInvoicePayment)' || $reflabel == '(SupplierInvoicePaymentBack)') { - $reflabel = $langs->trans('Supplier'); + $ref = $val['ref']; + if ($ref == '(SupplierInvoicePayment)' || $ref == '(SupplierInvoicePaymentBack)') { + $ref = $langs->trans('Supplier'); } - if ($reflabel == '(CustomerInvoicePayment)' || $reflabel == '(CustomerInvoicePaymentBack)') { - $reflabel = $langs->trans('Customer'); + if ($ref == '(CustomerInvoicePayment)' || $ref == '(CustomerInvoicePaymentBack)') { + $ref = $langs->trans('Customer'); } - if ($reflabel == '(SocialContributionPayment)') { - $reflabel = $langs->trans('SocialContribution'); + if ($ref == '(SocialContributionPayment)') { + $ref = $langs->trans('SocialContribution'); } - if ($reflabel == '(DonationPayment)') { - $reflabel = $langs->trans('Donation'); + if ($ref == '(DonationPayment)') { + $ref = $langs->trans('Donation'); } - if ($reflabel == '(SubscriptionPayment)') { - $reflabel = $langs->trans('Subscription'); + if ($ref == '(SubscriptionPayment)') { + $ref = $langs->trans('Subscription'); } - if ($reflabel == '(ExpenseReportPayment)') { - $reflabel = $langs->trans('Employee'); + if ($ref == '(ExpenseReportPayment)') { + $ref = $langs->trans('Employee'); } - if ($reflabel == '(payment_salary)') { - $reflabel = $langs->trans('Employee'); + if ($ref == '(payment_salary)') { + $ref = $langs->trans('Employee'); } - $ref=$reflabel; + + $sqlmid = ''; if ($typerecord == 'payment') { $sqlmid = 'SELECT payfac.fk_facture as id, f.facnumber as ref'; $sqlmid .= " FROM ".MAIN_DB_PREFIX."paiement_facture as payfac, ".MAIN_DB_PREFIX."facture as f"; $sqlmid .= " WHERE payfac.fk_facture = f.rowid AND payfac.fk_paiement=" . $val["paymentid"]; - dol_syslog("accountancy/journal/bankjournal.php::sqlmid=" . $sqlmid, LOG_DEBUG); - $resultmid = $db->query($sqlmid); - if ($resultmid) { - $ref=$langs->trans("Invoice"); - while ($objmid = $db->fetch_object($resultmid)) - { - $ref.=' '.$objmid->ref; - } - } - else dol_print_error($db); + $ref = $langs->trans("Invoice"); } elseif ($typerecord == 'payment_supplier') { $sqlmid = 'SELECT payfac.fk_facturefourn as id, f.ref'; $sqlmid .= " FROM " . MAIN_DB_PREFIX . "paiementfourn_facturefourn as payfac, ".MAIN_DB_PREFIX."facture_fourn as f"; $sqlmid .= " WHERE payfac.fk_facturefourn = f.rowid AND payfac.fk_paiementfourn=" . $val["paymentsupplierid"]; - dol_syslog("accountancy/journal/bankjournal.php::sqlmid=" . $sqlmid, LOG_DEBUG); - $resultmid = $db->query($sqlmid); - if ($resultmid) { - $ref=$langs->trans("SupplierInvoice"); - while($objmid = $db->fetch_object($resultmid)) - { - $ref.=' '.$objmid->ref; - } - } - else dol_print_error($db); + $ref = $langs->trans("SupplierInvoice"); } elseif ($typerecord == 'payment_expensereport') { $sqlmid = 'SELECT e.rowid as id, e.ref'; $sqlmid .= " FROM " . MAIN_DB_PREFIX . "payment_expensereport as pe, " . MAIN_DB_PREFIX . "expensereport as e"; $sqlmid .= " WHERE pe.rowid=" . $val["paymentexpensereport"]." AND pe.fk_expensereport = e.rowid"; - dol_syslog("accountancy/journal/bankjournal.php::sqlmid=" . $sqlmid, LOG_DEBUG); - $resultmid = $db->query($sqlmid); - if ($resultmid) { - $ref=$langs->trans("ExpenseReport"); - while($objmid = $db->fetch_object($resultmid)) - { - $ref.=' '.$objmid->ref; - } - } - else dol_print_error($db); + $ref = $langs->trans("ExpenseReport"); } elseif ($typerecord == 'payment_salary') { $sqlmid = 'SELECT s.rowid as ref'; $sqlmid .= " FROM " . MAIN_DB_PREFIX . "payment_salary as s"; $sqlmid .= " WHERE s.rowid=" . $val["paymentsalid"]; - dol_syslog("accountancy/journal/bankjournal.php::sqlmid=" . $sqlmid, LOG_DEBUG); - $resultmid = $db->query($sqlmid); - if ($resultmid) { - $ref=$langs->trans("SalaryPayment"); - while ($objmid = $db->fetch_object($resultmid)) - { - $ref.=' '.$objmid->ref; - } - } - else dol_print_error($db); + $ref = $langs->trans("SalaryPayment"); } elseif ($typerecord == 'payment_vat') { $sqlmid = 'SELECT v.rowid as ref'; $sqlmid .= " FROM " . MAIN_DB_PREFIX . "tva as v"; $sqlmid .= " WHERE v.rowid=" . $val["paymentvatid"]; - dol_syslog("accountancy/journal/bankjournal.php::sqlmid=" . $sqlmid, LOG_DEBUG); - $resultmid = $db->query($sqlmid); - if ($resultmid) { - $ref=$langs->trans("PaymentVat"); - while ($objmid = $db->fetch_object($resultmid)) - { - $ref.=' '.$objmid->ref; - } - } - else dol_print_error($db); + $ref = $langs->trans("PaymentVat"); } elseif ($typerecord == 'payment_donation') { $sqlmid = 'SELECT payd.fk_donation as ref'; $sqlmid .= " FROM " . MAIN_DB_PREFIX . "payment_donation as payd"; $sqlmid .= " WHERE payd.fk_donation=" . $val["paymentdonationid"]; - dol_syslog("accountancy/journal/bankjournal.php::sqlmid=" . $sqlmid, LOG_DEBUG); - $resultmid = $db->query($sqlmid); - if ($resultmid) { - $ref=$langs->trans("Donation").' '; - while ($objmid = $db->fetch_object($resultmid)) - { - $ref.=' '.$objmid->ref; - } - } - else dol_print_error($db); + $ref = $langs->trans("Donation").' '; } elseif ($typerecord == 'payment_various') { $sqlmid = 'SELECT v.rowid as ref'; $sqlmid .= " FROM " . MAIN_DB_PREFIX . "payment_various as v"; $sqlmid .= " WHERE v.rowid=" . $val["paymentvariousid"]; - dol_syslog("accountancy/journal/bankjournal.php::sqlmid=" . $sqlmid, LOG_DEBUG); - $resultmid = $db->query($sqlmid); - if ($resultmid) { - $ref=$langs->trans("VariousPayment"); - while ($objmid = $db->fetch_object($resultmid)) - { - $ref.=' '.$objmid->ref; - } - } - else dol_print_error($db); + $ref = $langs->trans("VariousPayment"); } + dol_syslog("accountancy/journal/bankjournal.php::sqlmid=" . $sqlmid, LOG_DEBUG); + $resultmid = $db->query($sqlmid); + if ($resultmid) { + while ($objmid = $db->fetch_object($resultmid)) + { + $ref.=' '.$objmid->ref; + } + } + else dol_print_error($db); return $ref; } diff --git a/htdocs/accountancy/journal/expensereportsjournal.php b/htdocs/accountancy/journal/expensereportsjournal.php index c73286a8bdd..10755fe2c9c 100644 --- a/htdocs/accountancy/journal/expensereportsjournal.php +++ b/htdocs/accountancy/journal/expensereportsjournal.php @@ -101,10 +101,15 @@ $sql .= " AND erd.fk_code_ventilation > 0"; $sql .= " AND er.entity IN (" . getEntity('expensereport', 0) . ")"; // We don't share object for accountancy if ($date_start && $date_end) $sql .= " AND er.date_debut >= '" . $db->idate($date_start) . "' AND er.date_debut <= '" . $db->idate($date_end) . "'"; +// Already in bookkeeping or not if ($in_bookkeeping == 'already') +{ $sql .= " AND er.rowid IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='expense_report')"; +} if ($in_bookkeeping == 'notyet') +{ $sql .= " AND er.rowid NOT IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='expense_report')"; +} $sql .= " ORDER BY er.date_debut"; dol_syslog('accountancy/journal/expensereportsjournal.php', LOG_DEBUG); @@ -183,6 +188,9 @@ if ($action == 'writebookkeeping') { { $errorforline = 0; + $totalcredit = 0; + $totaldebit = 0; + $db->begin(); // Thirdparty @@ -209,6 +217,9 @@ if ($action == 'writebookkeeping') { $bookkeeping->journal_label = $journal_label; $bookkeeping->fk_user_author = $user->id; + $totaldebit += $bookkeeping->debit; + $totalcredit += $bookkeeping->credit; + $result = $bookkeeping->create($user); if ($result < 0) { if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') // Already exists @@ -255,6 +266,9 @@ if ($action == 'writebookkeeping') { $bookkeeping->journal_label = $journal_label; $bookkeeping->fk_user_author = $user->id; + $totaldebit += $bookkeeping->debit; + $totalcredit += $bookkeeping->credit; + $result = $bookkeeping->create($user); if ($result < 0) { if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') // Already exists @@ -307,6 +321,9 @@ if ($action == 'writebookkeeping') { $bookkeeping->journal_label = $journal_label; $bookkeeping->fk_user_author = $user->id; + $totaldebit += $bookkeeping->debit; + $totalcredit += $bookkeeping->credit; + $result = $bookkeeping->create($user); if ($result < 0) { if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') // Already exists @@ -327,6 +344,13 @@ if ($action == 'writebookkeeping') { } } + if ($totaldebit != $totalcredit) + { + $error++; + $errorforline++; + setEventMessages('Try to insert a non balanced transaction in book for '.$val["ref"].'. Canceled. Surely a bug.', null, 'errors'); + } + if (! $errorforline) { $db->commit(); @@ -343,6 +367,8 @@ if ($action == 'writebookkeeping') { } } + $tabpay = $taber; + if (empty($error) && count($tabpay) > 0) { setEventMessages($langs->trans("GeneralLedgerIsWritten"), null, 'mesgs'); } @@ -367,7 +393,7 @@ if ($action == 'writebookkeeping') { $param.='&date_endday='.$date_endday; $param.='&date_endmonth='.$date_endmonth; $param.='&date_endyear='.$date_endyear; - $param.='&in_bookeeping='.$in_bookeeping; + $param.='&in_bookkeeping='.$in_bookkeeping; header("Location: ".$_SERVER['PHP_SELF'].($param?'?'.$param:'')); exit; } @@ -502,7 +528,7 @@ if (empty($action) || $action == 'view') { $description.= $langs->trans("DescJournalOnlyBindedVisible").'
    '; $listofchoices=array('already'=>$langs->trans("AlreadyInGeneralLedger"), 'notyet'=>$langs->trans("NotYetInGeneralLedger")); - $period = $form->select_date($date_start, 'date_start', 0, 0, 0, '', 1, 0, 1) . ' - ' . $form->select_date($date_end, 'date_end', 0, 0, 0, '', 1, 0, 1). ' - ' .$langs->trans("AlreadyInGeneralLedger").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1); + $period = $form->select_date($date_start, 'date_start', 0, 0, 0, '', 1, 0, 1) . ' - ' . $form->select_date($date_end, 'date_end', 0, 0, 0, '', 1, 0, 1). ' - ' .$langs->trans("JournalizationInLedgerStatus").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1); $varlink = 'id_journal=' . $id_journal; @@ -510,15 +536,16 @@ if (empty($action) || $action == 'view') { // Button to write into Ledger if (empty($conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT) || $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT == '-1') { - print '
    '.img_warning().' '.$langs->trans("SomeMandatoryStepsOfSetupWereNotDone"); - print ' : '.$langs->trans("AccountancyAreaDescMisc", 4, ''.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").''); + print '
    '.img_warning().' '.$langs->trans("SomeMandatoryStepsOfSetupWereNotDone"); + print ' : '.$langs->trans("AccountancyAreaDescMisc", 4, ''.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").''); } print '
    '; if (empty($conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT) || $conf->global->SALARIES_ACCOUNTING_ACCOUNT_PAYMENT == '-1') { - print ''; + print ''; } else { - print ''; + if ($in_bookkeeping == 'notyet') print ''; + else print '' . $langs->trans("WriteBookKeeping") . ''; } //print ''; print '
    '; @@ -544,7 +571,7 @@ if (empty($action) || $action == 'view') { print '
    '; $i = 0; - print '
    '; + print '
    '; print "
    ' . $langs->trans("Total") . '' . $codeCompta . ''; + print ''; print img_edit(); print ''; - print $formaccounting->select_account($objp->aarowid_suggest, 'codeventil'.$objp->rowid, 1, array(), 0, 0, 'maxwidth300 maxwidthonsmartphone', 'cachewithshowemptyone'); + print $formaccounting->select_account($objp->aarowid_suggest, 'codeventil'.$objp->rowid, 1, array(), 0, 0, 'codeventil maxwidth300 maxwidthonsmartphone', 'cachewithshowemptyone'); print ''; - print 'aarowid ? "checked" : "") . '/>'; + print 'aarowid ? "checked" : "") . '/>'; print '
    "; print ""; print ""; diff --git a/htdocs/accountancy/journal/purchasesjournal.php b/htdocs/accountancy/journal/purchasesjournal.php index 0f9081bdc98..0e82566b22a 100644 --- a/htdocs/accountancy/journal/purchasesjournal.php +++ b/htdocs/accountancy/journal/purchasesjournal.php @@ -56,9 +56,18 @@ $now = dol_now(); if ($user->societe_id > 0) accessforbidden(); +$hookmanager->initHooks(array('purchasesjournal')); +$parameters=array(); + /* * Actions */ +$reshook=$hookmanager->executeHooks('doActions',$parameters,$user,$action); // Note that $action and $object may have been modified by some hooks + + +/* + * Views + */ // Get informations of journal $accountingjournalstatic = new AccountingJournal($db); @@ -106,10 +115,15 @@ if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { } if ($date_start && $date_end) $sql .= " AND f.datef >= '" . $db->idate($date_start) . "' AND f.datef <= '" . $db->idate($date_end) . "'"; +// Already in bookkeeping or not if ($in_bookkeeping == 'already') - $sql .= " AND f.rowid IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='supplier_invoice')"; +{ + $sql .= " AND f.rowid IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='supplier_invoice')"; +} if ($in_bookkeeping == 'notyet') - $sql .= " AND f.rowid NOT IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='supplier_invoice')"; +{ + $sql .= " AND f.rowid NOT IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='supplier_invoice')"; +} $sql .= " ORDER BY f.datef"; dol_syslog('accountancy/journal/purchasesjournal.php', LOG_DEBUG); @@ -123,6 +137,7 @@ if ($result) { $tablocaltax1 = array (); $tablocaltax2 = array (); $tabcompany = array (); + $tabother = array(); $num = $db->num_rows($result); @@ -147,6 +162,9 @@ if ($result) { $vatdata = getTaxesFromId($obj->tva_tx.($obj->vat_src_code?' ('.$obj->vat_src_code.')':''), $mysoc, $mysoc, 0); $compta_tva = (! empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $cpttva); + $compta_localtax1 = (! empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $cpttva); + $compta_localtax2 = (! empty($vatdata['accountancy_code_buy']) ? $vatdata['accountancy_code_buy'] : $cpttva); + $compta_counterpart_tva_npr = (! empty($conf->global->ACCOUNTING_COUNTERPART_VAT_NPR)) ? $conf->global->ACCOUNTING_COUNTERPART_VAT_NPR : 'NotDefined'; // Define array to display all VAT rates that use this accounting account $compta_tva if (price2num($obj->tva_tx) || ! empty($obj->vat_src_code)) @@ -154,6 +172,9 @@ if ($result) { $def_tva[$obj->rowid][$compta_tva][vatrate($obj->tva_tx).($obj->vat_src_code?' ('.$obj->vat_src_code.')':'')]=(vatrate($obj->tva_tx).($obj->vat_src_code?' ('.$obj->vat_src_code.')':'')); } + $line = new SupplierInvoiceLine($db); + $line->fetch($obj->fdid); + $tabfac[$obj->rowid]["date"] = $db->jdate($obj->df); $tabfac[$obj->rowid]["datereg"] = $db->jdate($obj->dlr); $tabfac[$obj->rowid]["ref"] = $obj->ref_supplier . ' (' . $obj->ref . ')'; @@ -174,6 +195,10 @@ if ($result) { $tabttc[$obj->rowid][$compta_soc] += $obj->total_ttc; $tabht[$obj->rowid][$compta_prod] += $obj->total_ht; $tabtva[$obj->rowid][$compta_tva] += $obj->total_tva; + if (! empty($line->tva_npr)) // Add an entry for counterpart + { + $tabother[$obj->rowid][$compta_counterpart_tva_npr] += $obj->total_tva; + } $tablocaltax1[$obj->rowid][$compta_localtax1] += $obj->total_localtax1; $tablocaltax2[$obj->rowid][$compta_localtax2] += $obj->total_localtax2; $tabcompany[$obj->rowid] = array ( @@ -181,9 +206,9 @@ if ($result) { 'name' => $obj->name, 'code_fournisseur' => $obj->code_fournisseur, 'code_compta_fournisseur' => $compta_soc - ); + ); - $i ++; + $i++; } } else { dol_print_error($db); @@ -195,8 +220,12 @@ if ($action == 'writebookkeeping') { $error = 0; foreach ($tabfac as $key => $val) { // Loop on each invoice + $errorforline = 0; + $totalcredit = 0; + $totaldebit = 0; + $db->begin(); $companystatic = new Societe($db); @@ -242,6 +271,9 @@ if ($action == 'writebookkeeping') { $bookkeeping->journal_label = $journal_label; $bookkeeping->fk_user_author = $user->id; + $totaldebit += $bookkeeping->debit; + $totalcredit += $bookkeeping->credit; + $result = $bookkeeping->create($user); if ($result < 0) { if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') // Already exists @@ -290,6 +322,9 @@ if ($action == 'writebookkeeping') { $bookkeeping->journal_label = $journal_label; $bookkeeping->fk_user_author = $user->id; + $totaldebit += $bookkeeping->debit; + $totalcredit += $bookkeeping->credit; + $result = $bookkeeping->create($user); if ($result < 0) { if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') // Already exists @@ -322,6 +357,56 @@ if ($action == 'writebookkeeping') { if ($numtax == 2) $arrayofvat = $tablocaltax2; foreach ( $arrayofvat[$key] as $k => $mt ) { + if ($mt) { + $bookkeeping = new BookKeeping($db); + $bookkeeping->doc_date = $val["date"]; + $bookkeeping->date_lim_reglement = $val["datereg"]; + $bookkeeping->doc_ref = $val["refsologest"]; + $bookkeeping->date_create = $now; + $bookkeeping->doc_type = 'supplier_invoice'; + $bookkeeping->fk_doc = $key; + $bookkeeping->fk_docdet = 0; // Useless, can be several lines that are source of this record to add + $bookkeeping->thirdparty_code = $companystatic->code_fournisseur; + $bookkeeping->subledger_account = ''; + $bookkeeping->subledger_label = ''; + $bookkeeping->numero_compte = $k; + $bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->refsupplier . ' - ' . $langs->trans("VAT").' '.join(', ',$def_tva[$key][$k]) .' %' . ($numtax?' - Localtax '.$numtax:''); + $bookkeeping->montant = $mt; + $bookkeeping->sens = ($mt < 0) ? 'C' : 'D'; + $bookkeeping->debit = ($mt > 0) ? $mt : 0; + $bookkeeping->credit = ($mt <= 0) ? -$mt : 0; + $bookkeeping->code_journal = $journal; + $bookkeeping->journal_label = $journal_label; + $bookkeeping->fk_user_author = $user->id; + + $totaldebit += $bookkeeping->debit; + $totalcredit += $bookkeeping->credit; + + $result = $bookkeeping->create($user); + if ($result < 0) { + if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') // Already exists + { + $error++; + $errorforline++; + //setEventMessages('Transaction for ('.$bookkeeping->doc_type.', '.$bookkeeping->fk_doc.', '.$bookkeeping->fk_docdet.') were already recorded', null, 'warnings'); + } + else + { + $error++; + $errorforline++; + setEventMessages($bookkeeping->error, $bookkeeping->errors, 'errors'); + } + } + } + } + } + } + + // Counterpart of VAT for VAT NPR + // var_dump($tabother); + if (! $errorforline) + { + foreach ( $tabother[$key] as $k => $mt ) { if ($mt) { $bookkeeping = new BookKeeping($db); $bookkeeping->doc_date = $val["date"]; @@ -335,7 +420,7 @@ if ($action == 'writebookkeeping') { $bookkeeping->subledger_account = ''; $bookkeeping->subledger_label = ''; $bookkeeping->numero_compte = $k; - $bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->refsupplier . ' - ' . $langs->trans("VAT").' '.join(', ',$def_tva[$key][$k]) .' %' . ($numtax?' - Localtax '.$numtax:''); + $bookkeeping->label_operation = dol_trunc($companystatic->name, 16) . ' - ' . $invoicestatic->refsupplier . ' - ' . $langs->trans("VAT").' NPR'; $bookkeeping->montant = $mt; $bookkeeping->sens = ($mt < 0) ? 'C' : 'D'; $bookkeeping->debit = ($mt > 0) ? $mt : 0; @@ -344,6 +429,9 @@ if ($action == 'writebookkeeping') { $bookkeeping->journal_label = $journal_label; $bookkeeping->fk_user_author = $user->id; + $totaldebit += $bookkeeping->debit; + $totalcredit += $bookkeeping->credit; + $result = $bookkeeping->create($user); if ($result < 0) { if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') // Already exists @@ -362,6 +450,12 @@ if ($action == 'writebookkeeping') { } } } + + if ($totaldebit != $totalcredit) + { + $error++; + $errorforline++; + setEventMessages('Try to insert a non balanced transaction in book for '.$invoicestatic->ref.'. Canceled. Surely a bug.', null, 'errors'); } if (! $errorforline) @@ -380,6 +474,8 @@ if ($action == 'writebookkeeping') { } } + $tabpay = $tabfac; + if (empty($error) && count($tabpay) > 0) { setEventMessages($langs->trans("GeneralLedgerIsWritten"), null, 'mesgs'); } @@ -404,7 +500,7 @@ if ($action == 'writebookkeeping') { $param.='&date_endday='.$date_endday; $param.='&date_endmonth='.$date_endmonth; $param.='&date_endyear='.$date_endyear; - $param.='&in_bookeeping='.$in_bookeeping; + $param.='&in_bookkeeping='.$in_bookkeeping; header("Location: ".$_SERVER['PHP_SELF'].($param?'?'.$param:'')); exit; } @@ -502,6 +598,25 @@ if ($action == 'exportcsv') { print "\n"; } } + + // VAT counterpart for NPR + foreach ( $tabother[$key] as $k => $mt ) { + if ($mt) { + print '"' . $key . '"' . $sep; + print '"' . $date . '"' . $sep; + print '"' . $val["refsologest"] . '"' . $sep; + print '"' . utf8_decode ( dol_trunc($companystatic->name, 32) ). '"' . $sep; + print '"' . length_accounta(html_entity_decode($k)) . '"' . $sep; + print '"' . length_accounta(html_entity_decode($k)) . '"' . $sep; + print '"' . length_accounta(html_entity_decode($k)) . '"' . $sep; + print '"' . $langs->trans("Code_tiers") . '"' . $sep; + print '"' . utf8_decode ( dol_trunc($companystatic->name, 16) ) . ' - ' . $val["refsuppliersologest"] . ' - ' . $langs->trans("VAT") . ' NPR"' . $sep; + print '"' . ($mt < 0 ? price(- $mt) : '') . '"' . $sep; + print '"' . ($mt >= 0 ? price($mt) : '') . '"'. $sep; + print '"' . $journal . '"' ; + print "\n"; + } + } } } } @@ -523,7 +638,7 @@ if (empty($action) || $action == 'view') { } $listofchoices=array('already'=>$langs->trans("AlreadyInGeneralLedger"), 'notyet'=>$langs->trans("NotYetInGeneralLedger")); - $period = $form->select_date($date_start, 'date_start', 0, 0, 0, '', 1, 0, 1) . ' - ' . $form->select_date($date_end, 'date_end', 0, 0, 0, '', 1, 0, 1). ' - ' .$langs->trans("AlreadyInGeneralLedger").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1); + $period = $form->select_date($date_start, 'date_start', 0, 0, 0, '', 1, 0, 1) . ' - ' . $form->select_date($date_end, 'date_end', 0, 0, 0, '', 1, 0, 1). ' - ' .$langs->trans("JournalizationInLedgerStatus").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1); $varlink = 'id_journal=' . $id_journal; @@ -535,13 +650,14 @@ if (empty($action) || $action == 'view') { print ' : '.$langs->trans("AccountancyAreaDescMisc", 4, ''.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").''); } print '
    '; + print ''; if (empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER) || $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == '-1') { print ''; } else { - print ''; + if ($in_bookkeeping == 'notyet') print ''; + else print '' . $langs->trans("WriteBookKeeping") . ''; } - print ''; print '
    '; // TODO Avoid using js. We can use a direct link with $param @@ -668,30 +784,59 @@ if (empty($action) || $action == 'view') { foreach ( $arrayofvat[$key] as $k => $mt ) { if ($mt) { - print ''; - print ""; - print ""; - print ""; - // Account - print "'; + print ""; + print ""; + print ""; + // Account + print ""; + // Subledger account + print "'; + print ""; + print '"; + print '"; + print ""; } - else print $accountoshow; - print ""; - // Subledger account - print "'; - print ""; - print '"; - print '"; - print ""; - } } } + + // VAT counterpart for NPR + foreach ( $tabother[$key] as $k => $mt ) { + print ''; + print ""; + print ""; + print ""; + $companystatic->id = $tabcompany[$key]['id']; + $companystatic->name = $tabcompany[$key]['name']; + $companystatic->supplier_code = $tabcompany[$key]['code_supplier']; + // Account + print "'; + // Subledger account + print "'; + print ""; + print '"; + print '"; + print ""; + } + } print "
    " . $date . "" . $invoicestatic->getNomUrl(1) . ""; - $accountoshow = length_accountg($k); - if (empty($accountoshow) || $accountoshow == 'NotDefined') - { - print ''.$langs->trans("VATAccountNotDefined").''; + print '
    " . $date . "" . $invoicestatic->getNomUrl(1) . ""; + $accountoshow = length_accountg($k); + if (empty($accountoshow) || $accountoshow == 'NotDefined') + { + print ''.$langs->trans("VATAccountNotDefined").' ('.$langs->trans("Purchase").')'.''; + } + else print $accountoshow; + print ""; + print '"; + print $companystatic->getNomUrl(0, 'supplier', 16) . ' - ' . $invoicestatic->refsupplier . ' - ' . $langs->trans("VAT"). ' '.join(', ',$def_tva[$key][$k]).' %'.($numtax?' - Localtax '.$numtax:''); + print "' . ($mt >= 0 ? price($mt) : '') . "' . ($mt < 0 ? price(- $mt) : '') . "
    "; - print '" . $companystatic->getNomUrl(0, 'supplier', 16) . ' - ' . $invoicestatic->refsupplier . ' - ' . $langs->trans("VAT"). ' '.join(', ',$def_tva[$key][$k]).' %'.($numtax?' - Localtax '.$numtax:''); - print "' . ($mt >= 0 ? price($mt) : '') . "' . ($mt < 0 ? price(- $mt) : '') . "
    " . $date . "" . $invoicestatic->getNomUrl(1) . ""; + $accountoshow = length_accountg($k); + if (empty($accountoshow) || $accountoshow == 'NotDefined') + { + print ''.$langs->trans("VATAccountNotDefined").' ('.$langs->trans("NPR counterpart").'). Set ACCOUNTING_COUNTERPART_VAT_NPR to the subvention account'.''; + } + else print $accountoshow; + print '"; + print '" . $companystatic->getNomUrl(0, 'supplier', 16) . ' - ' . $invoicestatic->refsupplier . ' - ' . $langs->trans("VAT") . " NPR (counterpart)' . ($mt < 0 ? - price(- $mt) : '') . "' . ($mt >= 0 ? price($mt) : '') . "
    "; diff --git a/htdocs/accountancy/journal/sellsjournal.php b/htdocs/accountancy/journal/sellsjournal.php index 42fbb7ff681..4018b570f3d 100644 --- a/htdocs/accountancy/journal/sellsjournal.php +++ b/htdocs/accountancy/journal/sellsjournal.php @@ -111,10 +111,15 @@ if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { $sql .= " AND fd.product_type IN (0,1)"; if ($date_start && $date_end) $sql .= " AND f.datef >= '" . $db->idate($date_start) . "' AND f.datef <= '" . $db->idate($date_end) . "'"; +// Already in bookkeeping or not if ($in_bookkeeping == 'already') - $sql .= " AND f.rowid IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='customer_invoice')"; +{ + $sql .= " AND f.rowid IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='customer_invoice')"; +} if ($in_bookkeeping == 'notyet') - $sql .= " AND f.rowid NOT IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='customer_invoice')"; +{ + $sql .= " AND f.rowid NOT IN (SELECT fk_doc FROM " . MAIN_DB_PREFIX . "accounting_bookkeeping as ab WHERE ab.doc_type='customer_invoice')"; +} $sql .= " ORDER BY f.datef"; dol_syslog('accountancy/journal/sellsjournal.php', LOG_DEBUG); @@ -161,9 +166,10 @@ if ($result) { $def_tva[$obj->rowid][$compta_tva][vatrate($obj->tva_tx).($obj->vat_src_code?' ('.$obj->vat_src_code.')':'')]=(vatrate($obj->tva_tx).($obj->vat_src_code?' ('.$obj->vat_src_code.')':'')); } - // Situation invoices handling $line = new FactureLigne($db); $line->fetch($obj->fdid); + + // Situation invoices handling $prev_progress = $line->get_prev_progress($obj->fdid); if ($obj->type == Facture::TYPE_SITUATION) { // Avoid divide by 0 @@ -193,7 +199,7 @@ if ($result) { $tabttc[$obj->rowid][$compta_soc] += $obj->total_ttc * $situation_ratio; $tabht[$obj->rowid][$compta_prod] += $obj->total_ht * $situation_ratio; - $tabtva[$obj->rowid][$compta_tva] += $obj->total_tva * $situation_ratio; + if (empty($line->tva_npr)) $tabtva[$obj->rowid][$compta_tva] += $obj->total_tva * $situation_ratio; // We ignore line if VAT is a NPR $tablocaltax1[$obj->rowid][$compta_localtax1] += $obj->total_localtax1 * $situation_ratio; $tablocaltax2[$obj->rowid][$compta_localtax2] += $obj->total_localtax2 * $situation_ratio; $tabcompany[$obj->rowid] = array ( @@ -218,6 +224,9 @@ if ($action == 'writebookkeeping') { $errorforline = 0; + $totalcredit = 0; + $totaldebit = 0; + $db->begin(); $companystatic = new Societe($db); @@ -260,6 +269,9 @@ if ($action == 'writebookkeeping') { $bookkeeping->journal_label = $journal_label; $bookkeeping->fk_user_author = $user->id; + $totaldebit += $bookkeeping->debit; + $totalcredit += $bookkeeping->credit; + $result = $bookkeeping->create($user); if ($result < 0) { if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') // Already exists @@ -308,6 +320,9 @@ if ($action == 'writebookkeeping') { $bookkeeping->journal_label = $journal_label; $bookkeeping->fk_user_author = $user->id; + $totaldebit += $bookkeeping->debit; + $totalcredit += $bookkeeping->credit; + $result = $bookkeeping->create($user); if ($result < 0) { if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') // Already exists @@ -343,7 +358,7 @@ if ($action == 'writebookkeeping') { if ($mt) { $bookkeeping = new BookKeeping($db); $bookkeeping->doc_date = $val["date"]; - $bookkeeping->date_lim_reglement = $val["datereg"]; + $bookkeeping->date_lim_reglement = $val["datereg"]; $bookkeeping->doc_ref = $val["ref"]; $bookkeeping->date_create = $now; $bookkeeping->doc_type = 'customer_invoice'; @@ -362,6 +377,9 @@ if ($action == 'writebookkeeping') { $bookkeeping->journal_label = $journal_label; $bookkeeping->fk_user_author = $user->id; + $totaldebit += $bookkeeping->debit; + $totalcredit += $bookkeeping->credit; + $result = $bookkeeping->create($user); if ($result < 0) { if ($bookkeeping->error == 'BookkeepingRecordAlreadyExists') // Already exists @@ -382,6 +400,13 @@ if ($action == 'writebookkeeping') { } } + if ($totaldebit != $totalcredit) + { + $error++; + $errorforline++; + setEventMessages('Try to insert a non balanced transaction in book for '.$invoicestatic->ref.'. Canceled. Surely a bug.', null, 'errors'); + } + if (! $errorforline) { $db->commit(); @@ -399,6 +424,8 @@ if ($action == 'writebookkeeping') { } + $tabpay = $tabfac; + if (empty($error) && count($tabpay) > 0) { setEventMessages($langs->trans("GeneralLedgerIsWritten"), null, 'mesgs'); } @@ -423,7 +450,7 @@ if ($action == 'writebookkeeping') { $param.='&date_endday='.$date_endday; $param.='&date_endmonth='.$date_endmonth; $param.='&date_endyear='.$date_endyear; - $param.='&in_bookeeping='.$in_bookeeping; + $param.='&in_bookkeeping='.$in_bookkeeping; header("Location: ".$_SERVER['PHP_SELF'].($param?'?'.$param:'')); exit; } @@ -542,7 +569,7 @@ if (empty($action) || $action == 'view') { $description .= $langs->trans("DepositsAreIncluded"); $listofchoices=array('already'=>$langs->trans("AlreadyInGeneralLedger"), 'notyet'=>$langs->trans("NotYetInGeneralLedger")); - $period = $form->select_date($date_start, 'date_start', 0, 0, 0, '', 1, 0, 1) . ' - ' . $form->select_date($date_end, 'date_end', 0, 0, 0, '', 1, 0, 1). ' - ' .$langs->trans("AlreadyInGeneralLedger").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1); + $period = $form->select_date($date_start, 'date_start', 0, 0, 0, '', 1, 0, 1) . ' - ' . $form->select_date($date_end, 'date_end', 0, 0, 0, '', 1, 0, 1). ' - ' .$langs->trans("JournalizationInLedgerStatus").' '. $form->selectarray('in_bookkeeping', $listofchoices, $in_bookkeeping, 1); $varlink = 'id_journal=' . $id_journal; @@ -554,13 +581,14 @@ if (empty($action) || $action == 'view') { print ' : '.$langs->trans("AccountancyAreaDescMisc", 4, ''.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("MenuAccountancy").'-'.$langs->transnoentitiesnoconv("Setup")."-".$langs->transnoentitiesnoconv("MenuDefaultAccounts").''); } print '
    '; + print ''; if (empty($conf->global->ACCOUNTING_ACCOUNT_CUSTOMER) || $conf->global->ACCOUNTING_ACCOUNT_CUSTOMER == '-1') { print ''; } else { - print ''; + if ($in_bookkeeping == 'notyet') print ''; + else print '' . $langs->trans("WriteBookKeeping") . ''; } - print ''; print '
    '; // TODO Avoid using js. We can use a direct link with $param @@ -691,7 +719,7 @@ if (empty($action) || $action == 'view') { $accountoshow = length_accountg($k); if (empty($accountoshow) || $accountoshow == 'NotDefined') { - print ''.$langs->trans("VATAccountNotDefined").''; + print ''.$langs->trans("VATAccountNotDefined").' ('.$langs->trans("Sale").')'.''; } else print $accountoshow; print ""; diff --git a/htdocs/accountancy/supplier/card.php b/htdocs/accountancy/supplier/card.php index d36ae5e2543..f74165251f3 100644 --- a/htdocs/accountancy/supplier/card.php +++ b/htdocs/accountancy/supplier/card.php @@ -37,6 +37,9 @@ $langs->load("bills"); $langs->load("accountancy"); $action = GETPOST('action', 'alpha'); +$cancel = GETPOST('cancel', 'alpha'); +$backtopage = GETPOST('backtopage', 'alpha'); + $codeventil = GETPOST('codeventil'); $id = GETPOST('id'); @@ -49,8 +52,10 @@ if ($user->societe_id > 0) * Actions */ -if ($action == 'ventil' && $user->rights->accounting->bind->write) { - if (! GETPOST('cancel', 'alpha')) { +if ($action == 'ventil' && $user->rights->accounting->bind->write) +{ + if (! $cancel) + { if ($codeventil < 0) $codeventil = 0; $sql = " UPDATE " . MAIN_DB_PREFIX . "facture_fourn_det"; @@ -64,6 +69,11 @@ if ($action == 'ventil' && $user->rights->accounting->bind->write) { else { setEventMessages($langs->trans("RecordModifiedSuccessfully"), null, 'mesgs'); + if ($backtopage) + { + header("Location: ".$backtopage); + exit(); + } } } else { header("Location: ./lines.php"); @@ -111,6 +121,7 @@ if (! empty($id)) { print '' . "\n"; print ''; print ''; + print ''; print load_fiche_titre($langs->trans('SuppliersVentilation'), '', 'title_setup'); diff --git a/htdocs/accountancy/supplier/index.php b/htdocs/accountancy/supplier/index.php index 74f071836aa..6aa043c1e26 100644 --- a/htdocs/accountancy/supplier/index.php +++ b/htdocs/accountancy/supplier/index.php @@ -309,7 +309,6 @@ if ($conf->global->MAIN_FEATURES_LEVEL > 0) // This part of code looks strange. print_fiche_titre($langs->trans("OtherInfo"), '', ''); - print "
    \n"; print '
    '; print ''; print ''; diff --git a/htdocs/accountancy/supplier/lines.php b/htdocs/accountancy/supplier/lines.php index 78b9320fdb1..1d1d451f9ae 100644 --- a/htdocs/accountancy/supplier/lines.php +++ b/htdocs/accountancy/supplier/lines.php @@ -368,13 +368,13 @@ if ($result) { print ''; print ''; - print ''; - print ''; + print ''; - print ''; - print ''; + print ''; + print ''; print ''; print ""; diff --git a/htdocs/accountancy/supplier/list.php b/htdocs/accountancy/supplier/list.php index f63e0a03d4e..5d9871eecfb 100644 --- a/htdocs/accountancy/supplier/list.php +++ b/htdocs/accountancy/supplier/list.php @@ -100,6 +100,8 @@ $accounting = new AccountingAccount($db); $aarowid_s = $accounting->fetch('', $conf->global->ACCOUNTING_SERVICE_BUY_ACCOUNT, 1); $aarowid_p = $accounting->fetch('', $conf->global->ACCOUNTING_PRODUCT_BUY_ACCOUNT, 1); +$chartaccountcode = dol_getIdFromCode($db, $conf->global->CHARTOFACCOUNTS, 'accounting_system', 'rowid', 'pcg_version'); + /* * Action @@ -117,39 +119,40 @@ if (empty($reshook)) // Purge search criteria if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All test are required to be compatible with all browsers { - $search_lineid = ''; - $search_ref = ''; - $search_invoice = ''; - $search_label = ''; - $search_desc = ''; - $search_amount = ''; - $search_account = ''; - $search_vat = ''; - $search_day = ''; - $search_month = ''; - $search_year = ''; + $search_lineid = ''; + $search_ref = ''; + $search_invoice = ''; + $search_label = ''; + $search_desc = ''; + $search_amount = ''; + $search_account = ''; + $search_vat = ''; + $search_day = ''; + $search_month = ''; + $search_year = ''; } // Mass actions - $objectclass='AccountingAccount'; + $objectclass='AccountingAccount'; $permtoread = $user->rights->accounting->read; $permtodelete = $user->rights->accounting->delete; $uploaddir = $conf->accounting->dir_output; include DOL_DOCUMENT_ROOT.'/core/actions_massactions.inc.php'; } + if ($massaction == 'ventil') { $msg=''; + //print '
    ' . $langs->trans("Processing") . '...
    '; if (! empty($mesCasesCochees)) { $msg = '
    ' . $langs->trans("SelectedLines") . ': '.count($mesCasesCochees).'
    '; $msg.='
    '; - $mesCodesVentilChoisis = $codeventil; $cpt = 0; $ok=0; $ko=0; - foreach ( $mesCasesCochees as $maLigneCochee ) { + foreach ($mesCasesCochees as $maLigneCochee) { $maLigneCourante = explode("_", $maLigneCochee); $monId = $maLigneCourante[0]; $monCompte = GETPOST('codeventil'.$monId); @@ -198,9 +201,17 @@ $formother = new FormOther($db); llxHeader('', $langs->trans("SuppliersVentilation")); +if (empty($chartaccountcode)) +{ + print $langs->trans("ErrorChartOfAccountSystemNotSelected"); + llxFooter(); + $db->close(); + exit; +} + // Supplier Invoice Lines -$sql = "SELECT f.rowid as facid, f.ref, f.ref_supplier, f.libelle as invoice_label, f.datef,"; -$sql.= " l.rowid, l.fk_product, l.description, l.total_ht as price, l.fk_code_ventilation, l.product_type as type_l, l.tva_tx as tva_tx_line, l.vat_src_code,"; +$sql = "SELECT f.rowid as facid, f.ref, f.ref_supplier, f.libelle as invoice_label, f.datef, f.type as ftype,"; +$sql.= " l.rowid, l.fk_product, l.description, l.total_ht, l.fk_code_ventilation, l.product_type as type_l, l.tva_tx as tva_tx_line, l.vat_src_code,"; $sql.= " p.rowid as product_id, p.ref as product_ref, p.label as product_label, p.fk_product_type as type, p.accountancy_code_buy as code_buy, p.tva_tx as tva_tx_prod,"; $sql.= " aa.rowid as aarowid"; $parameters=array(); @@ -209,12 +220,9 @@ $sql.=$hookmanager->resPrint; $sql.= " FROM " . MAIN_DB_PREFIX . "facture_fourn as f"; $sql.= " INNER JOIN " . MAIN_DB_PREFIX . "facture_fourn_det as l ON f.rowid = l.fk_facture_fourn"; $sql.= " LEFT JOIN " . MAIN_DB_PREFIX . "product as p ON p.rowid = l.fk_product"; -$sql.= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON p.accountancy_code_buy = aa.account_number"; -$sql.= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_system as accsys ON accsys.pcg_version = aa.fk_pcg_version"; +$sql.= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON p.accountancy_code_buy = aa.account_number AND aa.fk_pcg_version = '" . $chartaccountcode."'"; $sql.= " WHERE f.fk_statut > 0 AND l.fk_code_ventilation <= 0"; $sql.= " AND product_type <= 2"; -$sql.= " AND (accsys.rowid='" . $conf->global->CHARTOFACCOUNTS . "' OR p.accountancy_code_buy IS NULL OR p.accountancy_code_buy =''OR p.accountancy_code_buy NOT IN - (SELECT aa.account_number FROM " . MAIN_DB_PREFIX . "accounting_account as aa , " . MAIN_DB_PREFIX . "accounting_system as asy WHERE fk_pcg_version = asy.pcg_version AND asy.rowid ='" . $conf->global->CHARTOFACCOUNTS . "'))"; // Add search filter like if ($search_lineid) { $sql .= natural_search("l.rowid", $search_lineid, 1); @@ -253,6 +261,11 @@ else if ($search_year > 0) { $sql.= " AND f.datef BETWEEN '".$db->idate(dol_get_first_day($search_year,1,false))."' AND '".$db->idate(dol_get_last_day($search_year,12,false))."'"; } +if (! empty($conf->global->FACTURE_DEPOSITS_ARE_JUST_PAYMENTS)) { + $sql .= " AND f.type IN (" . FactureFournisseur::TYPE_STANDARD . "," . FactureFournisseur::TYPE_REPLACEMENT . "," . FactureFournisseur::TYPE_CREDIT_NOTE . "," . FactureFournisseur::TYPE_SITUATION . ")"; +} else { + $sql .= " AND f.type IN (" . FactureFournisseur::TYPE_STANDARD . "," . FactureFournisseur::TYPE_REPLACEMENT . "," . FactureFournisseur::TYPE_CREDIT_NOTE . "," . FactureFournisseur::TYPE_DEPOSIT . "," . FactureFournisseur::TYPE_SITUATION . ")"; +} $sql .= " AND f.entity IN (" . getEntity('facture_fourn', 0) . ")"; // We don't share object for accountancy // Add where from hooks @@ -298,7 +311,7 @@ if ($result) { //'presend'=>$langs->trans("SendByMail"), //'builddoc'=>$langs->trans("PDFMerge"), ); - //if ($user->rights->mymodule->supprimer) $arrayofmassactions['delete']=$langs->trans("Delete"); + //if ($user->rights->mymodule->supprimer) $arrayofmassactions['predelete']=$langs->trans("Delete"); //if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array(); $massactionbutton=$form->selectMassAction('ventil', $arrayofmassactions, 1); @@ -315,13 +328,18 @@ if ($result) { print $langs->trans("DescVentilTodoCustomer") . '

    '; + /*$topicmail="Information"; + $modelmail="project"; + $objecttmp=new Project($db); + $trackid='prj'.$object->id; + include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php';*/ + if ($msg) print $msg.'
    '; $moreforfilter = ''; - print '
    '; - - print '
    ' . $langs->trans("Total") . '' . price($objp->total_ht) . '' . vatrate($objp->tva_tx.($objp->vat_src_code?' ('.$objp->vat_src_code.')':'')) . ''; - print $codecompta . ' '; + print '' . vatrate($objp->tva_tx.($objp->vat_src_code?' ('.$objp->vat_src_code.')':'')) . ''; + print $codecompta . ' '; print img_edit(); print '' . $objp->country .'' . $objp->tva_intra . '' . $objp->country .'' . $objp->tva_intra . '
    '."\n"; + print '
    '; + print '
    '."\n"; // We add search filter print ''; @@ -440,7 +458,7 @@ if ($result) { print ''; print ''; // Vat rate @@ -462,15 +480,15 @@ if ($result) { // Suggested accounting account print ''; - // Colonne choix ligne a ventiler + // Column with checkbox print ''; - print ""; + print ''; $i ++; } @@ -482,5 +500,17 @@ if ($result) { print $db->error(); } +// Add code to auto check the box when we select an account +print ''; + llxFooter(); $db->close(); diff --git a/htdocs/adherents/agenda.php b/htdocs/adherents/agenda.php index 1228dc92bf9..61cb960f05c 100644 --- a/htdocs/adherents/agenda.php +++ b/htdocs/adherents/agenda.php @@ -168,7 +168,7 @@ if ($object->id > 0) $filters=array(); $filters['search_agenda_label']=$search_agenda_label; - // TODO Replace this with same code than into listactions.php + // TODO Replace this with same code than into list.php show_actions_done($conf,$langs,$db,$object,null,0,$actioncode, '', $filters, $sortfield, $sortorder); } } diff --git a/htdocs/adherents/card.php b/htdocs/adherents/card.php index 05c1358ddee..73f207abe91 100644 --- a/htdocs/adherents/card.php +++ b/htdocs/adherents/card.php @@ -1211,15 +1211,6 @@ else print ""; } - // Other attributes - $parameters=array(); - $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - if (empty($reshook) && ! empty($extrafields->attribute_label)) - { - print $object->showOptionals($extrafields,'edit',$parameters); - } - // Third party Dolibarr if (! empty($conf->societe->enabled)) { @@ -1246,6 +1237,15 @@ else else print $langs->trans("NoDolibarrAccess"); print ''; + // Other attributes + $parameters=array(); + $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; + if (empty($reshook) && ! empty($extrafields->attribute_label)) + { + print $object->showOptionals($extrafields,'edit',$parameters); + } + print '
    '; - print price($objp->price); + print price($objp->total_ht); print ''; - print $formaccounting->select_account($objp->aarowid_suggest, 'codeventil'.$objp->rowid, 1, array(), 0, 0, 'maxwidth300 maxwidthonsmartphone', 'cachewithshowemptyone'); + print $formaccounting->select_account($objp->aarowid_suggest, 'codeventil'.$objp->rowid, 1, array(), 0, 0, 'codeventil maxwidth300 maxwidthonsmartphone', 'cachewithshowemptyone'); print ''; - print 'aarowid ? "checked" : "") . '/>'; + print 'aarowid ? "checked" : "") . '/>'; print '
    '; dol_fiche_end(); @@ -1487,55 +1487,29 @@ else print ''; } - print ''; - - print '
    '; - print '
    '; - - print '
    '; - print ''; - - // Birthday - print ''; - - // Public - print ''; - - // Categories - if (! empty($conf->categorie->enabled) && ! empty($user->rights->categorie->lire)) + // Date end subscription + print ''; - print ''; + print dol_print_date($object->datefin,'day'); + if ($object->hasDelay()) { + print " ".img_warning($langs->trans("Late")); + } } - - // Other attributes - include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; - - // Date end subscription - print ''; + else + { + if (! $adht->subscription) + { + print $langs->trans("SubscriptionNotRecorded"); + if ($object->statut > 0) print " ".img_warning($langs->trans("Late")); // displays delay Pictogram only if not a draft and not terminated + } + else + { + print $langs->trans("SubscriptionNotReceived"); + if ($object->statut > 0) print " ".img_warning($langs->trans("Late")); // displays delay Pictogram only if not a draft and not terminated + } + } + print ''; // Third party Dolibarr if (! empty($conf->societe->enabled)) @@ -1607,6 +1581,32 @@ else } print ''; + print '
    '.$langs->trans("Birthday").''.dol_print_date($object->birth,'day').'
    '.$langs->trans("Public").''.yn($object->public).'
    '.$langs->trans("SubscriptionEndDate").''; + if ($object->datefin) { - print '
    ' . $langs->trans("Categories") . ''; - print $form->showCategories($object->id, 'member', 1); - print '
    '.$langs->trans("SubscriptionEndDate").''; - if ($object->datefin) - { - print dol_print_date($object->datefin,'day'); - if ($object->hasDelay()) { - print " ".img_warning($langs->trans("Late")); - } - } - else - { - if (! $adht->subscription) - { - print $langs->trans("SubscriptionNotRecorded"); - if ($object->statut > 0) print " ".img_warning($langs->trans("Late")); // displays delay Pictogram only if not a draft and not terminated - } - else - { - print $langs->trans("SubscriptionNotReceived"); - if ($object->statut > 0) print " ".img_warning($langs->trans("Late")); // displays delay Pictogram only if not a draft and not terminated - } - } - print '
    '; + + print '
    '; + print '
    '; + + print '
    '; + print ''; + + // Birthday + print ''; + + // Public + print ''; + + // Categories + if (! empty($conf->categorie->enabled) && ! empty($user->rights->categorie->lire)) + { + print ''; + print ''; + } + + // Other attributes + include DOL_DOCUMENT_ROOT . '/core/tpl/extrafields_view.tpl.php'; + print "
    '.$langs->trans("Birthday").''.dol_print_date($object->birth,'day').'
    '.$langs->trans("Public").''.yn($object->public).'
    ' . $langs->trans("Categories") . ''; + print $form->showCategories($object->id, 'member', 1); + print '
    \n"; print "
    \n"; diff --git a/htdocs/adherents/cartes/carte.php b/htdocs/adherents/cartes/carte.php index 487dfa7f225..59713e20573 100644 --- a/htdocs/adherents/cartes/carte.php +++ b/htdocs/adherents/cartes/carte.php @@ -269,7 +269,8 @@ foreach(array_keys($_Avery_Labels) as $codecards) { $arrayoflabels[$codecards]=$_Avery_Labels[$codecards]['name']; } -print $form->selectarray('model',$arrayoflabels,(GETPOST('model')?GETPOST('model'):$conf->global->ADHERENT_CARD_TYPE),1,0,0); +asort($arrayoflabels); +print $form->selectarray('model', $arrayoflabels, (GETPOST('model')?GETPOST('model'):$conf->global->ADHERENT_CARD_TYPE), 1, 0, 0, '', 0, 0, 0, '', '', 1); print '
    '; print ''; print '
    '; @@ -285,7 +286,8 @@ foreach(array_keys($_Avery_Labels) as $codecards) { $arrayoflabels[$codecards]=$_Avery_Labels[$codecards]['name']; } -print $form->selectarray('model',$arrayoflabels,(GETPOST('model')?GETPOST('model'):$conf->global->ADHERENT_CARD_TYPE),1,0,0); +asort($arrayoflabels); +print $form->selectarray('model',$arrayoflabels,(GETPOST('model')?GETPOST('model'):$conf->global->ADHERENT_CARD_TYPE), 1, 0, 0, '', 0, 0, 0, '', '', 1); print '
    '.$langs->trans("Login").': '; print '
    '; print ''; @@ -302,7 +304,8 @@ foreach(array_keys($_Avery_Labels) as $codecards) { $arrayoflabels[$codecards]=$_Avery_Labels[$codecards]['name']; } -print $form->selectarray('modellabel',$arrayoflabels,(GETPOST('modellabel')?GETPOST('modellabel'):$conf->global->ADHERENT_ETIQUETTE_TYPE),1,0,0); +asort($arrayoflabels); +print $form->selectarray('modellabel',$arrayoflabels,(GETPOST('modellabel')?GETPOST('modellabel'):$conf->global->ADHERENT_ETIQUETTE_TYPE), 1, 0, 0, '', 0, 0, 0, '', '', 1); print '
    '; print ''; print '
    '; diff --git a/htdocs/adherents/class/adherentstats.class.php b/htdocs/adherents/class/adherentstats.class.php index 7fabd2c0ddf..59c51cb1d21 100644 --- a/htdocs/adherents/class/adherentstats.class.php +++ b/htdocs/adherents/class/adherentstats.class.php @@ -79,9 +79,10 @@ class AdherentStats extends Stats * Return the number of proposition by month for a given year * * @param int $year Year + * @param int $format 0=Label of absiss is a translated text, 1=Label of absiss is month number, 2=Label of absiss is first letter of month * @return array Array of nb each month */ - function getNbByMonth($year) + function getNbByMonth($year, $format=0) { global $user; @@ -93,7 +94,7 @@ class AdherentStats extends Stats $sql.= " GROUP BY dm"; $sql.= $this->db->order('dm','DESC'); - return $this->_getNbByMonth($year, $sql); + return $this->_getNbByMonth($year, $sql, $format); } /** @@ -116,12 +117,13 @@ class AdherentStats extends Stats } /** - * Return the number of subscriptions by month for a given year + * Return the number of subscriptions by month for a given year * * @param int $year Year + * @param int $format 0=Label of absiss is a translated text, 1=Label of absiss is month number, 2=Label of absiss is first letter of month * @return array Array of amount each month */ - function getAmountByMonth($year) + function getAmountByMonth($year, $format=0) { global $user; @@ -133,7 +135,7 @@ class AdherentStats extends Stats $sql.= " GROUP BY dm"; $sql.= $this->db->order('dm','DESC'); - return $this->_getAmountByMonth($year, $sql); + return $this->_getAmountByMonth($year, $sql, $format); } /** diff --git a/htdocs/adherents/class/api_members.class.php b/htdocs/adherents/class/api_members.class.php index 2be24fb5d03..453b45f59b3 100644 --- a/htdocs/adherents/class/api_members.class.php +++ b/htdocs/adherents/class/api_members.class.php @@ -226,9 +226,13 @@ class Members extends DolibarrApi // If there is no error, update() returns the number of affected rows // so if the update is a no op, the return value is zero. if($member->update(DolibarrApiAccess::$user) >= 0) + { return $this->get($id); - - return false; + } + else + { + throw new RestException(500, $this->task->error); + } } /** @@ -295,6 +299,17 @@ class Members extends DolibarrApi // Remove the subscriptions because they are handled as a subresource. unset($object->subscriptions); + unset($object->fk_incoterms); + unset($object->libelle_incoterms); + unset($object->location_incoterms); + unset($object->fk_delivery_address); + unset($object->shipping_method_id); + + unset($object->total_ht); + unset($object->total_ttc); + unset($object->total_tva); + unset($object->total_localtax1); + unset($object->total_localtax2); return $object; } diff --git a/htdocs/adherents/class/api_memberstypes.class.php b/htdocs/adherents/class/api_memberstypes.class.php index 8e545e6d784..6e793d7229d 100644 --- a/htdocs/adherents/class/api_memberstypes.class.php +++ b/htdocs/adherents/class/api_memberstypes.class.php @@ -204,9 +204,13 @@ class MembersTypes extends DolibarrApi // If there is no error, update() returns the number of affected rows // so if the update is a no op, the return value is zero. if ($membertype->update(DolibarrApiAccess::$user) >= 0) + { return $this->get($id); - - return false; + } + else + { + throw new RestException(500, $this->task->error); + } } /** diff --git a/htdocs/adherents/class/api_subscriptions.class.php b/htdocs/adherents/class/api_subscriptions.class.php index 2cdf7a59ff3..60a243e6d90 100644 --- a/htdocs/adherents/class/api_subscriptions.class.php +++ b/htdocs/adherents/class/api_subscriptions.class.php @@ -193,9 +193,13 @@ class Subscriptions extends DolibarrApi } if ($subscription->update(DolibarrApiAccess::$user) > 0) + { return $this->get($id); - - return false; + } + else + { + throw new RestException(500, $this->task->error); + } } /** diff --git a/htdocs/adherents/class/subscription.class.php b/htdocs/adherents/class/subscription.class.php index 397be6ee8da..bb5780db15a 100644 --- a/htdocs/adherents/class/subscription.class.php +++ b/htdocs/adherents/class/subscription.class.php @@ -22,6 +22,8 @@ * \brief File of class to manage subscriptions of foundation members */ +//namespace DolibarrMember; + require_once DOL_DOCUMENT_ROOT.'/core/class/commonobject.class.php'; @@ -170,6 +172,7 @@ class Subscription extends CommonObject $resql = $this->db->query($sql); if ($resql) { + require_once DOL_DOCUMENT_ROOT.'/adherents/class/adherent.class.php'; $member=new Adherent($this->db); $result=$member->fetch($this->fk_adherent); $result=$member->update_end_date($user); @@ -256,23 +259,26 @@ class Subscription extends CommonObject * Return clicable name (with picto eventually) * * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto + * @param int $notooltip 1=Disable tooltip * @return string Chaine avec URL */ - function getNomUrl($withpicto=0) + function getNomUrl($withpicto=0, $notooltip=0) { global $langs; $result=''; $label=$langs->trans("ShowSubscription").': '.$this->ref; - $link = ''; + $linkstart = ''; $linkend=''; $picto='payment'; - if ($withpicto) $result.=($link.img_object($label, $picto, 'class="classfortooltip"').$linkend); - if ($withpicto && $withpicto != 2) $result.=' '; - $result.=$link.$this->ref.$linkend; + $result .= $linkstart; + if ($withpicto) $result.=img_object(($notooltip?'':$label), ($this->picto?$this->picto:'generic'), ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1); + if ($withpicto != 2) $result.= $this->ref; + $result .= $linkend; + return $result; } diff --git a/htdocs/adherents/index.php b/htdocs/adherents/index.php index 001f6132e95..a04b1df5786 100644 --- a/htdocs/adherents/index.php +++ b/htdocs/adherents/index.php @@ -1,7 +1,7 @@ * Copyright (C) 2003 Jean-Louis Bergamo - * Copyright (C) 2004-2012 Laurent Destailleur + * Copyright (C) 2004-2017 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * * This program is free software; you can redistribute it and/or modify @@ -165,12 +165,13 @@ if ($conf->use_javascript_ajax) print '
    '; print ''; print ''; - print ''; print ''; } // Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $typeofextrafield=$extrafields->attribute_type[$key]; - print ''; - } - } -} +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; + // Fields from hook $parameters=array('arrayfields'=>$arrayfields); $reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook @@ -603,19 +574,8 @@ if (! empty($arrayfields['d.phone_mobile']['checked'])) print_liste_field_titr if (! empty($arrayfields['d.email']['checked'])) print_liste_field_titre($arrayfields['d.email']['label'],$_SERVER["PHP_SELF"],'d.email','',$param,'',$sortfield,$sortorder); if (! empty($arrayfields['d.datefin']['checked'])) print_liste_field_titre($arrayfields['d.datefin']['label'],$_SERVER["PHP_SELF"],'d.datefin','',$param,'align="center"',$sortfield,$sortorder); // Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $sortonfield = "ef.".$key; - if (! empty($extrafields->attribute_computed[$key])) $sortonfield=''; - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],$sortonfield,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } -} +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; + // Hook fields $parameters=array('arrayfields'=>$arrayfields); $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook @@ -800,23 +760,7 @@ while ($i < min($num, $limit)) } } // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - print 'getAlignFlag($key); - if ($align) print ' align="'.$align.'"'; - print '>'; - $tmpkey='options_'.$key; - print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1); - print ''; - if (! $i) $totalarray['nbfield']++; - } - } - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); $reshook=$hookmanager->executeHooks('printFieldListValue',$parameters); // Note that $action and $object may have been modified by hook diff --git a/htdocs/adherents/subscription.php b/htdocs/adherents/subscription.php index e3b3d1ff3ee..6f6bd073f05 100644 --- a/htdocs/adherents/subscription.php +++ b/htdocs/adherents/subscription.php @@ -834,13 +834,15 @@ if ($rowid > 0) print "\n"; $accountstatic=new Account($db); - + while ($i < $num) { $objp = $db->fetch_object($result); - print ''; + $subscriptionstatic->ref=$objp->crowid; $subscriptionstatic->id=$objp->crowid; + + print ''; print ''; print '\n"; print '\n"; @@ -885,18 +887,21 @@ if ($rowid > 0) } - // Shon online payment link - $useonlinepayment = (! empty($conf->paypal->enabled) || ! empty($conf->stripe->enabled) || ! empty($conf->paybox->enabled)); - - if ($useonlinepayment) + if (($action != 'addsubscription' && $action != 'create_thirdparty')) { - print '
    '; + // Shon online payment link + $useonlinepayment = (! empty($conf->paypal->enabled) || ! empty($conf->stripe->enabled) || ! empty($conf->paybox->enabled)); - require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; - print showOnlinePaymentUrl('membersubscription', $object->ref); + if ($useonlinepayment) + { + print '
    '; + + require_once DOL_DOCUMENT_ROOT.'/core/lib/payments.lib.php'; + print showOnlinePaymentUrl('membersubscription', $object->ref); + print '
    '; + } } - /* * Add new subscription form */ diff --git a/htdocs/adherents/subscription/list.php b/htdocs/adherents/subscription/list.php index 7dfad296beb..1ed0b9a5c50 100644 --- a/htdocs/adherents/subscription/list.php +++ b/htdocs/adherents/subscription/list.php @@ -177,8 +177,8 @@ if ($result) //'presend'=>$langs->trans("SendByMail"), //'builddoc'=>$langs->trans("PDFMerge"), ); - if ($user->rights->adherent->supprimer) $arrayofmassactions['delete']=$langs->trans("Delete"); - //if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array(); + if ($user->rights->adherent->supprimer) $arrayofmassactions['predelete']=$langs->trans("Delete"); + if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array(); $massactionbutton=$form->selectMassAction('', $arrayofmassactions); print ''; @@ -193,6 +193,12 @@ if ($result) print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_generic.png', 0, '', '', $limit); + $topicmail="Information"; + $modelmail="subscription"; + $objecttmp=new Subscription($db); + $trackid='sub'.$object->id; + include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; + if ($sall) { print $langs->trans("Filter")." (".$langs->trans("Ref").", ".$langs->trans("Lastname").", ".$langs->trans("Firstname").", ".$langs->trans("EMail").", ".$langs->trans("Address")." ".$langs->trans("or")." ".$langs->trans("Town")."): ".$sall; diff --git a/htdocs/admin/boxes.php b/htdocs/admin/boxes.php index 03e4a0ec9f3..bc1dc74f6c4 100644 --- a/htdocs/admin/boxes.php +++ b/htdocs/admin/boxes.php @@ -248,10 +248,8 @@ if ($resql) // Check record to know if we must recalculate sort order $i = 0; $decalage=0; - $var=false; while ($i < $num) { - $var = ! $var; $obj = $db->fetch_object($resql); $boxes[$obj->position][$obj->box_id]=1; $i++; @@ -321,6 +319,8 @@ if ($resql) // Available boxes to activate $boxtoadd=InfoBox::listBoxes($db,'available',-1,null,$actives); +// Activated boxes +$boxactivated=InfoBox::listBoxes($db,'activated',-1,null); print "
    \n"; print "\n\n".''."\n"; @@ -339,11 +339,9 @@ print ''; print ''; print ''; print "\n"; -$var=true; + foreach($boxtoadd as $box) { - - if (preg_match('/^([^@]+)@([^@]+)$/i',$box->boximg)) { $logo = $box->boximg; @@ -376,7 +374,10 @@ foreach($boxtoadd as $box) print ''."\n"; } - +if (! count($boxtoadd) && count($boxactivated)) +{ + print ''; +} print '
    '.$langs->trans("Statistics").'
    '; + print '
    '; $SommeA=0; $SommeB=0; $SommeC=0; $SommeD=0; + $total=0; $dataval=array(); $datalabels=array(); $i=0; @@ -187,14 +188,23 @@ if ($conf->use_javascript_ajax) $SommeD+=isset($MembersResiliated[$key])?$MembersResiliated[$key]:0; $i++; } - + $total = $SommeA + $SommeB + $SommeC + $SommeD; $dataseries=array(); - $dataseries[]=array('label'=>$langs->trans("MenuMembersNotUpToDate"),'data'=>round($SommeB)); - $dataseries[]=array('label'=>$langs->trans("MenuMembersUpToDate"),'data'=>round($SommeC)); - $dataseries[]=array('label'=>$langs->trans("MembersStatusResiliated"),'data'=>round($SommeD)); - $dataseries[]=array('label'=>$langs->trans("MembersStatusToValid"),'data'=>round($SommeA)); - $data=array('series'=>$dataseries); - dol_print_graph('stats',300,180,$data,1,'pie',1); + $dataseries[]=array($langs->trans("MenuMembersNotUpToDate"), round($SommeB)); + $dataseries[]=array($langs->trans("MenuMembersUpToDate"), round($SommeC)); + $dataseries[]=array($langs->trans("MembersStatusResiliated"), round($SommeD)); + $dataseries[]=array($langs->trans("MembersStatusToValid"), round($SommeA)); + + include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; + $dolgraph = new DolGraph(); + $dolgraph->SetData($dataseries); + $dolgraph->setShowLegend(1); + $dolgraph->setShowPercent(1); + $dolgraph->SetType(array('pie')); + $dolgraph->setWidth('100%'); + $dolgraph->draw('idgraphstatus'); + print $dolgraph->show($total?0:1); + print '
    '.$langs->trans("Total").''; print $SommeA+$SommeB+$SommeC+$SommeD; diff --git a/htdocs/adherents/list.php b/htdocs/adherents/list.php index 4d699c4866d..6b41a217f80 100644 --- a/htdocs/adherents/list.php +++ b/htdocs/adherents/list.php @@ -61,9 +61,10 @@ $search_type=GETPOST("search_type"); $search_email=GETPOST("search_email"); $search_categ = GETPOST("search_categ",'int'); $catid = GETPOST("catid",'int'); -$sall=GETPOST('sall', 'alphanohtml'); $optioncss = GETPOST('optioncss','alpha'); +$sall=trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alphanohtml'):GETPOST('sall', 'alphanohtml')); + if ($statut < -1) $statut = ''; $limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; @@ -244,19 +245,8 @@ if ($filter == 'uptodate') $sql.=" AND datefin >= '".$db->idate($now)."'"; if ($filter == 'outofdate') $sql.=" AND (datefin IS NULL OR datefin < '".$db->idate($now)."')"; // Add where from extra fields -foreach ($search_array_options as $key => $val) -{ - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $typ=$extrafields->attribute_type[$tmpkey]; - $mode_search=0; - if (in_array($typ, array('int','double','real'))) $mode_search=1; // Search on a numeric - if (in_array($typ, array('sellist','link')) && $crit != '0' && $crit != '-1') $mode_search=2; // Search on a foreign key int - if ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0') && (! in_array($typ, array('link')) || $crit != '-1')) - { - $sql .= natural_search('ef.'.$tmpkey, $crit, $mode_search); - } -} +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; + // Add where from hooks $parameters=array(); $reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters); // Note that $action and $object may have been modified by hook @@ -343,20 +333,15 @@ if ($filter) $param.="&filter=".urlencode($filter); if ($search_type > 0) $param.="&search_type=".urlencode($search_type); if ($optioncss != '') $param.='&optioncss='.urlencode($optioncss); // Add $param from extra fields -foreach ($search_array_options as $key => $val) -{ - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); -} +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; // List of mass actions available $arrayofmassactions = array( // 'presend'=>$langs->trans("SendByMail"), // 'builddoc'=>$langs->trans("PDFMerge"), ); -if ($user->rights->adherent->supprimer) $arrayofmassactions['delete']=$langs->trans("Delete"); -//if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array(); +if ($user->rights->adherent->supprimer) $arrayofmassactions['predelete']=$langs->trans("Delete"); +if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array(); $massactionbutton=$form->selectMassAction('', $arrayofmassactions); print '
    '; @@ -371,6 +356,12 @@ print ''; print_barre_liste($titre, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_generic.png', 0, '', '', $limit); +$topicmail="Information"; +$modelmail="member"; +$objecttmp=new Adherent($db); +$trackid='mem'.$object->id; +include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; + if ($sall) { foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val); @@ -522,28 +513,8 @@ if (! empty($arrayfields['d.datefin']['checked'])) print '
    '; - if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select'))) - { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $searchclass=''; - if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; - if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; - print ''; - } - print '
    '.$subscriptionstatic->getNomUrl(1).''.dol_print_date($db->jdate($objp->datec),'dayhour')."'.dol_print_date($db->jdate($objp->dateh),'day')."'.$langs->trans("Note").'/'.$langs->trans("Parameters").''.$langs->trans("SourceFile").''.$langs->trans("ActivateOn").'
    '.$langs->trans("AllWidgetsWereEnabled").'
    '."\n"; print '
    '; @@ -387,8 +388,6 @@ print ''; print "\n".''."\n"; -// Activated boxes -$boxactivated=InfoBox::listBoxes($db,'activated',-1,null); //var_dump($boxactivated); print "
    \n\n"; print load_fiche_titre($langs->trans("BoxesActivated")); @@ -404,13 +403,10 @@ print ''.$langs->trans("PositionByDefa print ''.$langs->trans("Disable").''; print ''."\n"; -$var=true; $box_order=1; $foundrupture=1; foreach($boxactivated as $key => $box) { - $var = ! $var; - if (preg_match('/^([^@]+)@([^@]+)$/i',$box->boximg)) { $logo = $box->boximg; @@ -462,7 +458,6 @@ print ''; print ''; print ''; -$var=false; print ''; print ''; print ''; diff --git a/htdocs/admin/company.php b/htdocs/admin/company.php index 517c57c7d0b..1c6a0c00145 100644 --- a/htdocs/admin/company.php +++ b/htdocs/admin/company.php @@ -69,6 +69,8 @@ if ( ($action == 'update' && ! GETPOST("cancel",'alpha')) $s=$mysoc->country_id.':'.$mysoc->country_code.':'.$mysoc->country_label; dolibarr_set_const($db, "MAIN_INFO_SOCIETE_COUNTRY", $s,'chaine',0,'',$conf->entity); + + activateModulesRequiredByCountry($mysoc->country_code); } dolibarr_set_const($db, "MAIN_INFO_SOCIETE_NOM", GETPOST("nom",'nohtml'),'chaine',0,'',$conf->entity); @@ -981,12 +983,13 @@ else print '
    '; print '
    '.$langs->trans("Parameter").''.$langs->trans("Value").'
    '; print ''; - print ''; + print ''; print ''; print "\n"; - print ""; + print '"; print ''.$langs->trans($val['label']).''; print ''; + if (! $i) $totalarray['nbfield']++; + if (! empty($val['isameasure'])) + { + if (! $i) $totalarray['pos'][$totalarray['nbfield']]='ef.'.$tmpkey; + $totalarray['val']['ef.'.$tmpkey] += $obj->$tmpkey; + } + } + } +} \ No newline at end of file diff --git a/htdocs/core/tpl/extrafields_list_search_input.tpl.php b/htdocs/core/tpl/extrafields_list_search_input.tpl.php new file mode 100644 index 00000000000..948196ae8cb --- /dev/null +++ b/htdocs/core/tpl/extrafields_list_search_input.tpl.php @@ -0,0 +1,28 @@ +attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) { + $align=$extrafields->getAlignFlag($key); + $typeofextrafield=$extrafields->attribute_type[$key]; + print ''; + } + } +} \ No newline at end of file diff --git a/htdocs/core/tpl/extrafields_list_search_param.tpl.php b/htdocs/core/tpl/extrafields_list_search_param.tpl.php new file mode 100644 index 00000000000..9bb6fefe8b0 --- /dev/null +++ b/htdocs/core/tpl/extrafields_list_search_param.tpl.php @@ -0,0 +1,8 @@ + $val) +{ + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); +} \ No newline at end of file diff --git a/htdocs/core/tpl/extrafields_list_search_sql.tpl.php b/htdocs/core/tpl/extrafields_list_search_sql.tpl.php new file mode 100644 index 00000000000..ed4fae40213 --- /dev/null +++ b/htdocs/core/tpl/extrafields_list_search_sql.tpl.php @@ -0,0 +1,15 @@ + $val) +{ + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + $typ=$extrafields->attribute_type[$tmpkey]; + $mode_search=0; + if (in_array($typ, array('int','double','real'))) $mode_search=1; // Search on a numeric + if (in_array($typ, array('sellist','link','chkbxlst','checkbox')) && $crit != '0' && $crit != '-1') $mode_search=2; // Search on a foreign key int + if ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0') && (! in_array($typ, array('link')) || $crit != '-1')) + { + $sql .= natural_search('ef.'.$tmpkey, $crit, $mode_search); + } +} \ No newline at end of file diff --git a/htdocs/core/tpl/extrafields_list_search_title.tpl.php b/htdocs/core/tpl/extrafields_list_search_title.tpl.php new file mode 100644 index 00000000000..bfda64d8464 --- /dev/null +++ b/htdocs/core/tpl/extrafields_list_search_title.tpl.php @@ -0,0 +1,15 @@ +attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + $sortonfield = "ef.".$key; + if (! empty($extrafields->attribute_computed[$key])) $sortonfield=''; + print getTitleFieldOfList($langs->trans($extralabels[$key]), 0, $_SERVER["PHP_SELF"], $sortonfield, "", $param, ($align?'align="'.$align.'"':''), $sortfield, $sortorder)."\n"; + } + } +} \ No newline at end of file diff --git a/htdocs/ecm/tpl/filemanager.tpl.php b/htdocs/core/tpl/filemanager.tpl.php similarity index 85% rename from htdocs/ecm/tpl/filemanager.tpl.php rename to htdocs/core/tpl/filemanager.tpl.php index 26299cbf104..d47853cbe5a 100644 --- a/htdocs/ecm/tpl/filemanager.tpl.php +++ b/htdocs/core/tpl/filemanager.tpl.php @@ -19,7 +19,7 @@ */ ?> - +rights->ecm->setup; @@ -46,6 +46,7 @@ if ($module == 'medias') // Confirm remove file (for non javascript users) if (($action == 'delete' || $action == 'file_manager_delete') && empty($conf->use_javascript_ajax)) { + // TODO Add website, pageid, filemanager if defined print $form->formconfirm($_SERVER["PHP_SELF"].'?section='.$section.'&urlfile='.urlencode($_GET["urlfile"]), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile','','',1); } @@ -65,7 +66,7 @@ print '
    '; if ($permtoadd) { - print ''; + print ''; print ''; print ''; } @@ -103,9 +104,11 @@ if ((! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABL '."\n"; include_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; $formfile=new FormFile($db); - $formfile->form_attach_new_file($_SERVER["PHP_SELF"], 'none', 0, ($section?$section:-1), $permtoupload, 48, null, '', 0, '', 0, $nameforformuserfile); + $formfile->form_attach_new_file($_SERVER["PHP_SELF"], 'none', 0, ($section?$section:-1), $permtoupload, 48, null, '', 0, '', 0, $nameforformuserfile, '', $sectiondir); } else print ' '; @@ -131,7 +134,7 @@ if ($action == 'delete_section') // End confirm -if (empty($action) || $action == 'file_manager' || preg_match('/refresh/i',$action) || $action == 'delete') +if (empty($action) || $action == 'editfile' || $action == 'file_manager' || preg_match('/refresh/i',$action) || $action == 'delete') { print '
    '.$langs->trans("VATManagement").''.$langs->trans("Description").''.$langs->trans("VATManagement").''.$langs->trans("Description").' 
    global->FACTURE_TVAOPTION)?"":" checked")."> ".$langs->trans("VATIsUsed")."
    '; + print "global->FACTURE_TVAOPTION)?"":" checked")."> ".$langs->trans("VATIsUsed")."'; print ""; print ""; @@ -995,7 +998,8 @@ else print "\n"; - print ""; + print '"; print ''; // Edit link - print ''; + print ''; // Add link - //print ''; + //print ''; //print ''; // Info @@ -230,7 +233,7 @@ if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE } } - // Enable jquery handlers on new generated HTML objects + // Enable jquery handlers on new generated HTML objects (same code than into lib_footer.js.php) // Because the content is reloaded by ajax call, we must also reenable some jquery hooks print "\n\n"; print ''."\n"; diff --git a/htdocs/core/class/dolgraph.class.php b/htdocs/core/class/dolgraph.class.php index f2885a50951..329383160aa 100644 --- a/htdocs/core/class/dolgraph.class.php +++ b/htdocs/core/class/dolgraph.class.php @@ -27,7 +27,7 @@ * Class to build graphs. * Usage is: * $dolgraph=new DolGraph(); - * $dolgraph->SetTitle($langs->transnoentities('Tracking_Projects_Pourcent').'
    '.$langs->transnoentities('Tracking_IndicatorDefGraph').'%'); + * $dolgraph->SetTitle($langs->transnoentities('MyTitle').'
    '.$langs->transnoentities('MyTitlePercent').'%'); * $dolgraph->SetMaxValue(50); * $dolgraph->SetData($data); * $dolgraph->setShowLegend(1); @@ -35,7 +35,7 @@ * $dolgraph->SetType(array('pie')); * $dolgraph->setWidth('100%'); * $dolgraph->draw('idofgraph'); - * print $dolgraph->show(); + * print $dolgraph->show($total?0:1); */ class DolGraph { @@ -796,7 +796,7 @@ class DolGraph * Build a graph using JFlot library. Input when calling this method should be: * $this->data = array(array(0=>'labelxA',1=>yA), array('labelxB',yB)); * $this->data = array(array(0=>'labelxA',1=>yA1,...,n=>yAn), array('labelxB',yB1,...yBn)); // or when there is n series to show for each x - * $this->data = array(array('label'=>'labelxA','data'=>yA), array('labelxB',yB)); // TODO Syntax not supported. Removed when dol_print_graph_removed + * $this->data = array(array('label'=>'labelxA','data'=>yA), array('labelxB',yB)); // Syntax deprecated * $this->legend= array("Val1",...,"Valn"); // list of n series name * $this->type = array('bars',...'lines'); or array('pie') * $this->mode = 'depth' ??? @@ -1041,10 +1041,20 @@ class DolGraph /** * Output HTML string to show graph * - * @return string HTML string to show graph + * @param int $shownographyet Show graph to say there is not enough data + * @return string HTML string to show graph */ - function show() + function show($shownographyet=0) { + global $langs; + + if ($shownographyet) + { + $s= '
    '; + $s.='
    '.$langs->trans("NotEnoughDataYet").'
    '; + return $s; + } + return $this->stringtoshow; } diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index 9fb13da7dd9..e556def834d 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -145,7 +145,7 @@ class ExtraFields * @param string $computed Computed value * @param string $entity Entity of extrafields * @param string $langfile Language file - * @return int <=0 if KO, >0 if OK + * @return int <=0 if KO, >0 if OK */ function addExtraField($attrname, $label, $type, $pos, $size, $elementtype, $unique=0, $required=0, $default_value='', $param='', $alwayseditable=0, $perms='', $list=-1, $ishidden=0, $computed='', $entity='', $langfile='') { @@ -234,6 +234,7 @@ class ExtraFields } else { $typedb=$type; $lengthdb=$length; + if ($type == 'varchar' && empty($lengthdb)) $lengthdb='255'; } $field_desc = array( 'type'=>$typedb, @@ -817,6 +818,8 @@ class ExtraFields $form=new Form($this->db); } + $out=''; + $keyprefix = $keyprefix.'options_'; // Because we work on extrafields $label=$this->attribute_label[$key]; @@ -892,13 +895,13 @@ class ExtraFields if (!$required && $value == '') $value = '-1'; // TODO Must also support $moreparam - $out = $form->select_date($value, $keyprefix.$key.$keysuffix, $showtime, $showtime, $required, '', 1, ($keyprefix != 'search_' ? 1 : 0), 1, 0, 1); + $out = $form->select_date($value, $keyprefix.$key.$keysuffix, $showtime, $showtime, $required, '', 1, (($keyprefix != 'search_' && $keyprefix != 'search_options_') ? 1 : 0), 1, 0, 1); } elseif (in_array($type,array('int','integer'))) { $tmp=explode(',',$size); $newsize=$tmp[0]; - $out=''; + $out=''; } elseif (preg_match('/varchar/', $type)) { @@ -906,13 +909,20 @@ class ExtraFields } elseif (in_array($type, array('mail', 'phone', 'url'))) { - $out=''; + $out=''; } elseif ($type == 'text') { - require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor($keyprefix.$key.$keysuffix,$value,'',200,'dolibarr_notes','In',false,false,! empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE,ROWS_5,'90%'); - $out=$doleditor->Create(1); + if (! preg_match('/search_/', $keyprefix)) // If keyprefix is search_ or search_options_, we must just use a simple text field + { + require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; + $doleditor=new DolEditor($keyprefix.$key.$keysuffix,$value,'',200,'dolibarr_notes','In',false,false,! empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE,ROWS_5,'90%'); + $out=$doleditor->Create(1); + } + else + { + $out=''; + } } elseif ($type == 'boolean') { @@ -1353,12 +1363,12 @@ class ExtraFields if ($type == 'date') { $showsize=10; - $value=dol_print_date($value,'day'); + $value=dol_print_date($value, 'day', 'tzuser'); } elseif ($type == 'datetime') { $showsize=19; - $value=dol_print_date($value,'dayhour'); + $value=dol_print_date($value, 'dayhour', 'tzuser'); } elseif ($type == 'int') { @@ -1380,7 +1390,7 @@ class ExtraFields } elseif ($type == 'mail') { - $value=dol_print_email($value,0,0,0,64,1,1); + $value=dol_print_email($value, 0, 0, 0, 64, 1, 1); } elseif ($type == 'url') { @@ -1392,7 +1402,7 @@ class ExtraFields } elseif ($type == 'price') { - $value=price($value,0,$langs,0,0,-1,$conf->currency); + $value=price($value, 0, $langs, 0, 0, -1, $conf->currency); } elseif ($type == 'select') { diff --git a/htdocs/core/class/fiscalyear.class.php b/htdocs/core/class/fiscalyear.class.php index 5e5ff6e3ce8..987033d35e3 100644 --- a/htdocs/core/class/fiscalyear.class.php +++ b/htdocs/core/class/fiscalyear.class.php @@ -145,7 +145,7 @@ class Fiscalyear extends CommonObject $sql .= " SET label = '".$this->db->escape($this->label)."'"; $sql .= ", date_start = '".$this->db->idate($this->date_start)."'"; $sql .= ", date_end = ".($this->date_end ? "'".$this->db->idate($this->date_end)."'" : "null"); - $sql .= ", statut = '".$this->db->escape($this->statut)."'"; + $sql .= ", statut = '".$this->db->escape($this->statut?$this->statut:0)."'"; $sql .= ", datec = " . ($this->datec != '' ? "'".$this->db->idate($this->datec)."'" : 'null'); $sql .= ", fk_user_modif = " . $user->id; $sql .= " WHERE rowid = ".$this->id; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 74b1416ec08..839a4c56fe0 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -410,12 +410,13 @@ class Form * @param int $notabs 0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span * @param string $incbefore Include code before the text * @param int $noencodehtmltext Do not encode into html entity the htmltext - * @param string $tooltiptrigger ''=Tooltip on hover, 'abc'=Tooltip on click (abc is a unique key) + * @param string $tooltiptrigger ''=Tooltip on hover, 'abc'=Tooltip on click (abc is a unique key) + * @param int $forcenowrap Force no wrap between text and picto (works with notabs=2 only) * @return string Code html du tooltip (texte+picto) * @see Use function textwithpicto if you can. * TODO Move this as static as soon as everybody use textwithpicto or @Form::textwithtooltip */ - function textwithtooltip($text, $htmltext, $tooltipon = 1, $direction = 0, $img = '', $extracss = '', $notabs = 2, $incbefore = '', $noencodehtmltext = 0, $tooltiptrigger='') + function textwithtooltip($text, $htmltext, $tooltipon = 1, $direction = 0, $img = '', $extracss = '', $notabs = 2, $incbefore = '', $noencodehtmltext = 0, $tooltiptrigger='', $forcenowrap=0) { global $conf; @@ -462,7 +463,7 @@ class Form } else $paramfortooltiptd =($extracss?' class="'.$extracss.'"':'').($extrastyle?' style="'.$extrastyle.'"':''); // Attribut to put on td text tag if (empty($notabs)) $s.='
    global->FACTURE_TVAOPTION)?" checked":"")."> ".$langs->trans("VATIsNotUsed")."
    '; + print "global->FACTURE_TVAOPTION)?" checked":"")."> ".$langs->trans("VATIsNotUsed")."'; print ""; print ""; @@ -1015,12 +1019,13 @@ else print '
    '; print '
    ".$langs->trans("VATIsNotUsedDesc")."
    '; print ''; - print ''; + print ''; print ''; print "\n"; - print ""; + print ""; print '
    '.$langs->transcountry("LocalTax1Management",$mysoc->country_code).''.$langs->trans("Description").''.$langs->transcountry("LocalTax1Management",$mysoc->country_code).''.$langs->trans("Description").' 
    global->FACTURE_LOCAL_TAX1_OPTION == '1' || $conf->global->FACTURE_LOCAL_TAX1_OPTION == "localtax1on")?" checked":"")."> ".$langs->transcountry("LocalTax1IsUsed",$mysoc->country_code)."
    "; + print "global->FACTURE_LOCAL_TAX1_OPTION == '1' || $conf->global->FACTURE_LOCAL_TAX1_OPTION == "localtax1on")?" checked":"")."> ".$langs->transcountry("LocalTax1IsUsed",$mysoc->country_code)."'; print ""; print ""; @@ -1048,7 +1053,8 @@ else print "\n"; - print ""; + print '"; print '
    ".$langs->transcountry("LocalTax1IsUsedDesc",$mysoc->country_code)."
    global->FACTURE_LOCAL_TAX1_OPTION) || $conf->global->FACTURE_LOCAL_TAX1_OPTION == "localtax1off")?" checked":"")."> ".$langs->transcountry("LocalTax1IsNotUsed",$mysoc->country_code)."
    '; + print "global->FACTURE_LOCAL_TAX1_OPTION) || $conf->global->FACTURE_LOCAL_TAX1_OPTION == "localtax1off")?" checked":"")."> ".$langs->transcountry("LocalTax1IsNotUsed",$mysoc->country_code)."'; print ""; print ""; @@ -1065,12 +1071,13 @@ else print '
    '; print '
    '; print ''; - print ''; + print ''; print ''; print "\n"; - print ""; + print ""; print ''; + $userepeatevent=($conf->global->MAIN_FEATURES_LEVEL == 2 ? 1 : 0); // Dev in progress + if ($userepeatevent) + { + // Repeat + print ''; + } + // Status print ''; print ''; + print ''; } // Assigned to @@ -722,6 +793,7 @@ if ($action == 'create') { $assignedtouser=GETPOST("assignedtouser")?GETPOST("assignedtouser"):(! empty($object->userownerid) && $object->userownerid > 0 ? $object->userownerid : $user->id); if ($assignedtouser) $listofuserid[$assignedtouser]=array('id'=>$assignedtouser,'mandatory'=>0,'transparency'=>$object->transparency); // Owner first + $listofuserid[$user->id]['transparency']=GETPOSTISSET('transparency')?GETPOST('transparency','alpha'):1; // 1 by default at first init $_SESSION['assignedtouser']=json_encode($listofuserid); } else @@ -730,16 +802,17 @@ if ($action == 'create') { $listofuserid=json_decode($_SESSION['assignedtouser'], true); } + $listofuserid[$user->id]['transparency']=GETPOSTISSET('transparency')?GETPOST('transparency','alpha'):0; // 0 by default when refreshing } print '
    '; - print $form->select_dolusers_forevent(($action=='create'?'add':'update'), 'assignedtouser', 1, '', 0, '', '', 0, 0, 0, 'AND u.statut != 0'); + print $form->select_dolusers_forevent(($action=='create'?'add':'update'), 'assignedtouser', 1, '', 0, '', '', 0, 0, 0, 'AND u.statut != 0', 1, $listofuserid, $listofcontactid, $listofotherid); print '
    '; - if (in_array($user->id,array_keys($listofuserid))) + /*if (in_array($user->id,array_keys($listofuserid))) { print '
    '; print $langs->trans("MyAvailability").': '.$langs->trans("Busy"); print '
    '; - } + }*/ print ''; // Realised by @@ -751,39 +824,45 @@ if ($action == 'create') } print '
    '.$langs->transcountry("LocalTax2Management",$mysoc->country_code).''.$langs->trans("Description").''.$langs->transcountry("LocalTax2Management",$mysoc->country_code).''.$langs->trans("Description").' 
    global->FACTURE_LOCAL_TAX2_OPTION == '1' || $conf->global->FACTURE_LOCAL_TAX2_OPTION == "localtax2on")?" checked":"")."> ".$langs->transcountry("LocalTax2IsUsed",$mysoc->country_code)."
    "; + print "global->FACTURE_LOCAL_TAX2_OPTION == '1' || $conf->global->FACTURE_LOCAL_TAX2_OPTION == "localtax2on")?" checked":"")."> ".$langs->transcountry("LocalTax2IsUsed",$mysoc->country_code)."'; print ""; print ""; diff --git a/htdocs/admin/dict.php b/htdocs/admin/dict.php index eb1efd3211b..cf620fae65f 100644 --- a/htdocs/admin/dict.php +++ b/htdocs/admin/dict.php @@ -805,7 +805,7 @@ if (GETPOST('actionadd') || GETPOST('actionmodify')) $i++; } $sql.= " WHERE ".$rowidcol." = '".$rowid."'"; - $sql.= " AND entity = '".getEntity($tabname[$id])."'"; + if (in_array('entity', $listfieldmodify)) $sql.= " AND entity = '".getEntity($tabname[$id])."'"; dol_syslog("actionmodify", LOG_DEBUG); //print $sql; diff --git a/htdocs/admin/ihm.php b/htdocs/admin/ihm.php index 256dd08f9a8..03f3d364cca 100644 --- a/htdocs/admin/ihm.php +++ b/htdocs/admin/ihm.php @@ -353,7 +353,8 @@ if ($action == 'edit') // Edit print ''; // Hide wiki link on login page - print ''; print ''; @@ -441,7 +442,7 @@ else // Show { // Language print '
    '.$langs->trans("DisableLinkToHelp",img_picto('',DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/helpdoc.png','',1)).''; + $pictohelp=''; + print '
    '.$langs->trans("DisableLinkToHelp",$pictohelp).''; print $form->selectyesno('MAIN_HELP_DISABLELINK', isset($conf->global->MAIN_HELP_DISABLELINK)?$conf->global->MAIN_HELP_DISABLELINK:0,1); print ' 
    '; - print ''; + print ''; print ''; print ''; print ''; diff --git a/htdocs/admin/prelevement.php b/htdocs/admin/prelevement.php index f368010078b..aa2effb32e2 100644 --- a/htdocs/admin/prelevement.php +++ b/htdocs/admin/prelevement.php @@ -74,13 +74,13 @@ if ($action == "set") $res = dolibarr_set_const($db, "PRELEVEMENT_ICS", GETPOST("PRELEVEMENT_ICS"),'chaine',0,'',$conf->entity); if (! $res > 0) $error++; - + if (GETPOST("PRELEVEMENT_USER") > 0) { $res = dolibarr_set_const($db, "PRELEVEMENT_USER", GETPOST("PRELEVEMENT_USER"),'chaine',0,'',$conf->entity); if (! $res > 0) $error++; } - + if (! $error) { $db->commit(); @@ -155,7 +155,7 @@ if ($action == 'specimen') setEventMessages($langs->trans("ErrorModuleNotFound"), null, 'errors'); dol_syslog($langs->trans("ErrorModuleNotFound"), LOG_ERR); } -} +} // Set default model else if ($action == 'setdoc') @@ -411,7 +411,7 @@ if (! empty($conf->global->MAIN_MODULE_NOTIFICATION)) $sql = "SELECT u.rowid, u.lastname, u.firstname, u.fk_soc, u.email"; $sql.= " FROM ".MAIN_DB_PREFIX."user as u"; - $sql.= " WHERE entity IN (0,".$conf->entity.")"; + $sql.= " WHERE entity IN (".getEntity('facture').")"; $resql=$db->query($sql); if ($resql) @@ -422,7 +422,7 @@ if (! empty($conf->global->MAIN_MODULE_NOTIFICATION)) while ($i < $num) { $obj = $db->fetch_object($resql); - + if (!$obj->fk_soc) { $username=dolGetFirstLastname($obj->firstname,$obj->lastname); @@ -495,7 +495,7 @@ if (! empty($conf->global->MAIN_MODULE_NOTIFICATION)) while ($i < $num) { $obj = $db->fetch_object($resql); - + print ''; print ''; diff --git a/htdocs/admin/system/dolibarr.php b/htdocs/admin/system/dolibarr.php index 5daaca5e29e..30830cb26d4 100644 --- a/htdocs/admin/system/dolibarr.php +++ b/htdocs/admin/system/dolibarr.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2005-2017 Laurent Destailleur * Copyright (C) 2007 Rodolphe Quiedeville * Copyright (C) 2007-2012 Regis Houssin * @@ -120,8 +120,13 @@ if (function_exists('curl_init')) } } +// Now show link to the changelog print '     -     '; -print ''.$langs->trans("SeeChangeLog").''; + +$version=DOL_VERSION; +if (preg_match('/[a-z]+/i', $version)) $version='develop'; // If version contains text, it is not an official tagged version, so we use the full change log. + +print ''.$langs->trans("SeeChangeLog").''; print ''."\n"; print ''."\n"; print ''."\n"; @@ -258,7 +263,7 @@ print ''."\n"; print ''."\n"; $filesystemencoding=ini_get("unicode.filesystem_encoding"); // Disponible avec PHP 6.0 -print ''."\n"; // date.timezone must be in valued defined in http://fr3.php.net/manual/en/timezones.europe.php +print ''."\n"; $tmp=ini_get("unicode.filesystem_encoding"); // Disponible avec PHP 6.0 if (empty($tmp) && ! empty($_SERVER["WINDIR"])) $tmp='iso-8859-1'; // By default for windows diff --git a/htdocs/admin/system/filecheck.php b/htdocs/admin/system/filecheck.php index 8ddae2a3d5b..8aed7d193f9 100644 --- a/htdocs/admin/system/filecheck.php +++ b/htdocs/admin/system/filecheck.php @@ -212,7 +212,7 @@ if ($xml) // Defined qualified files (must be same than into generate_filelist_xml.php) $regextoinclude='\.(php|css|html|js|json|tpl|jpg|png|gif|sql|lang)$'; - $regextoexclude='('.($includecustom?'':'custom|').'documents|conf|install)$'; // Exclude dirs + $regextoexclude='('.($includecustom?'':'custom|').'documents|conf|install|public\/test|Shared\/PCLZip|nusoap\/lib\/Mail|php\/example|php\/test|geoip\/sample.*\.php|ckeditor\/samples|ckeditor\/adapters)$'; // Exclude dirs $scanfiles = dol_dir_list(DOL_DOCUMENT_ROOT, 'files', 1, $regextoinclude, $regextoexclude); // Fill file_list with files in signature, new files, modified files diff --git a/htdocs/admin/taxes.php b/htdocs/admin/taxes.php index 59796919a8b..a8f98f02c3b 100644 --- a/htdocs/admin/taxes.php +++ b/htdocs/admin/taxes.php @@ -113,7 +113,7 @@ if ($action == 'update') { llxHeader(); $form=new Form($db); -if (! empty($conf->accounting->enabled)) $formaccounting = New FormAccounting($db); +if (! empty($conf->accounting->enabled)) $formaccounting = new FormAccounting($db); $linkback=''.$langs->trans("BackToModuleList").''; print load_fiche_titre($langs->trans('TaxSetup'),$linkback,'title_setup'); diff --git a/htdocs/admin/tools/dolibarr_export.php b/htdocs/admin/tools/dolibarr_export.php index c09ab8ed3f9..7b2c8805f55 100644 --- a/htdocs/admin/tools/dolibarr_export.php +++ b/htdocs/admin/tools/dolibarr_export.php @@ -214,10 +214,13 @@ print ''."\n"; @@ -315,9 +312,7 @@ if ($mode == 'overwrite') print '\n"; print ''; @@ -406,6 +401,7 @@ if ($mode == 'searchkey') // Search modules dirs $modulesdir = dolGetModulesDirs(); + $nbtotaloffiles=0; $nbempty=0; /*var_dump($langcode); var_dump($transkey); @@ -420,6 +416,7 @@ if ($mode == 'searchkey') else { // Search into dir of modules (the $modulesdir is already a list that loop on $conf->file->dol_document_root) + $i=0; foreach($modulesdir as $keydir => $tmpsearchdir) { $searchdir = $tmpsearchdir; // $searchdir can be '.../htdocs/core/modules/' or '.../htdocs/custom/mymodule/core/modules/' @@ -432,10 +429,19 @@ if ($mode == 'searchkey') foreach($filearray as $file) { $tmpfile=preg_replace('/.lang/i', '', basename($file['name'])); - $newlang->load($tmpfile, 0, 0, '', 0); // Load translation files + database overwrite - $newlangfileonly->load($tmpfile, 0, 0, '', 1); // Load translation files only - //print 'After loading lang '.$tmpfile.', newlang has '.count($newlang->tab_translate).' records
    '."\n"; + $moduledirname =(basename(dirname(dirname($dir_lang)))); + + $langkey=$tmpfile; + if ($i > 0) $langkey.='@'.$moduledirname; + //var_dump($i.' - '.$keydir.' - '.$dir_lang_osencoded.' -> '.$moduledirname . ' / ' . $tmpfile.' -> '.$langkey); + + $result = $newlang->load($langkey, 0, 0, '', 0); // Load translation files + database overwrite + $result = $newlangfileonly->load($langkey, 0, 0, '', 1); // Load translation files only + if ($result < 0) print 'Failed to load language file '.$tmpfile.'
    '."\n"; + else $nbtotaloffiles++; + //print 'After loading lang '.$langkey.', newlang has '.count($newlang->tab_translate).' records
    '."\n"; } + $i++; } // Now search into translation array @@ -455,7 +461,7 @@ if ($mode == 'searchkey') //print 'param='.$param.' $_SERVER["PHP_SELF"]='.$_SERVER["PHP_SELF"].' num='.$num.' page='.$page.' nbtotalofrecords='.$nbtotalofrecords." sortfield=".$sortfield." sortorder=".$sortorder; $title = $langs->trans("TranslationKeySearch"); - if ($nbtotalofrecords > 0) $title.=' ('.$nbtotalofrecords.' / '.$nbtotalofrecordswithoutfilters.')'; + if ($nbtotalofrecords > 0) $title.=' ('.$nbtotalofrecords.' / '.$nbtotalofrecordswithoutfilters.' - '.$nbtotaloffiles.' '.$langs->trans("Files").')'; print print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, -1 * $nbtotalofrecords, '', 0, '', '', $limit)."\n"; print ''; diff --git a/htdocs/api/admin/explorer.php b/htdocs/api/admin/explorer.php index b09acb6772a..a9f13928217 100644 --- a/htdocs/api/admin/explorer.php +++ b/htdocs/api/admin/explorer.php @@ -14,7 +14,7 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . - * + * * @deprecated Old explorer. Not using Swagger. See instead explorer in htdocs/api/index.php. */ @@ -106,18 +106,7 @@ foreach ($modulesdir as $dir) { while (($file_searched = readdir($handle_part))!==false) { - // Support of the deprecated API. - if (is_readable($dir_part.$file_searched) && preg_match("/^api_deprecated_(.*)\.class\.php$/i",$file_searched,$reg)) - { - $classname = ucwords($reg[1]).'Api'; - require_once $dir_part.$file_searched; - if (class_exists($classname)) - { - dol_syslog("Found deprecated API classname=".$classname." into ".$dir); - $api->r->addAPIClass($classname, ''); - } - } - elseif (is_readable($dir_part.$file_searched) && preg_match("/^api_(.*)\.class\.php$/i",$file_searched,$reg)) + if (is_readable($dir_part.$file_searched) && preg_match("/^api_(.*)\.class\.php$/i",$file_searched,$reg)) { $classname = ucwords($reg[1]); require_once $dir_part.$file_searched; @@ -126,8 +115,8 @@ foreach ($modulesdir as $dir) dol_syslog("Found API classname=".$classname." into ".$dir); $listofapis[] = $classname; } - } - + } + /* if (is_readable($dir_part.$file_searched) && preg_match("/^(api_.*)\.class\.php$/i",$file_searched,$reg)) { @@ -137,11 +126,11 @@ foreach ($modulesdir as $dir) $classname = ucfirst($classname); require_once $dir_part.$file_searched; - if (class_exists($classname)) + if (class_exists($classname)) { - dol_syslog("Found API classname=".$classname); + dol_syslog("Found API classname=".$classname); $api->r->addAPIClass($classname,''); - + /* require_once DOL_DOCUMENT_ROOT.'/includes/restler/framework/Luracast/Restler/Routes.php'; @@ -151,10 +140,10 @@ foreach ($modulesdir as $dir) } catch (Exception $e) { throw new RestException(500, "Error while parsing comments of `$classname` class. " . $e->getMessage()); }*/ - + //$listofapis[]=array('classname'=>$classname, 'fullpath'=>$file_searched); /* } - + }*/ } } @@ -196,7 +185,7 @@ foreach($listofapis['v1'] as $key => $val) { if ($key == 'login') continue; if ($key == 'index') continue; - + if ($key) { foreach($val as $method => $val2) @@ -204,8 +193,8 @@ foreach($listofapis['v1'] as $key => $val) $newclass=$val2['className']; if (preg_match('/restler/i', $newclass)) continue; - - if ($oldclass != $newclass) + + if ($oldclass != $newclass) { print "\n
    \n".$langs->trans("Class").': '.$newclass.'
    '."\n"; $oldclass = $newclass; @@ -214,7 +203,7 @@ foreach($listofapis['v1'] as $key => $val) $url=$urlwithroot.'/api/index.php/'.$key; $url.='?api_key=token'; print img_picto('','object_globe.png').' '.$method.' '.$url."
    \n"; - } + } } } diff --git a/htdocs/api/class/api.class.php b/htdocs/api/class/api.class.php index 5c85cddfaee..66ab13bc8fb 100644 --- a/htdocs/api/class/api.class.php +++ b/htdocs/api/class/api.class.php @@ -101,7 +101,7 @@ class DolibarrApi // Remove linkedObjects. We should already have linkedObjectIds that avoid huge responses unset($object->linkedObjects); - unset($object->lines); // should be ->lines + unset($object->lignes); // we don't want lignes, we want only ->lines unset($object->fields); diff --git a/htdocs/api/class/api_documents.class.php b/htdocs/api/class/api_documents.class.php index 669fc09911e..7cbdd1d21f7 100644 --- a/htdocs/api/class/api_documents.class.php +++ b/htdocs/api/class/api_documents.class.php @@ -23,8 +23,6 @@ use Luracast\Restler\Format\UploadFormat; require_once DOL_DOCUMENT_ROOT.'/main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; -require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; /** * API class for receive files @@ -177,6 +175,8 @@ class Documents extends DolibarrApi if ($modulepart == 'societe' || $modulepart == 'thirdparty') { + require_once DOL_DOCUMENT_ROOT.'/societe/class/societe.class.php'; + if (!DolibarrApiAccess::$user->rights->societe->lire) { throw new RestException(401); } @@ -239,7 +239,7 @@ class Documents extends DolibarrApi * Test sample 1: { "filename": "mynewfile.txt", "modulepart": "facture", "ref": "FA1701-001", "subdir": "", "filecontent": "content text", "fileencoding": "", "overwriteifexists": "0" }. * Test sample 2: { "filename": "mynewfile.txt", "modulepart": "medias", "ref": "", "subdir": "mysubdir1/mysubdir2", "filecontent": "content text", "fileencoding": "", "overwriteifexists": "0" }. * - * @param string $filename Name of file to create ('FA1705-0123') + * @param string $filename Name of file to create ('FA1705-0123.txt') * @param string $modulepart Name of module or area concerned by file upload ('facture', 'project', 'project_task', ...) * @param string $ref Reference of object (This will define subdir automatically and store submited file into it) * @param string $subdir Subdirectory (Only if ref not provided) @@ -285,15 +285,20 @@ class Documents extends DolibarrApi if ($modulepart == 'facture' || $modulepart == 'invoice') { $modulepart='facture'; + + require_once DOL_DOCUMENT_ROOT.'/compta/facture/class/facture.class.php'; $object = new Facture($this->db); } elseif ($modulepart == 'project') { + require_once DOL_DOCUMENT_ROOT.'/projet/class/project.class.php'; $object = new Project($this->db); } elseif ($modulepart == 'task' || $modulepart == 'project_task') { $modulepart = 'project_task'; + + require_once DOL_DOCUMENT_ROOT.'/projet/class/task.class.php'; $object = new Task($this->db); $task_result = $object->fetch('', $ref); diff --git a/htdocs/api/class/api_login.class.php b/htdocs/api/class/api_login.class.php index d59e0036423..1273b843dd3 100644 --- a/htdocs/api/class/api_login.class.php +++ b/htdocs/api/class/api_login.class.php @@ -57,11 +57,22 @@ class Login if (empty($dolibarr_main_authentication)) $dolibarr_main_authentication = 'http,dolibarr'; // Authentication mode: forceuser - if ($dolibarr_main_authentication == 'forceuser' && empty($dolibarr_auto_user)) - $dolibarr_auto_user = 'auto'; + if ($dolibarr_main_authentication == 'forceuser') + { + if (empty($dolibarr_auto_user)) $dolibarr_auto_user='auto'; + if ($dolibarr_auto_user != $login) + { + dol_syslog("Warning: your instance is set to use the automatic forced login '".$dolibarr_auto_user."' that is not the requested login. API usage is forbidden in this mode."); + throw new RestException(403, "Your instance is set to use the automatic login '".$dolibarr_auto_user."' that is not the requested login. API usage is forbidden in this mode."); + } + } // Set authmode $authmode = explode(',', $dolibarr_main_authentication); + if ($entity != '' && ! is_numeric($entity)) + { + throw new RestException(403, "Bad value for entity, must be the numeric ID of company."); + } if ($entity == '') $entity=1; include_once DOL_DOCUMENT_ROOT . '/core/lib/security2.lib.php'; diff --git a/htdocs/api/index.php b/htdocs/api/index.php index 50e0421010a..d588fbdad1d 100644 --- a/htdocs/api/index.php +++ b/htdocs/api/index.php @@ -96,7 +96,7 @@ preg_match('/index\.php\/([^\/]+)(.*)$/', $_SERVER["PHP_SELF"], $reg); // Set the flag to say to refresh (when we reload the explorer, production must be for API call only) $refreshcache=false; -if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/resources.json' || $reg[2] == '/resources.json/root')) +if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/swagger.json' || $reg[2] == '/swagger.json/root' || $reg[2] == '/resources.json' || $reg[2] == '/resources.json/root')) { $refreshcache=true; } @@ -109,7 +109,7 @@ $api = new DolibarrApi($db, '', $refreshcache); // See https://github.com/Luracast/Restler-API-Explorer for more info. $api->r->addAPIClass('Luracast\\Restler\\Explorer'); -$api->r->setSupportedFormats('JsonFormat', 'XmlFormat', 'UploadFormat'); +$api->r->setSupportedFormats('JsonFormat', 'XmlFormat', 'UploadFormat'); // 'YamlFormat' $api->r->addAuthenticationClass('DolibarrApiAccess',''); // Define accepted mime types @@ -118,7 +118,7 @@ UploadFormat::$allowedMimeTypes = array('image/jpeg', 'image/png', 'text/plain', // Call Explorer file for all APIs definitions -if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/resources.json' || $reg[2] == '/resources.json/root')) +if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/swagger.json' || $reg[2] == '/swagger.json/root' || $reg[2] == '/resources.json' || $reg[2] == '/resources.json/root')) { // Scan all API files to load them @@ -163,22 +163,7 @@ if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/resources.json' | { if ($file_searched == 'api_access.class.php') continue; - // Support of the deprecated API. - if (is_readable($dir_part.$file_searched) && preg_match("/^api_deprecated_(.*)\.class\.php$/i",$file_searched,$regapi)) - { - $classname = ucwords($regapi[1]).'Api'; - require_once $dir_part.$file_searched; - if (class_exists($classname)) - { - //dol_syslog("Found deprecated API by index.php: classname=".$classname." for module ".$dir." into ".$dir_part.$file_searched); - $api->r->addAPIClass($classname, '/'); - } - else - { - dol_syslog("We found an api_xxx file (".$file_searched.") but class ".$classname." does not exists after loading file", LOG_WARNING); - } - } - elseif (is_readable($dir_part.$file_searched) && preg_match("/^api_(.*)\.class\.php$/i",$file_searched,$regapi)) + if (is_readable($dir_part.$file_searched) && preg_match("/^api_(.*)\.class\.php$/i",$file_searched,$regapi)) { $classname = ucwords($regapi[1]); $classname = str_replace('_', '', $classname); @@ -213,15 +198,16 @@ if (! empty($reg[1]) && $reg[1] == 'explorer' && ($reg[2] == '/resources.json' | { $api->r->addAPIClass($classname, $apiname); } + //var_dump($api->r); } // Call one APIs or one definition of an API -if (! empty($reg[1]) && ($reg[1] != 'explorer' || ($reg[2] != '/resources.json' && preg_match('/^\/resources.json\/(.+)$/', $reg[2], $regbis) && $regbis[1] != 'root'))) +if (! empty($reg[1]) && ($reg[1] != 'explorer' || ($reg[2] != '/swagger.json' && $reg[2] != '/resources.json' && preg_match('/^\/(swagger|resources)\.json\/(.+)$/', $reg[2], $regbis) && $regbis[2] != 'root'))) { $module = $reg[1]; if ($module == 'explorer') // If we call page to explore details of a service { - $module = $regbis[1]; + $module = $regbis[2]; } $module=strtolower($module); @@ -230,52 +216,33 @@ if (! empty($reg[1]) && ($reg[1] != 'explorer' || ($reg[2] != '/resources.json' // Load a dedicated API file dol_syslog("Load a dedicated API file moduledirforclass=".$moduledirforclass); - if (in_array($module, array('category','contact','customer','invoice','order','product','thirdparty','user'))) // Old Apis - { - $classfile = $module; - if ($module == 'customer') { $classfile = 'thirdparty'; } - if ($module == 'order') { $classfile = 'commande'; } - $dir_part_file = dol_buildpath('/'.$moduledirforclass.'/class/api_deprecated_'.$classfile.'.class.php', 0, 2); - $classname=ucwords($module); - if ($module == 'customer') { $classname='Thirdparty'; } - if ($module == 'order') { $classname='Commande'; } - //var_dump($classfile);var_dump($classname);exit; + $tmpmodule = $module; + if ($tmpmodule != 'api') + $tmpmodule = preg_replace('/api$/i', '', $tmpmodule); + $classfile = str_replace('_', '', $tmpmodule); + if ($module == 'supplierproposals') + $classfile = 'supplier_proposals'; + if ($module == 'supplierorders') + $classfile = 'supplier_orders'; + if ($module == 'supplierinvoices') + $classfile = 'supplier_invoices'; + $dir_part_file = dol_buildpath('/' . $moduledirforclass . '/class/api_' . $classfile . '.class.php', 0, 2); - $res = false; - if ($dir_part_file) $res = include_once $dir_part_file; - if (! $res) - { - print 'API not found (failed to include API file)'; - header('HTTP/1.1 501 API not found (failed to include API file)'); - exit(0); - } - if (class_exists($classname.'Api')) $api->r->addAPIClass($classname.'Api', '/'); - } - else - { - $tmpmodule = $module; - if ($tmpmodule != 'api') $tmpmodule = preg_replace('/api$/i','', $tmpmodule); - $classfile = str_replace('_', '', $tmpmodule); - if ($module == 'supplierproposals') $classfile = 'supplier_proposals'; - if ($module == 'supplierorders') $classfile = 'supplier_orders'; - if ($module == 'supplierinvoices') $classfile = 'supplier_invoices'; - $dir_part_file = dol_buildpath('/'.$moduledirforclass.'/class/api_'.$classfile.'.class.php', 0, 2); + $classname = ucwords($module); - $classname=ucwords($module); + dol_syslog('Search /' . $moduledirforclass . '/class/api_' . $classfile . '.class.php => dir_part_file=' . $dir_part_file . ' classname=' . $classname); - dol_syslog('Search /'.$moduledirforclass.'/class/api_'.$classfile.'.class.php => dir_part_file='.$dir_part_file.' classname='.$classname); + $res = false; + if ($dir_part_file) + $res = include_once $dir_part_file; + if (! $res) { + print 'API not found (failed to include API file)'; + header('HTTP/1.1 501 API not found (failed to include API file)'); + exit(0); + } - $res = false; - if ($dir_part_file) $res = include_once $dir_part_file; - if (! $res) - { - print 'API not found (failed to include API file)'; - header('HTTP/1.1 501 API not found (failed to include API file)'); - exit(0); - } - - if (class_exists($classname)) $api->r->addAPIClass($classname); - } + if (class_exists($classname)) + $api->r->addAPIClass($classname); } // TODO If not found, redirect to explorer diff --git a/htdocs/barcode/printsheet.php b/htdocs/barcode/printsheet.php index e8deb15a8d2..04a181d3613 100644 --- a/htdocs/barcode/printsheet.php +++ b/htdocs/barcode/printsheet.php @@ -236,7 +236,10 @@ if ($action == 'builddoc') { $mesg=$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("DescADHERENT_ETIQUETTE_TYPE")); } - if (! $mesg) $result=doc_label_pdf_create($db, $arrayofrecords, $modellabel, $outputlangs, $diroutput, $template, 'tmp_barcode_sheet.pdf'); + + $outfile = $langs->trans("BarCode").'_sheets_'.dol_print_date(dol_now(),'dayhourlog').'.pdf'; + + if (! $mesg) $result=doc_label_pdf_create($db, $arrayofrecords, $modellabel, $outputlangs, $diroutput, $template, dol_sanitizeFileName($outfile)); } if ($result <= 0) @@ -292,9 +295,9 @@ foreach(array_keys($_Avery_Labels) as $codecards) $labeltoshow=$_Avery_Labels[$codecards]['name']; //$labeltoshow.=' ('.$_Avery_Labels[$row['code']]['paper-size'].')'; $arrayoflabels[$codecards]=$labeltoshow; - $arrayoflabels[$codecards]=$_Avery_Labels[$codecards]['name']; } -print $form->selectarray('modellabel',$arrayoflabels,(GETPOST('modellabel')?GETPOST('modellabel'):$conf->global->ADHERENT_ETIQUETTE_TYPE),1,0,0); +asort($arrayoflabels); +print $form->selectarray('modellabel', $arrayoflabels, (GETPOST('modellabel')?GETPOST('modellabel'):$conf->global->ADHERENT_ETIQUETTE_TYPE), 1, 0, 0, '', 0, 0, 0, '', '', 1); print ''; // Number of stickers to print diff --git a/htdocs/blockedlog/README-fr.md b/htdocs/blockedlog/README-fr.md new file mode 100644 index 00000000000..e92bd5a09fe --- /dev/null +++ b/htdocs/blockedlog/README-fr.md @@ -0,0 +1,23 @@ +LOG INALTERABLE +=============== + +## Fonctionnalité + +Ce module trace, en temps réel, certains évènements métiers dans une log inaltérable (que vous ne pouvez pas modifier une fois enregistrés) de type blockchain. +Ce module est requis pour la compatibilité avec les exigences légales de certains pays (comme la France avec la loi Fincance 2016 - Norme NF535). + + +**Les évènements tracés de manière inaltérables sont:** + +- Création de facture +- Enregistrement des paiements +- Impression et téléchargement de facture faites via le logiciel + +Remarque: Le type des événements tracés est probablement plus large que la plupart des exigences légales mais permet d'être prêt pour d'éventuel élargissement +de ces exigences. +Vous pouvez aussi lire et faire des recherches au sein de la log inaltérable. + +Tous les enregistrements de la logs inaltérable sont liés avec le précédent dans une Blockchain, et leur contenu fait parti de la signature inclue dans ce lien, +aussi, une fois le module activé et le premier enregistrement réalisé, il ne sera plus possible d'effacer ni modifier un enregistrement dans la log +inaltérable sans corrompre toute la chaine. Dès lors qu'un enregistrement est invalide, tous les suivants pourront également être considérés invalides par votre administration. + diff --git a/htdocs/blockedlog/README.md b/htdocs/blockedlog/README.md new file mode 100644 index 00000000000..ec3174fb847 --- /dev/null +++ b/htdocs/blockedlog/README.md @@ -0,0 +1,22 @@ +BLOCKED LOG +=========== + +## Feature + +This module tracks, in real time, some events into a non reversible log (that you can't modify once recorded) into a block chain. +This module provides compatibility with requirements of laws of some countries (like France with the law Fincance 2016 - Norme NF535). + + +**The tracked events are:** + +- Invoices creation +- Payments record +- Invoice printing + +You can also read and search into this dedicated log. + +All record in the log are linked with the previous one in a blockchain, and content of the record is part of the +signature included into the link, so, once the module is activated, it is no more possible to erase or modify a record without corrupting all the chain. + + + diff --git a/htdocs/blockedlog/admin/blockedlog.php b/htdocs/blockedlog/admin/blockedlog.php index b3822a9acb7..8d4fe48a20f 100644 --- a/htdocs/blockedlog/admin/blockedlog.php +++ b/htdocs/blockedlog/admin/blockedlog.php @@ -34,6 +34,7 @@ if (! $user->admin) accessforbidden(); $action = GETPOST('action','alpha'); + /* * Actions */ @@ -41,7 +42,10 @@ $action = GETPOST('action','alpha'); if (preg_match('/set_(.*)/',$action,$reg)) { $code=$reg[1]; - if (dolibarr_set_const($db, $code, GETPOST($code), 'chaine', 0, '', $conf->entity) > 0) + $values = GETPOST($code); + if(is_array($values))$values = implode(',', $values); + + if (dolibarr_set_const($db, $code, $values, 'chaine', 0, '', $conf->entity) > 0) { header("Location: ".$_SERVER["PHP_SELF"]); exit; @@ -115,6 +119,34 @@ if (!empty($conf->global->BLOCKEDLOG_USE_REMOTE_AUTHORITY)) { print ''; } +print '
    '; +print ''; +print ''; + print '
    '.$langs->trans("Language").' 
    '.$langs->trans("Language").'  
    '.$langs->trans("DefaultLanguage").''; $s=picto_from_langcode($conf->global->MAIN_LANG_DEFAULT); @@ -467,48 +468,35 @@ else // Show // Other print ''; - print ''; + print ''; print ''; - print ''; print ""; print ''; - print ''; print ""; - /* - print '"; - print ''; - print ""; - */ - // Disable javascript/ajax print '"; - print ''; print ""; // First day for weeks print ''; - print ''; print ''; // DefaultWorkingDays print ''; - print ''; print ''; // DefaultWorkingHours print ''; - print ''; print ''; // Firstname / Name position @@ -516,17 +504,15 @@ else // Show if (empty($conf->global->MAIN_FIRSTNAME_NAME_POSITION)) { print $langs->trans("Firstname").' '.$langs->trans("Lastname"); } else { print $langs->trans("Lastname").' '.$langs->trans("Firstname"); } print ''; - print ''; print ''; // Hide unauthorized button - print ''; // Show logo print ''; - print ''; print ""; // Hide version link @@ -534,23 +520,22 @@ else // Show print ''; - print ''; print ''; */ // Show bugtrack link print '"; - print ''; print ""; // Link to wiki help - print ''; // Message of the day - print ''."\n"; @@ -561,21 +546,21 @@ else // Show // Login page print '
    '.$langs->trans("Parameters").''.$langs->trans("Value").'
    '.$langs->trans("Parameters").''.$langs->trans("Value").'
    '.$langs->trans("DefaultMaxSizeList").'' . $conf->global->MAIN_SIZE_LISTE_LIMIT . ' 
    '.$langs->trans("DefaultMaxSizeShortList").'' . $conf->global->MAIN_SIZE_SHORTLIST_LIMIT . ' 
    '.$langs->trans("showInputBorder").''; - print yn($conf->global->THEME_ELDY_SHOW_BORDER_INPUT)." 
    '.$langs->trans("DisableJavascript").''; print yn($conf->global->MAIN_DISABLE_JAVASCRIPT)." 
    '.$langs->trans("WeekStartOnDay").''; print $langs->trans("Day".(isset($conf->global->MAIN_START_WEEK)?$conf->global->MAIN_START_WEEK:'1')); print ' 
    '.$langs->trans("DefaultWorkingDays").''; print isset($conf->global->MAIN_DEFAULT_WORKING_DAYS)?$conf->global->MAIN_DEFAULT_WORKING_DAYS:'1-5'; print ' 
    '.$langs->trans("DefaultWorkingHours").''; print isset($conf->global->MAIN_DEFAULT_WORKING_HOURS)?$conf->global->MAIN_DEFAULT_WORKING_HOURS:'9-18'; print ' 
     
    '.$langs->trans("ButtonHideUnauthorized").''; + print '
    '.$langs->trans("ButtonHideUnauthorized").''; print yn((isset($conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED)?$conf->global->MAIN_BUTTON_HIDE_UNAUTHORIZED:0),1); print '
    '.$langs->trans("EnableShowLogo").'' . yn($conf->global->MAIN_SHOW_LOGO) . ' 
    '.$langs->trans("HideVersionLink").''; print yn($conf->global->MAIN_HIDE_VERSION); print ' 
    '.$langs->trans("ShowBugTrackLink", $langs->transnoentitiesnoconv("FindBug")).''; print yn($conf->global->MAIN_BUGTRACK_ENABLELINK)." 
    '.$langs->trans("DisableLinkToHelp",img_picto('',DOL_URL_ROOT.'/theme/'.$conf->theme.'/img/helpdoc.png','',1)).''; + $pictohelp=''; + print '
    '.$langs->trans("DisableLinkToHelp",$pictohelp).''; print yn((isset($conf->global->MAIN_HELP_DISABLELINK)?$conf->global->MAIN_HELP_DISABLELINK:0),1); print '
    '.$langs->trans("MessageOfDay").''; + print '
    '.$langs->trans("MessageOfDay").''; if (isset($conf->global->MAIN_MOTD)) print dol_htmlcleanlastbr($conf->global->MAIN_MOTD); else print ' '; print '
    '; - print ''; + print ''; // Message login - print ''."\n"; // Link to help center - print ''; // Background login - print ''; + print ''; print '
    '.$langs->trans("LoginPage").' 
    '.$langs->trans("LoginPage").'
    '.$langs->trans("MessageLogin").''; + print '
    '.$langs->trans("MessageLogin").''; if (isset($conf->global->MAIN_HOME)) print dol_htmlcleanlastbr($conf->global->MAIN_HOME); else print ' '; print '
    '.$langs->trans("DisableLinkToHelpCenter").''; + print '
    '.$langs->trans("DisableLinkToHelpCenter").''; print yn((isset($conf->global->MAIN_HELPCENTER_DISABLELINK)?$conf->global->MAIN_HELPCENTER_DISABLELINK:0),1); print '
    '.$langs->trans("BackgroundImageLogin").''; + print '
    '.$langs->trans("BackgroundImageLogin").''; print '
    '; print $conf->global->MAIN_LOGIN_BACKGROUND; if ($conf->global->MAIN_LOGIN_BACKGROUND && is_file($conf->mycompany->dir_output.'/logos/'.$conf->global->MAIN_LOGIN_BACKGROUND)) diff --git a/htdocs/admin/loan.php b/htdocs/admin/loan.php index 65363f468e8..1a9ef385bf7 100644 --- a/htdocs/admin/loan.php +++ b/htdocs/admin/loan.php @@ -77,7 +77,7 @@ if ($action == 'update') llxHeader(); $form = new Form($db); -if (! empty($conf->accounting->enabled)) $formaccounting = New FormAccounting($db); +if (! empty($conf->accounting->enabled)) $formaccounting = new FormAccounting($db); $linkback=''.$langs->trans("BackToModuleList").''; print load_fiche_titre($langs->trans('ConfigLoan'),$linkback,'title_setup'); diff --git a/htdocs/admin/mails.php b/htdocs/admin/mails.php index d77f448f811..d482322a054 100644 --- a/htdocs/admin/mails.php +++ b/htdocs/admin/mails.php @@ -587,9 +587,13 @@ else } else dol_print_error($db); - print '
    '.$langs->trans('MAIN_MAIL_DEFAULT_FROMTYPE').'
    '.$langs->trans('MAIN_MAIL_DEFAULT_FROMTYPE').''; - if ($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE === 'user') + if ($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE === 'robot') + { + print $langs->trans('RobotEmail'); + } + else if ($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE === 'user') { print $langs->trans('UserEmail'); } @@ -724,10 +728,13 @@ else // Cree l'objet formulaire mail include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; $formmail = new FormMail($db); + $formmail->trackid=(($action == 'testhtml')?"testhtml":"test"); $formmail->fromname = (isset($_POST['fromname'])?$_POST['fromname']:$conf->global->MAIN_MAIL_EMAIL_FROM); $formmail->frommail = (isset($_POST['frommail'])?$_POST['frommail']:$conf->global->MAIN_MAIL_EMAIL_FROM); - $formmail->trackid=(($action == 'testhtml')?"testhtml":"test"); - $formmail->withfromreadonly=0; + $formmail->fromid=$user->id; + $formmail->fromalsorobot=1; + $formmail->fromtype=(GETPOST('fromtype')?GETPOST('fromtype'):(!empty($conf->global->MAIN_MAIL_DEFAULT_FROMTYPE)?$conf->global->MAIN_MAIL_DEFAULT_FROMTYPE:'user')); + $formmail->withfromreadonly=1; $formmail->withsubstit=0; $formmail->withfrom=1; $formmail->witherrorsto=1; diff --git a/htdocs/admin/mails_senderprofile_list.php b/htdocs/admin/mails_senderprofile_list.php index c0d4d54eac4..763e648746d 100644 --- a/htdocs/admin/mails_senderprofile_list.php +++ b/htdocs/admin/mails_senderprofile_list.php @@ -46,7 +46,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/emailsenderprofile.class.php'; // Load traductions files requiredby by page $langs->loadLangs(array("errors","admin","mails","languages")); -$action = GETPOST('action','alpha')?GETPOST('action','alpha'):'view'; +$action = GETPOST('action','alpha')?GETPOST('action','alpha'):'view'; // The action 'add', 'create', 'edit', 'update', 'view', ... $massaction = GETPOST('massaction','alpha'); // The bulk action (combo box choice into lists) $show_files = GETPOST('show_files','int'); // Show files area generated by bulk actions ? $confirm = GETPOST('confirm','alpha'); // Result of a confirmation @@ -71,7 +71,7 @@ $pagenext = $page + 1; // Initialize technical objects $object=new EmailSenderProfile($db); $extrafields = new ExtraFields($db); -$diroutputmassaction=$conf->monmodule->dir_output . '/temp/massgeneration/'.$user->id; +$diroutputmassaction=$conf->admin->dir_output . '/temp/massgeneration/'.$user->id; $hookmanager->initHooks(array('emailsenderprofilelist')); // Note that conf->hooks_modules contains array // Fetch optionals attributes and labels $extralabels = $extrafields->fetch_name_optionals_label('emailsenderprofile'); @@ -205,9 +205,10 @@ $parameters=array(); $reshook=$hookmanager->executeHooks('printFieldListSelect', $parameters, $object); // Note that $action and $object may have been modified by hook $sql.=$hookmanager->resPrint; $sql=preg_replace('/, $/','', $sql); -$sql.= " FROM ".MAIN_DB_PREFIX."c_email_senderprofile as t"; -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."emailsenderprofile_extrafields as ef on (t.rowid = ef.fk_object)"; -$sql.= " WHERE t.entity IN (".getEntity('emailsenderprofile').")"; +$sql.= " FROM ".MAIN_DB_PREFIX.$object->table_element." as t"; +if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."myobject_extrafields as ef on (t.rowid = ef.fk_object)"; +if ($object->ismultientitymanaged == 1) $sql.= " WHERE t.entity IN (".getEntity('emailsenderprofile').")"; +else $sql.=" WHERE 1 = 1"; foreach($search as $key => $val) { $mode_search=(($object->isInt($object->fields[$key]) || $object->isFloat($object->fields[$key]))?1:0); @@ -215,19 +216,7 @@ foreach($search as $key => $val) } if ($search_all) $sql.= natural_search(array_keys($fieldstosearchall), $search_all); // Add where from extra fields -foreach ($search_array_options as $key => $val) -{ - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $typ=$extrafields->attribute_type[$tmpkey]; - $mode_search=0; - if (in_array($typ, array('int','double','real'))) $mode_search=1; // Search on a numeric - if (in_array($typ, array('sellist','link')) && $crit != '0' && $crit != '-1') $mode_search=2; // Search on a foreign key int - if ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0')) - { - $sql .= natural_search('ef.'.$tmpkey, $crit, $mode_search); - } -} +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; // Add where from hooks $parameters=array(); $reshook=$hookmanager->executeHooks('printFieldListWhere', $parameters, $object); // Note that $action and $object may have been modified by hook @@ -259,7 +248,6 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) $sql.= $db->plimit($limit+1, $offset); -dol_syslog($script_file, LOG_DEBUG); $resql=$db->query($sql); if (! $resql) { @@ -305,19 +293,14 @@ foreach($search as $key => $val) } if ($optioncss != '') $param.='&optioncss='.urlencode($optioncss); // Add $param from extra fields -foreach ($search_array_options as $key => $val) -{ - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); -} +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; // List of mass actions available $arrayofmassactions = array( //'presend'=>$langs->trans("SendByMail"), //'builddoc'=>$langs->trans("PDFMerge"), ); -if ($user->rights->monmodule->delete) $arrayofmassactions['delete']=$langs->trans("Delete"); +if ($user->rights->monmodule->delete) $arrayofmassactions['predelete']=$langs->trans("Delete"); if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array(); $massactionbutton=$form->selectMassAction('', $arrayofmassactions); @@ -333,6 +316,12 @@ print ''; //print_barre_liste($title, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_companies', 0, '', '', $limit); +$topicmail="Information"; +//$modelmail="subscription"; +$objecttmp=new EmailSenderProfile($db); +//$trackid='sub'.$object->id; +include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; + $moreforfilter = ''; /*$moreforfilter.='
    '; $moreforfilter.= $langs->trans('MyFilter') . ': '; @@ -363,50 +352,18 @@ print ''; foreach($object->fields as $key => $val) { - if (in_array($key, array('date_creation', 'tms', 'import_key', 'status'))) continue; $align=''; - if (in_array($val['type'], array('date','datetime','timestamp'))) $align='center'; - if (in_array($val['type'], array('timestamp'))) $align.=' nowrap'; + if (in_array($val['type'], array('date','datetime','timestamp'))) $align.=($align?' ':'').'center'; + if (in_array($val['type'], array('timestamp'))) $align.=($align?' ':'').'nowrap'; if ($key == 'status') $align.=($align?' ':'').'center'; if (! empty($arrayfields['t.'.$key]['checked'])) print ''; } // Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $typeofextrafield=$extrafields->attribute_type[$key]; - print ''; - } - } -} +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; // Fields from hook $parameters=array('arrayfields'=>$arrayfields); $reshook=$hookmanager->executeHooks('printFieldListOption', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; -// Rest of fields search -foreach($object->fields as $key => $val) -{ - if (! in_array($key, array('date_creation', 'tms', 'import_key', 'status'))) continue; - $align=''; - if (in_array($val['type'], array('date','datetime','timestamp'))) $align='center'; - if (in_array($val['type'], array('timestamp'))) $align.=' nowrap'; - if ($key == 'status') $align.=($align?' ':'').'center'; - if (! empty($arrayfields['t.'.$key]['checked'])) print ''; -} // Action column print ''."\n"; print ''; foreach($object->fields as $key => $val) { - if (in_array($key, array('date_creation', 'tms', 'import_key', 'status'))) continue; $align=''; - if (in_array($val['type'], array('date','datetime','timestamp'))) $align='center'; - if (in_array($val['type'], array('timestamp'))) $align.='nowrap'; + if (in_array($val['type'], array('date','datetime','timestamp'))) $align.=($align?' ':'').'center'; + if (in_array($val['type'], array('timestamp'))) $align.=($align?' ':'').'nowrap'; if ($key == 'status') $align.=($align?' ':'').'center'; if (! empty($arrayfields['t.'.$key]['checked'])) print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($align?'class="'.$align.'"':''), $sortfield, $sortorder, $align.' ')."\n"; } // Extra fields -if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) -{ - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $sortonfield = "ef.".$key; - if (! empty($extrafields->attribute_computed[$key])) $sortonfield=''; - print getTitleFieldOfList($langs->trans($extralabels[$key]), 0, $_SERVER["PHP_SELF"], $sortonfield, "", $param, ($align?'align="'.$align.'"':''), $sortfield, $sortorder)."\n"; - } - } -} +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; + // Hook fields $parameters=array('arrayfields'=>$arrayfields); $reshook=$hookmanager->executeHooks('printFieldListTitle', $parameters, $object); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; -// Rest of fields title -foreach($object->fields as $key => $val) -{ - if (! in_array($key, array('date_creation', 'tms', 'import_key', 'status'))) continue; - $align=''; - if (in_array($val['type'], array('date','datetime','timestamp'))) $align='center'; - if (in_array($val['type'], array('timestamp'))) $align.=' nowrap'; - if ($key == 'status') $align.=($align?' ':'').'center'; - if (! empty($arrayfields['t.'.$key]['checked'])) print getTitleFieldOfList($arrayfields['t.'.$key]['label'], 0, $_SERVER['PHP_SELF'], 't.'.$key, '', $param, ($align?'class="'.$align.'"':''), $sortfield, $sortorder, $align.' ')."\n"; -} print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch ')."\n"; print ''."\n"; @@ -487,77 +422,31 @@ while ($i < min($num, $limit)) print ''; foreach($object->fields as $key => $val) { - if (in_array($key, array('date_creation', 'tms', 'import_key', 'status'))) continue; - $align=''; - if (in_array($val['type'], array('date','datetime','timestamp'))) $align='center'; - if (in_array($val['type'], array('timestamp'))) $align.='nowrap'; - if ($key == 'status') $align.=($align?' ':'').'center'; - if (! empty($arrayfields['t.'.$key]['checked'])) - { - print ''; - if (in_array($val['type'], array('date','datetime','timestamp'))) print dol_print_date($db->jdate($obj->$key), 'dayhour'); - elseif ($key == 'ref') print $object->getNomUrl(1, '', 0, '', 1); - elseif ($key == 'status') print $object->getLibStatut(3); - else print $obj->$key; - print ''; - if (! $i) $totalarray['nbfield']++; - if (! empty($val['isameasure'])) - { - if (! $i) $totalarray['pos'][$totalarray['nbfield']]='t.'.$key; - $totalarray['val']['t.'.$key] += $obj->$key; - } - } - } - // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - print 'getAlignFlag($key); - if ($align) print ' align="'.$align.'"'; - print '>'; - $tmpkey='options_'.$key; - print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1); - print ''; - if (! $i) $totalarray['nbfield']++; - if (! empty($val['isameasure'])) - { - if (! $i) $totalarray['pos'][$totalarray['nbfield']]='ef.'.$tmpkey; - $totalarray['val']['ef.'.$tmpkey] += $obj->$tmpkey; - } - } - } - } - // Fields from hook - $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); - $reshook=$hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook - print $hookmanager->resPrint; - // Rest of fields - foreach($object->fields as $key => $val) - { - if (! in_array($key, array('date_creation', 'tms', 'import_key', 'status'))) continue; $align=''; if (in_array($val['type'], array('date','datetime','timestamp'))) $align.=($align?' ':'').'center'; if (in_array($val['type'], array('timestamp'))) $align.=($align?' ':'').'nowrap'; if ($key == 'status') $align.=($align?' ':'').'center'; if (! empty($arrayfields['t.'.$key]['checked'])) { - print ''; - if (in_array($val['type'], array('date','datetime','timestamp'))) print dol_print_date($db->jdate($obj->$key), 'dayhour'); - elseif ($key == 'status') print $object->getLibStatut(3); - else print $obj->$key; + print ''; + print $object->showOutputField($val, $key, $obj->$key, ''); print ''; if (! $i) $totalarray['nbfield']++; if (! empty($val['isameasure'])) { if (! $i) $totalarray['pos'][$totalarray['nbfield']]='t.'.$key; - $totalarray['val']['t.'.$key] += $obj->$key; + $totalarray['val']['t.'.$key] += $obj->$key; } } } + // Extra fields + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; + // Fields from hook + $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); + $reshook=$hookmanager->executeHooks('printFieldListValue', $parameters, $object); // Note that $action and $object may have been modified by hook + print $hookmanager->resPrint; // Action column print ''."\n"; @@ -1009,9 +1036,21 @@ if ($mode == 'develop') print ''; print ''; - print "\n"; + print ''."\n"; + print ''; + print ''; + print ''; + print ''; + + print ''."\n"; $url='https://partners.dolibarr.org'; - print ''; + print ''; print ''; print ''; print ''; diff --git a/htdocs/admin/oauth.php b/htdocs/admin/oauth.php index c1bb5909e15..0733779a91a 100644 --- a/htdocs/admin/oauth.php +++ b/htdocs/admin/oauth.php @@ -47,7 +47,7 @@ $action = GETPOST('action', 'alpha'); /* * Actions */ - + if ($action == 'update') { $error = 0; @@ -86,7 +86,7 @@ print ''; $head = oauthadmin_prepare_head(); -dol_fiche_head($head, 'services', '', 0, 'technic'); +dol_fiche_head($head, 'services', '', -1, 'technic'); print $langs->trans("ListOfSupportedOauthProviders").'

    '; @@ -102,10 +102,10 @@ foreach ($list as $key) if (! $supported) continue; // show only supported $i++; - + print ''; // Api Name - $label = $langs->trans($key[0]); + $label = $langs->trans($key[0]); print ''; print ''; print ''; } - + // Api Id print ''; print ''; diff --git a/htdocs/admin/oauthlogintokens.php b/htdocs/admin/oauthlogintokens.php index 06315222825..d2a7232a4fe 100644 --- a/htdocs/admin/oauthlogintokens.php +++ b/htdocs/admin/oauthlogintokens.php @@ -118,7 +118,7 @@ print load_fiche_titre($langs->trans('ConfigOAuth'),$linkback,'title_setup'); $head=oauthadmin_prepare_head($mode); -dol_fiche_head($head, 'tokengeneration', '', 0, 'technic'); +dol_fiche_head($head, 'tokengeneration', '', -1, 'technic'); if ($mode == 'setup' && $user->admin) @@ -131,8 +131,8 @@ if ($mode == 'setup' && $user->admin) $supported=0; if (in_array($key[0], array_keys($supportedoauth2array))) $supported=1; if (! $supported) continue; // show only supported - - + + $OAUTH_SERVICENAME='Unknown'; if ($key[0] == 'OAUTH_GITHUB_NAME') { @@ -148,7 +148,7 @@ if ($mode == 'setup' && $user->admin) $urltodelete=$urlwithroot.'/core/modules/oauth/google_oauthcallback.php?action=delete&backtourl='.urlencode(DOL_URL_ROOT.'/admin/oauthlogintokens.php'); $urltocheckperms='https://security.google.com/settings/security/permissions'; } - + // Show value of token $tokenobj=null; // Token @@ -164,21 +164,21 @@ if ($mode == 'setup' && $user->admin) { // Return an error if token not found } - + // Set other properties $refreshtoken=false; $expiredat=''; - + $expire = false; // Is token expired or will token expire in the next 30 seconds if (is_object($tokenobj)) { $expire = ($tokenobj->getEndOfLife() !== $tokenobj::EOL_NEVER_EXPIRES && $tokenobj->getEndOfLife() !== $tokenobj::EOL_UNKNOWN && time() > ($tokenobj->getEndOfLife() - 30)); } - + if ($key[1] != '' && $key[2] != '') { if (is_object($tokenobj)) { $refreshtoken = $tokenobj->getRefreshToken(); - + $endoflife = $tokenobj->getEndOfLife(); if ($endoflife == $tokenobj::EOL_NEVER_EXPIRES) { @@ -196,21 +196,21 @@ if ($mode == 'setup' && $user->admin) } $submit_enabled=0; - + print ''; print ''; print ''; - - + + print '
    '; - if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select')) && empty($extrafields->attribute_computed[$key])) - { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $searchclass=''; - if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; - if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; - print ''; - } - print ''; $searchpicto=$form->showFilterButtons(); @@ -420,41 +377,19 @@ print '
    '; if ($massactionbutton || $massaction) // If we are in select mode (massactionbutton defined) or if we have already selected and sent an action ($massaction) defined @@ -629,7 +518,7 @@ if (in_array('builddoc',$arrayofmassactions) && ($nbtotalofrecords === '' || $nb $filedir=$diroutputmassaction; $genallowed=$user->rights->monmodule->read; - $delallowed=$user->rights->monmodule->read; + $delallowed=$user->rights->monmodule->create; print $formfile->showdocuments('massfilesarea_monmodule','',$filedir,$urlsource,0,$delallowed,'',1,1,0,48,1,$param,$title,''); } diff --git a/htdocs/admin/mails_templates.php b/htdocs/admin/mails_templates.php index ef06806a5d2..77f969181f4 100644 --- a/htdocs/admin/mails_templates.php +++ b/htdocs/admin/mails_templates.php @@ -270,6 +270,7 @@ if (empty($reshook)) if ($value == 'private' && ! is_numeric($_POST[$keycode])) $_POST[$keycode]='0'; if ($value == 'position' && ! is_numeric($_POST[$keycode])) $_POST[$keycode]='1'; if ($_POST[$keycode] == '' && $keycode != 'langcode') $sql.="null"; // lang must be '' if not defined so the unique key that include lang will work + elseif ($_POST[$keycode] == '0' && $keycode == 'langcode') $sql.="null"; else $sql.="'".$db->escape($_POST[$keycode])."'"; $i++; } @@ -708,8 +709,8 @@ if ($resql) { if (! empty($tabhelp[$id][$value])) { - if (in_array($value, array('topic'))) $valuetoshow = $form->textwithpicto($valuetoshow, $tabhelp[$id][$value], 1, 'help', '', 0, 2, 'tooltip'.$value); // Tooltip on hover - else $valuetoshow = $form->textwithpicto($valuetoshow, $tabhelp[$id][$value], 1, 'help', '', 0, 2); // Tooltip on hover + if (in_array($value, array('topic'))) $valuetoshow = $form->textwithpicto($valuetoshow, $tabhelp[$id][$value], 1, 'help', '', 0, 2, 'tooltip'.$value); // Tooltip on click + else $valuetoshow = $form->textwithpicto($valuetoshow, $tabhelp[$id][$value], 1, 'help', '', 0, 2, '', 1); // Tooltip on hover } print getTitleFieldOfList($valuetoshow, 0, $_SERVER["PHP_SELF"], ($sortable?$fieldlist[$field]:''), ($page?'page='.$page.'&':''), $param, "align=".$align, $sortfield, $sortorder); } diff --git a/htdocs/admin/modules.php b/htdocs/admin/modules.php index ce5d4ec55eb..82f1df1b7d5 100644 --- a/htdocs/admin/modules.php +++ b/htdocs/admin/modules.php @@ -34,8 +34,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/geturl.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; require_once DOL_DOCUMENT_ROOT.'/admin/dolistore/class/dolistore.class.php'; -$langs->load("errors"); -$langs->load("admin"); +$langs->loadLangs(array("errors","admin","modulebuilder")); $mode=GETPOST('mode', 'alpha'); if (empty($mode)) $mode='common'; @@ -95,6 +94,8 @@ $hookmanager->initHooks(array('adminmodules','globaladmin')); * Actions */ +$formconfirm = ''; + $parameters=array(); $reshook=$hookmanager->executeHooks('doActions',$parameters,$object,$action); // Note that $action and $object may have been modified by some hooks if ($reshook < 0) setEventMessages($hookmanager->error, $hookmanager->errors, 'errors'); @@ -237,8 +238,7 @@ if ($action == 'set' && $user->admin) header("Location: ".$_SERVER["PHP_SELF"]."?mode=".$mode.$param.($page_y?'&page_y='.$page_y:'')); exit; } - -if ($action == 'reset' && $user->admin) +else if ($action == 'reset' && $user->admin && GETPOST('confirm') == 'yes') { $result=unActivateModule($value); if ($result) setEventMessages($result, null, 'errors'); @@ -424,6 +424,22 @@ foreach ($modulesdir as $dir) } } +if ($action == 'reset_confirm' && $user->admin) +{ + if(!empty($modules[$value])) { + $objMod = $modules[$value]; + + if(!empty($objMod->langfiles)) $langs->loadLangs($objMod->langfiles); + + $form = new Form($db); + $formconfirm = $form->formconfirm($_SERVER["PHP_SELF"] . '?value='.$value.'&mode='.$mode.$param, $langs->trans('ConfirmUnactivation'), $langs->trans(GETPOST('confirm_message_code')), 'reset', '', 'no', 1); + + } + +} + +print $formconfirm; + asort($orders); //var_dump($orders); //var_dump($categ); @@ -680,9 +696,20 @@ if ($mode == 'common') } else { - print ''; - print img_picto($langs->trans("Activated"),'switch_on'); - print ''; + if(!empty($objMod->warnings_unactivation[$mysoc->country_code]) && method_exists($objMod, 'alreadyUsed') && $objMod->alreadyUsed()) { + print 'warnings_unactivation[$mysoc->country_code].'&value=' . $modName . '&mode=' . $mode . $param . '">'; + print img_picto($langs->trans("Activated"),'switch_on'); + print ''; + + } + else { + + print ''; + print img_picto($langs->trans("Activated"),'switch_on'); + print ''; + + } + } print ''.$langs->trans("URL").'
    '; + //span class="fa fa-bug"> + //print ''; + print '
    '; + print '
    '.$langs->trans("TryToUseTheModuleBuilder").''.$langs->trans("SeeTopRightMenu").'
    '; + print''; + print ''.$langs->trans("DoliPartnersDesc").''.$url.'
    '.$label.''; if (! empty($key[3])) print $langs->trans($key[3]); @@ -127,7 +127,7 @@ foreach ($list as $key) print ''.$langs->trans("FeatureNotYetSupported").'
    '."\n"; - + $var=false; print ''; print ''; print ''; print ''; print "\n"; - + print ''; print ''; //var_dump($key); @@ -221,7 +221,7 @@ if ($mode == 'setup' && $user->admin) print ''; print ''."\n"; - + $var = ! $var; print ''; print ''; @@ -248,7 +248,7 @@ if ($mode == 'setup' && $user->admin) } print ''; print ''; - + $var = ! $var; print ''; print ''; @@ -265,7 +265,7 @@ if ($mode == 'setup' && $user->admin) /*print '
    Extra:
    ';*/ - } + } print ''; print '
    '."\n"; @@ -281,7 +281,7 @@ if ($mode == 'setup' && $user->admin) print yn($refreshtoken); print ''; print ''; - + // Token expired $var = ! $var; print ''; @@ -292,7 +292,7 @@ if ($mode == 'setup' && $user->admin) print yn($expire); print ''; print ''; - + // Token expired at $var = ! $var; print ''; @@ -302,9 +302,9 @@ if ($mode == 'setup' && $user->admin) print ''; - print ''; + print ''; } - + print '
    '.$langs->trans($key[0]).'
    '; print '
    '; print $expiredat; print '
    '; if (! empty($driver)) @@ -314,10 +314,10 @@ if ($mode == 'setup' && $user->admin) } } - + print ''; } - + } if ($mode == 'test' && $user->admin) @@ -344,7 +344,7 @@ if ($mode == 'test' && $user->admin) } } - + print '
    '; } @@ -368,7 +368,7 @@ if ($mode == 'userconf' && $user->admin) $sql = 'SELECT p.rowid, p.printer_name, p.printer_location, p.printer_id, p.copy, p.module, p.driver, p.userid, u.login FROM '.MAIN_DB_PREFIX.'printing as p, '.MAIN_DB_PREFIX.'user as u WHERE p.userid=u.rowid'; $resql = $db->query($sql); while ($row=$db->fetch_array($resql)) { - + print '
    '.$row['login'].''.$row['module'].'
    '.dolGetFirstLastname($obj->firstname,$obj->lastname).'
    '.$langs->trans("VersionLastUpgrade").' ('.$langs->trans("Database").')'.$conf->global->MAIN_VERSION_LAST_UPGRADE.'
    '.$langs->trans("VersionLastInstall").''.$conf->global->MAIN_VERSION_LAST_INSTALL.'
      => '.$langs->trans("ClientHour").''.dol_print_date(dol_now(),'dayhour','tzuser').'
    '.$langs->trans("File encoding").' (php.ini unicode.filesystem_encoding)'.$filesystemencoding.'
    '.$langs->trans("File encoding").' (php.ini unicode.filesystem_encoding)'.$filesystemencoding.'
    '; + global->MYSQL_OLD_OPTION_DISABLE_FK)) { ?>
    + +
    '; for="checkbox_use_transaction"> trans("UseTransactionnalMode"); ?> - + global->MYSQL_OLD_OPTION_DISABLE_FK)) { ?>
    +
    @@ -463,6 +467,19 @@ if (! empty($_SESSION["commandbackuplastdone"])) $_SESSION["commandbackuptorun"]=''; $_SESSION["commandbackupresult"]=''; } +if (! empty($_SESSION["commandbackuptorun"])) +{ + print '
    '.$langs->trans("YouMustRunCommandFromCommandLineAfterLoginToUser",$dolibarr_main_db_user,$dolibarr_main_db_user).':
    '."\n"; + print '
    '."\n"; + print ajax_autoselect("commandbackuptoruntext", 0); + print '
    '; + + //print $paramclear; + + $_SESSION["commandbackuplastdone"]=''; + $_SESSION["commandbackuptorun"]=''; + $_SESSION["commandbackupresult"]=''; +} ?> diff --git a/htdocs/admin/tools/export.php b/htdocs/admin/tools/export.php index 7e2fa8ee79d..01ab314df73 100644 --- a/htdocs/admin/tools/export.php +++ b/htdocs/admin/tools/export.php @@ -214,10 +214,10 @@ else $_SESSION["commandbackupresult"]=$resultstring; } - else + /*else { - setEventMessages($langs->trans("YouMustRunCommandFromCommandLineAfterLoginToUser",$dolibarr_main_db_user,$dolibarr_main_db_user), null, 'mesgs'); - } + setEventMessages($langs->trans("YouMustRunCommandFromCommandLineAfterLoginToUser",$dolibarr_main_db_user,$dolibarr_main_db_user), null, 'warnings'); + }*/ } @@ -254,7 +254,7 @@ function backup_tables($outputfile, $tables='*') global $errormsg; // Set to UTF-8 - if(is_a($db, 'DoliDBMysqli')) { + if (is_a($db, 'DoliDBMysqli')) { /** @var DoliDBMysqli $db */ $db->db->set_charset('utf8'); } else { @@ -300,11 +300,17 @@ function backup_tables($outputfile, $tables='*') /*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; /*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; /*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; "; if (GETPOST("nobin_disable_fk")) $sqlhead .= "SET FOREIGN_KEY_CHECKS=0;\n"; - $sqlhead .= "SET SQL_MODE=\"NO_AUTO_VALUE_ON_ZERO\";\n"; + //$sqlhead .= "SET SQL_MODE=\"NO_AUTO_VALUE_ON_ZERO\";\n"; if (GETPOST("nobin_use_transaction")) $sqlhead .= "SET AUTOCOMMIT=0;\nSTART TRANSACTION;\n"; fwrite($handle, $sqlhead); @@ -321,8 +327,8 @@ function backup_tables($outputfile, $tables='*') fwrite($handle, "\n--\n-- Table structure for table `".$table."`\n--\n"); if (GETPOST("nobin_drop")) fwrite($handle,"DROP TABLE IF EXISTS `".$table."`;\n"); // Dropping table if exists prior to re create it - //fwrite($handle,"/*!40101 SET @saved_cs_client = @@character_set_client */;\n"); - //fwrite($handle,"/*!40101 SET character_set_client = utf8 */;\n"); + fwrite($handle,"/*!40101 SET @saved_cs_client = @@character_set_client */;\n"); + fwrite($handle,"/*!40101 SET character_set_client = utf8 */;\n"); $resqldrop=$db->query('SHOW CREATE TABLE '.$table); $row2 = $db->fetch_row($resqldrop); if (empty($row2[1])) @@ -338,6 +344,7 @@ function backup_tables($outputfile, $tables='*') fwrite($handle, "\n--\n-- Dumping data for table `".$table."`\n--\n"); if (!GETPOST("nobin_nolocks")) fwrite($handle, "LOCK TABLES `".$table."` WRITE;\n"); // Lock the table before inserting data (when the data will be imported back) if (GETPOST("nobin_disable_fk")) fwrite($handle, "ALTER TABLE `".$table."` DISABLE KEYS;\n"); + else fwrite($handle, "/*!40000 ALTER TABLE `".$table."` DISABLE KEYS */;\n"); $sql='SELECT * FROM '.$table; $result = $db->query($sql); diff --git a/htdocs/admin/translation.php b/htdocs/admin/translation.php index d42ae4b2ade..a51c3212c26 100644 --- a/htdocs/admin/translation.php +++ b/htdocs/admin/translation.php @@ -27,12 +27,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/html.formadmin.class.php'; -$langs->load("companies"); -$langs->load("products"); -$langs->load("admin"); -$langs->load("sms"); -$langs->load("other"); -$langs->load("errors"); +$langs->loadLangs(array("companies","products","admin","sms","other","errors")); if (!$user->admin) accessforbidden(); @@ -263,6 +258,11 @@ if ($mode == 'overwrite') { //print load_fiche_titre($langs->trans("TranslationOverwriteKey"), '', '')."\n"; + $disabled=''; + if ($action == 'edit' || empty($conf->global->MAIN_ENABLE_OVERWRITE_TRANSLATION)) $disabled=' disabled="disabled"'; + $disablededit=''; + if ($action == 'edit' || empty($conf->global->MAIN_ENABLE_OVERWRITE_TRANSLATION)) $disablededit=' disabled'; + print '
    '; print img_info().' '.$langs->trans("SomeTranslationAreUncomplete"); $urlwikitranslatordoc='https://wiki.dolibarr.org/index.php/Translator_documentation'; @@ -291,9 +291,6 @@ if ($mode == 'overwrite') // Line to add new record print "\n"; - $disablededit=''; - if ($action == 'edit') $disablededit=' disabled'; - print '
    '; print $formadmin->select_language(GETPOST('langcode'), 'langcode', 0, null, 1, 0, $disablededit?1:0, 'maxwidthonsmartphone', 1); print ''; print ''; //} - $disabled=''; - if ($action == 'edit' || empty($conf->global->MAIN_ENABLE_OVERWRITE_TRANSLATION)) $disabled=' disabled="disabled"'; - print ''; + print ''; print "
    '.$langs->trans("BlockedLogDisableNotAllowedForCountry").''; +print '
    '; +print ''; +print ''; + +$sql = "SELECT rowid, code as code_iso, code_iso as code_iso3, label, favorite"; +$sql.= " FROM ".MAIN_DB_PREFIX."c_country"; +$sql.= " WHERE active > 0"; + +$countryArray=array(); +$resql=$db->query($sql); +if ($resql) +{ + while ($obj = $db->fetch_object($resql)) + { + $countryArray[$obj->code_iso] = ($obj->code_iso && $langs->transnoentitiesnoconv("Country".$obj->code_iso)!="Country".$obj->code_iso?$langs->transnoentitiesnoconv("Country".$obj->code_iso):($obj->label!='-'?$obj->label:'')); + } +} + +$seledted = empty($conf->global->BLOCKEDLOG_DISABLE_NOT_ALLOWED_FOR_COUNTRY) ? array() : explode(',',$conf->global->BLOCKEDLOG_DISABLE_NOT_ALLOWED_FOR_COUNTRY); + +print $form->multiselectarray('BLOCKEDLOG_DISABLE_NOT_ALLOWED_FOR_COUNTRY', $countryArray, $seledted); +print ''; +print '
    '; +print '
    '; dol_fiche_end(); diff --git a/htdocs/blockedlog/admin/blockedlog_list.php b/htdocs/blockedlog/admin/blockedlog_list.php new file mode 100644 index 00000000000..ee54f18348d --- /dev/null +++ b/htdocs/blockedlog/admin/blockedlog_list.php @@ -0,0 +1,379 @@ + + * + * 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 + * the Free Software Foundation; either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** + * \file htdocs/blockedlog/admin/blockedlog_list.php + * \ingroup blockedlog + * \brief Page setup for blockedlog module + */ + +require '../../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/blockedlog/lib/blockedlog.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php'; +require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/authority.class.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; + +$langs->loadLangs(array("admin", "other", "blockedlog", "bills")); + +if (! $user->admin) accessforbidden(); + +$action = GETPOST('action','alpha'); +$contextpage= GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'myobjectlist'; // To manage different context of search +$backtopage = GETPOST('backtopage','alpha'); // Go back to a dedicated page +$optioncss = GETPOST('optioncss','aZ'); // Option for the css output (always '' except when 'print') + +$showonlyerrors = GETPOST('showonlyerrors','int'); + +$search_start = -1; +if(GETPOST('search_startyear')!='') $search_start = dol_mktime(0, 0, 0, GETPOST('search_startmonth'), GETPOST('search_startday'), GETPOST('search_startyear')); +$search_end = -1; +if(GETPOST('search_endyear')!='') $search_end= dol_mktime(23, 59, 59, GETPOST('search_endmonth'), GETPOST('search_endday'), GETPOST('search_endyear')); +$search_ref = GETPOST('search_ref', 'alpha'); +$search_amount = GETPOST('search_amount', 'alpha'); + + +// Load variable for pagination +$limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; +$sortfield = GETPOST('sortfield','alpha'); +$sortorder = GETPOST('sortorder','alpha'); +$page = GETPOST('page','int'); +if (empty($page) || $page == -1) { $page = 0; } // If $page is not defined, or '' or -1 +$offset = $limit * $page; +$pageprev = $page - 1; +$pagenext = $page + 1; + +if (empty($sortfield)) $sortfield='rowid'; +if (empty($sortorder)) $sortorder='DESC'; + + + + +$block_static = new BlockedLog($db); + + +/* + * Actions + */ + +// Purge search criteria +if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') ||GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers +{ + $search_start = -1; + $search_end = -1; + $search_ref = ''; + $search_amount = ''; + $toselect=''; + $search_array_options=array(); +} + +if ($action === 'downloadblockchain') { + + $auth = new BlockedLogAuthority($db); + + $bc = $auth->getLocalBlockChain(); + + header('Content-Type: application/octet-stream'); + header("Content-Transfer-Encoding: Binary"); + header("Content-disposition: attachment; filename=\"" .$auth->signature. ".certif\""); + + echo $bc; + + exit; +} +else if($action === 'downloadcsv') { + + $sql = "SELECT rowid,date_creation,tms,user_fullname,action,amounts,element,fk_object,date_object,ref_object,signature,fk_user,object_data"; + $sql.= " FROM ".MAIN_DB_PREFIX."blockedlog"; + $sql.= " WHERE entity = ".$conf->entity; + $sql.= " ORDER BY rowid ASC"; + $res = $db->query($sql); + + if($res) { + + $signature = $block_static->getSignature(); + + header('Content-Type: application/octet-stream'); + header("Content-Transfer-Encoding: Binary"); + header("Content-disposition: attachment; filename=\"archive-log-" .$signature. ".csv\""); + + print $langs->transnoentities('Id') + .';'.$langs->transnoentities('Date') + .';'.$langs->transnoentities('User') + .';'.$langs->transnoentities('Action') + .';'.$langs->transnoentities('Element') + .';'.$langs->transnoentities('Amounts') + .';'.$langs->transnoentities('ObjectId') + .';'.$langs->transnoentities('Date') + .';'.$langs->transnoentities('Ref') + .';'.$langs->transnoentities('Fingerprint') + .';'.$langs->transnoentities('FullData') + ."\n"; + + while($obj = $db->fetch_object($res)) { + + print $obj->rowid + .';'.$obj->date_creation + .';"'.$obj->user_fullname.'"' + .';'.$obj->action + .';'.$obj->element + .';'.$obj->amounts + .';'.$obj->fk_object + .';'.$obj->date_object + .';"'.$obj->ref_object.'"' + .';'.$obj->signature + .';"'.str_replace('"','""',$obj->object_data).'"' + ."\n"; + } + + exit; + } + else{ + setEventMessage($db->lasterror, 'errors'); + } + +} + + +/* + * View + */ + +$form=new Form($db); + +llxHeader('',$langs->trans("BlockedLogSetup")); + +$blocks = $block_static->getLog('all', 0, GETPOST('all','alpha') ? 0 : 50, $sortfield, $sortorder, $search_start, $search_end, $search_ref, $search_amount); +if (! is_array($blocks)) +{ + dol_print_error($block_static->db); + exit; +} + +$linkback=''.$langs->trans("BackToModuleList").''; +print load_fiche_titre($langs->trans("ModuleSetup").' '.$langs->trans('BlockedLog'),$linkback); + +$head=blockedlogadmin_prepare_head(); + +dol_fiche_head($head, 'fingerprints', '', -1); + +print $langs->trans("FingerprintsDesc")."
    \n"; + +print '
    '; + +$param=''; +if (! empty($contextpage) && $contextpage != $_SERVER["PHP_SELF"]) $param.='&contextpage='.urlencode($contextpage); +if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.urlencode($limit); +if ($search_start > 0) $param.='&search_startyear='.urlencode(GETPOST('search_startyear','int')).'&search_startmonth='.urlencode(GETPOST('search_startmonth','int')).'&search_startday='.urlencode(GETPOST('search_startday','int')); +if ($search_end > 0) $param.='&search_endyear='.urlencode(GETPOST('search_endyear','int')).'&search_endmonth='.urlencode(GETPOST('search_endmonth','int')).'&search_endday='.urlencode(GETPOST('search_endday','int')); +if ($optioncss != '') $param.='&optioncss='.urlencode($optioncss); +// Add $param from extra fields +//include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; + + +print ''; + + +print '
    '; // You can use div-table-responsive-no-min if you dont need reserved height for your table + +print '
    '; + +print ''; +print ''; + +print ''; + +print ''; + +print ''; +print ''; + +// Ref +print ''; + +print ''; + +// Amount +print ''; + +print ''; +print ''; + +// Action column +print ''; + +print ''; + +print ''; +print getTitleFieldOfList($langs->trans('#'), 0, $_SERVER["PHP_SELF"],'rowid','',$param,'',$sortfield,$sortorder,'minwidth50 ')."\n"; +print getTitleFieldOfList($langs->trans('Date'), 0, $_SERVER["PHP_SELF"],'date_creation','',$param,'',$sortfield,$sortorder,'')."\n"; +print getTitleFieldOfList($langs->trans('Author'), 0, $_SERVER["PHP_SELF"],'user_fullname','',$param,'',$sortfield,$sortorder,'')."\n"; +print getTitleFieldOfList($langs->trans('Action'), 0, $_SERVER["PHP_SELF"],'','',$param,'',$sortfield,$sortorder,'')."\n"; +print getTitleFieldOfList($langs->trans('Ref'), 0, $_SERVER["PHP_SELF"],'ref_object','',$param,'',$sortfield,$sortorder,'')."\n"; +print getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"],'','',$param,'',$sortfield,$sortorder,'')."\n"; +print getTitleFieldOfList($langs->trans('Amount'), 0, $_SERVER["PHP_SELF"],'','',$param,'align="right"',$sortfield,$sortorder,'')."\n"; +print getTitleFieldOfList($langs->trans('DataOfArchivedEvent'), 0, $_SERVER["PHP_SELF"],'','',$param,'align="center"',$sortfield,$sortorder,'')."\n"; +print getTitleFieldOfList($langs->trans('Fingerprint'), 0, $_SERVER["PHP_SELF"],'','',$param,'',$sortfield,$sortorder,'')."\n"; +print getTitleFieldOfList('', 0, $_SERVER["PHP_SELF"],'','',$param,'align="center"',$sortfield,$sortorder,'')."\n"; +print ''; + +$loweridinerror=0; +$checkresult=array(); +foreach($blocks as &$block) { + $checksignature = $block->checkSignature(); + $checkresult[$block->id]=$checksignature; // false if error + if (! $checksignature) + { + if (empty($loweridinerror)) $loweridinerror=$block->id; + else $loweridinerror = min($loweridinerror, $block->id); + } + +} + +foreach($blocks as &$block) { + $object_link = $block->getObjectLink(); + + if (empty($showonlyerrors) || ! $checkresult[$block->id] || ($loweridinerror && $block->id >= $loweridinerror)) + { + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + + print ''; + + print ''; + + print ''; + + } +} + +print '
     '; +print $form->select_date($search_start,'search_start'); +print $form->select_date($search_end,'search_end'); +print ''; +$searchpicto=$form->showFilterButtons(); +print $searchpicto; +print '
    '.$block->id.''.dol_print_date($block->tms,'dayhour').''; + //print $block->getUser() + print $block->user_fullname; + print ''.$langs->trans('log'.$block->action).''.$block->ref_object.''.$object_link.''.price($block->amounts).''.img_info($langs->trans('ShowDetails')).''; + print $form->textwithpicto(dol_trunc($block->signature, '12'), $block->signature); + print ''; + if (! $checkresult[$block->id] || ($loweridinerror && $block->id >= $loweridinerror)) // If error + { + if ($checkresult[$block->id]) print img_picto($langs->trans('OkCheckFingerprintValidityButChainIsKo'), 'statut1'); + else print img_picto($langs->trans('KoCheckFingerprintValidity'), 'statut8'); + } + else + { + print img_picto($langs->trans('OkCheckFingerprintValidity'), 'statut4'); + } + + if(!empty($conf->global->BLOCKEDLOG_USE_REMOTE_AUTHORITY) && !empty($conf->global->BLOCKEDLOG_AUTHORITY_URL)) { + print ' '.($block->certified ? img_picto($langs->trans('AddedByAuthority'), 'info') : img_picto($langs->trans('NotAddedByAuthorityYet'), 'info_black') ); + } + print '
    '; + +print '
    '; + +print '
    '; + +print ''."\n"; + + +if(!empty($conf->global->BLOCKEDLOG_USE_REMOTE_AUTHORITY) && !empty($conf->global->BLOCKEDLOG_AUTHORITY_URL)) { + +?> + + +
    '; + +llxFooter(); +$db->close(); diff --git a/htdocs/blockedlog/admin/fingerprints.php b/htdocs/blockedlog/admin/fingerprints.php deleted file mode 100644 index da149d4340d..00000000000 --- a/htdocs/blockedlog/admin/fingerprints.php +++ /dev/null @@ -1,261 +0,0 @@ - - * - * 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 - * the Free Software Foundation; either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -/** - * \file htdocs/blockedlog/admin/fingerprints.php - * \ingroup blockedlog - * \brief Page setup for blockedlog module - */ - -require '../../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/blockedlog/lib/blockedlog.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php'; -require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/authority.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; - -$langs->load("admin"); -$langs->load("other"); -$langs->load("blockedlog"); - -if (! $user->admin) accessforbidden(); - -$action = GETPOST('action','alpha'); -$showonlyerrors = GETPOST('showonlyerrors','int'); - -$block_static = new BlockedLog($db); - -if($action === 'downloadblockchain') { - - $auth = new BlockedLogAuthority($db); - - $bc = $auth->getLocalBlockChain(); - - header('Content-Type: application/octet-stream'); - header("Content-Transfer-Encoding: Binary"); - header("Content-disposition: attachment; filename=\"" .$auth->signature. ".certif\""); - - echo $bc; - - exit; -} -else if($action === 'downloadcsv') { - - $res = $db->query("SELECT rowid,tms,action,amounts,element,fk_object,date_object,ref_object,signature,fk_user - FROM ".MAIN_DB_PREFIX."blockedlog ORDER BY rowid ASC"); - - if($res) { - - $signature = $block_static->getSignature(); - - header('Content-Type: application/octet-stream'); - header("Content-Transfer-Encoding: Binary"); - header("Content-disposition: attachment; filename=\"" .$signature. ".csv\""); - - print $langs->transnoentities('Id') - .';'.$langs->transnoentities('Timestamp') - .';'.$langs->transnoentities('Action') - .';'.$langs->transnoentities('Amounts') - .';'.$langs->transnoentities('Element') - .';'.$langs->transnoentities('ObjectId') - .';'.$langs->transnoentities('Date') - .';'.$langs->transnoentities('Ref') - .';'.$langs->transnoentities('Fingerprint') - .';'.$langs->transnoentities('User')."\n"; - - while($obj = $db->fetch_object($res)) { - - print $obj->rowid - .';'.$obj->tms - .';'.$obj->action - .';'.$obj->amounts - .';'.$obj->element - .';'.$obj->fk_object - .';'.$obj->date_object - .';'.$obj->ref_object - .';'.$obj->signature - .';'.$obj->fk_user."\n"; - - } - - exit; - } - else{ - setEventMessage($db->lasterror, 'errors'); - } - -} - -/* - * View - */ - -$blocks = $block_static->getLog('all', 0, GETPOST('all') ? 0 : 50); - -$form=new Form($db); - -llxHeader('',$langs->trans("BlockedLogSetup")); - -$linkback=''.$langs->trans("BackToModuleList").''; -print load_fiche_titre($langs->trans("ModuleSetup").' '.$langs->trans('BlockedLog'),$linkback); - -$head=blockedlogadmin_prepare_head(); - -dol_fiche_head($head, 'fingerprints', '', -1); - -print $langs->trans("FingerprintsDesc")."
    \n"; - -print '
    '; - -print ''; - - -print ''; -print ''; - -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; -print ''; - -print ''; - -foreach($blocks as &$block) { - - $checksignature = $block->checkSignature(); - $object_link = $block->getObjectLink(); - - if(!$showonlyerrors || $block->error>0) { - - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - - print ''; - - print ''; - - print ''; - - } -} - -print '
    '.$langs->trans('#').''.$langs->trans('Date').''.$langs->trans('Author').''.$langs->trans('Action').''.$langs->trans('Ref').''.$langs->trans('Element').''.$langs->trans('Amount').''.$langs->trans('DataOfArchivedEvent').''.$langs->trans('Fingerprint').'
    '.$block->id.''.dol_print_date($block->tms,'dayhour').''.$block->getUser().''.$langs->trans('log'.$block->action).''.$block->ref_object.''.$object_link.''.price($block->amounts).''.img_info($langs->trans('ShowDetails')).''; - print $form->textwithpicto(dol_trunc($block->signature, '12'), $block->signature); - print ''; - print $block->error == 0 ? img_picto($langs->trans('OkCheckFingerprintValidity'), 'tick') : img_picto($langs->trans('KoCheckFingerprintValidity'), 'statut8'); - - if(!empty($conf->global->BLOCKEDLOG_USE_REMOTE_AUTHORITY) && !empty($conf->global->BLOCKEDLOG_AUTHORITY_URL)) { - print ' '.($block->certified ? img_picto($langs->trans('AddedByAuthority'), 'info') : img_picto($langs->trans('NotAddedByAuthorityYet'), 'info_black') ); - } - print '
    '; - - - -?> - - -global->BLOCKEDLOG_USE_REMOTE_AUTHORITY) && !empty($conf->global->BLOCKEDLOG_AUTHORITY_URL)) { - -?> - - -
    '; - -llxFooter(); -$db->close(); diff --git a/htdocs/blockedlog/ajax/check_signature.php b/htdocs/blockedlog/ajax/check_signature.php index 170693a2ece..4b50474b4a9 100644 --- a/htdocs/blockedlog/ajax/check_signature.php +++ b/htdocs/blockedlog/ajax/check_signature.php @@ -45,7 +45,7 @@ $auth->syncSignatureWithAuthority(); $block_static = new BlockedLog($db); -$blocks = $block_static->getLog('just_certified', 0, 0, 1) ; +$blocks = $block_static->getLog('just_certified', 0, 0, 'rowid', 'ASC'); $auth->signature = $block_static->getSignature(); diff --git a/htdocs/blockedlog/class/authority.class.php b/htdocs/blockedlog/class/authority.class.php index 707e3b1b172..b1084b01a54 100644 --- a/htdocs/blockedlog/class/authority.class.php +++ b/htdocs/blockedlog/class/authority.class.php @@ -1,4 +1,4 @@ - * * This program is free software; you can redistribute it and/or modify @@ -20,76 +20,76 @@ */ class BlockedLogAuthority { - + /** * Id of the log * @var int */ public $id; - + /** * Unique fingerprint of the blockchain to store * @var string */ public $signature = ''; - + /** * Entire fingerprints blockchain * @var string */ public $blockchain = ''; - + /** * timestamp * @var int */ public $tms = 0; - + /** * Constructor * * @param DoliDB $db Database handler */ public function __construct($db) { - + $this->db = $db; - + } - + /** - * Get the blockchain + * Get the blockchain * * @return string blockchain */ public function getLocalBlockChain() { - + $block_static = new BlockedLog($this->db); - + $this->signature = $block_static->getSignature(); - - $blocks = $block_static->getLog('all', 0, 0, 1) ; - + + $blocks = $block_static->getLog('all', 0, 0, 'rowid', 'ASC') ; + $this->blockchain = ''; - + foreach($blocks as &$b) { $this->blockchain.=$b->signature; - + } - + return $this->blockchain; } - + /** * Get hash of the block chain to check * * @return string hash md5 of blockchain */ public function getBlockchainHash() { - + return md5($this->signature.$this->blockchain); - + } - + /** * Get hash of the block chain to check * @@ -97,22 +97,22 @@ class BlockedLogAuthority * @return boolean */ public function checkBlockchain($hash) { - + return ($hash === $this->getBlockchainHash() ); - + } - + /** * Add a new block to the chain * * @param string $block new block to chain */ public function addBlock($block) { - + $this->blockchain.=$block; - + } - + /** * hash already exist into chain ? * @@ -120,20 +120,20 @@ class BlockedLogAuthority * @return boolean */ public function checkBlock($block) { - + if(strlen($block)!=64) return false; - + $blocks = str_split($this->blockchain,64); - + if(!in_array($block,$blocks)) { return true; - } + } else{ return false; } } - - + + /** * Get object from database * @@ -142,40 +142,40 @@ class BlockedLogAuthority * @return int >0 if OK, <0 if KO, 0 if not found */ public function fetch($id, $signature='') { - + global $langs; - + dol_syslog(get_class($this)."::fetch id=".$id, LOG_DEBUG); - + if (empty($id) && empty($signature)) { $this->error='BadParameter'; return -1; } - + $langs->load("blockedlog"); - + $sql = "SELECT b.rowid, b.signature, b.blockchain, b.tms"; $sql.= " FROM ".MAIN_DB_PREFIX."blockedlog_authority as b"; - + if ($id) $sql.= " WHERE b.rowid = ". $id; else if($signature)$sql.= " WHERE b.signature = '". $this->db->escape( $signature ) ."'" ; - + $resql=$this->db->query($sql); if ($resql) { if ($this->db->num_rows($resql)) { $obj = $this->db->fetch_object($resql); - + $this->id = $obj->rowid; $this->ref = $obj->rowid; - + $this->signature = $obj->signature; $this->blockchain = $obj->blockchain; - + $this->tms = $this->db->jdate($obj->tms); - + return 1; } else @@ -189,9 +189,9 @@ class BlockedLogAuthority $this->error=$this->db->error(); return -1; } - + } - + /** * Create authority in database. * @@ -199,17 +199,17 @@ class BlockedLogAuthority * @return int <0 if KO, >0 if OK */ public function create($user) { - + global $conf,$langs,$hookmanager; - + $langs->load('blockedlog'); - + $error=0; - + dol_syslog(get_class($this).'::create', LOG_DEBUG); - + $this->db->begin(); - + $sql = "INSERT INTO ".MAIN_DB_PREFIX."blockedlog_authority ("; $sql.= " signature,"; $sql.= " blockchain"; @@ -217,18 +217,18 @@ class BlockedLogAuthority $sql.= "'".$this->db->escape($this->signature)."',"; $sql.= "'".$this->db->escape($this->blockchain)."'"; $sql.= ")"; - + $res = $this->db->query($sql); if ($res) { $id = $this->db->last_insert_id(MAIN_DB_PREFIX."blockedlog_authority"); - + if ($id > 0) { $this->id = $id; - + $this->db->commit(); - + return $this->id; } else @@ -243,9 +243,9 @@ class BlockedLogAuthority $this->db->rollback(); return -1; } - + } - + /** * Create authority in database. * @@ -253,26 +253,26 @@ class BlockedLogAuthority * @return int <0 if KO, >0 if OK */ public function update($user) { - + global $conf,$langs,$hookmanager; - + $langs->load('blockedlog'); - + $error=0; - + dol_syslog(get_class($this).'::create', LOG_DEBUG); - + $this->db->begin(); - + $sql = "UPDATE ".MAIN_DB_PREFIX."blockedlog_authority SET "; $sql.= " blockchain='".$this->db->escape($this->blockchain)."'"; $sql.= " WHERE rowid=".$this->id; - + $res = $this->db->query($sql); if ($res) { $this->db->commit(); - + return 1; } else @@ -281,9 +281,9 @@ class BlockedLogAuthority $this->db->rollback(); return -1; } - + } - + /** * For cron to sync to authority. * @@ -291,43 +291,43 @@ class BlockedLogAuthority */ public function syncSignatureWithAuthority() { global $conf, $langs; - + //TODO create cron task on activation - + if(empty($conf->global->BLOCKEDLOG_AUTHORITY_URL) || empty($conf->global->BLOCKEDLOG_USE_REMOTE_AUTHORITY)) { $this->error = $langs->trans('NoAuthorityURLDefined'); return -2; } require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php'; - + $block_static = new BlockedLog($this->db); - - $blocks = $block_static->getLog('not_certified', 0, 0, 1); - + + $blocks = $block_static->getLog('not_certified', 0, 0, 'rowid', 'ASC'); + $signature=$block_static->getSignature(); - + foreach($blocks as &$block) { - + $url = $conf->global->BLOCKEDLOG_AUTHORITY_URL.'/blockedlog/ajax/authority.php?s='.$signature.'&b='.$block->signature; - + $res = file_get_contents($url); echo $block->signature.' '.$url. ' '.$res.'
    '; if($res === 'blockalreadyadded' || $res === 'blockadded') { - + $block->setCertified(); - + } else { - + $this->error = $langs->trans('ImpossibleToContactAuthority ',$url); return -1; } - - + + } - + return 1; } - + } \ No newline at end of file diff --git a/htdocs/blockedlog/class/blockedlog.class.php b/htdocs/blockedlog/class/blockedlog.class.php index fffd5cc9d80..621ee254a48 100644 --- a/htdocs/blockedlog/class/blockedlog.class.php +++ b/htdocs/blockedlog/class/blockedlog.class.php @@ -1,5 +1,6 @@ + * Copyright (C) 2017 Laurent Destailleur * * 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 @@ -13,6 +14,8 @@ * * You should have received a copy of the GNU General Public License * along with this program. If not, see . + * + * See https://medium.com/@lhartikk/a-blockchain-in-200-lines-of-code-963cc1cc0e54 */ /** @@ -145,7 +148,7 @@ class BlockedLog } } - return $langs->trans('ImpossibleToReloadObject', $this->element, $this->fk_object); + return ''.$langs->trans('ImpossibleToReloadObject', $this->element, $this->fk_object).''; } @@ -176,10 +179,20 @@ class BlockedLog * Populate properties of log from object data * * @param Object $object object to store + * @param string $action action + * @param string $amounts amounts */ - public function setObjectData(&$object) + public function setObjectData(&$object, $action, $amounts) { - // Set date + global $langs, $user, $mysoc; + + // Generic fields + + // action + $this->action = $action; + // amount + $this->amounts= $amounts; + // date if ($object->element == 'payment' || $object->element == 'payment_supplier') { $this->date_object = $object->datepaye; @@ -191,27 +204,67 @@ class BlockedLog else { $this->date_object = $object->date; } - - $this->ref_object = $object->ref; + // ref + $this->ref_object = ((! empty($object->newref)) ? $object->newref : $object->ref); // newref is set when validating a draft, ref is set in other cases + // type of object $this->element = $object->element; + // id of object $this->fk_object = $object->id; $this->object_data=new stdClass(); - if ($this->element == 'facture') + // Add thirdparty info + + if (empty($object->thirdparty) && method_exists($object, 'fetch_thirdparty')) $object->fetch_thirdparty(); + + if (! empty($object->thirdparty)) { - if(empty($object->thirdparty))$object->fetch_thirdparty(); $this->object_data->thirdparty = new stdClass(); - foreach($object->thirdparty as $key=>$value) { - if(!is_object($value)) $this->object_data->thirdparty->{$key} = $value; + foreach($object->thirdparty as $key=>$value) + { + if (in_array($key, array('fields'))) continue; // Discard some properties + if (! in_array($key, array( + 'name','name_alias','ref_ext','address','zip','town','state_code','country_code','idprof1','idprof2','idprof3','idprof4','idprof5','idprof6','phone','fax','email','barcode', + 'tva_intra', 'localtax1_assuj', 'localtax1_value', 'localtax2_assuj', 'localtax2_value', 'managers', 'capital', 'typent_code', 'forme_juridique_code', 'code_client', 'code_fournisseur' + ))) continue; // Discard if not into a dedicated list + if (!is_object($value)) $this->object_data->thirdparty->{$key} = $value; } + } + // Add company info + if (! empty($mysoc)) + { + $this->object_data->mycompany = new stdClass(); + + foreach($mysoc as $key=>$value) + { + if (in_array($key, array('fields'))) continue; // Discard some properties + if (! in_array($key, array( + 'name','name_alias','ref_ext','address','zip','town','state_code','country_code','idprof1','idprof2','idprof3','idprof4','idprof5','idprof6','phone','fax','email','barcode', + 'tva_intra', 'localtax1_assuj', 'localtax1_value', 'localtax2_assuj', 'localtax2_value', 'managers', 'capital', 'typent_code', 'forme_juridique_code', 'code_client', 'code_fournisseur' + ))) continue; // Discard if not into a dedicated list + if (!is_object($value)) $this->object_data->mycompany->{$key} = $value; + } + } + + // Add user info + + $this->fk_user = $user->id; + $this->user_fullname = $user->getFullName($langs); + + // Field specific to object + + if ($this->element == 'facture') + { $this->object_data->total_ht = (double) $object->total_ht; $this->object_data->total_tva = (double) $object->total_tva; $this->object_data->total_ttc = (double) $object->total_ttc; - $this->object_data->total_localtax1= (double) $object->total_localtax1; - $this->object_data->total_localtax2= (double) $object->total_localtax2; + $this->object_data->total_localtax1 = (double) $object->total_localtax1; + $this->object_data->total_localtax2 = (double) $object->total_localtax2; + + $this->object_data->revenue_stamp = (double) $object->revenue_stamp; + $this->object_data->date_pointoftax = (double) $object->date_pointoftax; $this->object_data->note_public = (double) $object->note_public; } if($this->element == 'invoice_supplier') { @@ -225,11 +278,12 @@ class BlockedLog $this->object_data->total_ht = (double) $object->total_ht; $this->object_data->total_tva = (double) $object->total_tva; $this->object_data->total_ttc = (double) $object->total_ttc; - $this->object_data->total_localtax1= (double) $object->total_localtax1; - $this->object_data->total_localtax2= (double) $object->total_localtax2; - $this->object_data->note_public = (double) $object->note_public; - $this->object_data->note_private= (double) $object->note_private; + $this->object_data->total_localtax1 = (double) $object->total_localtax1; + $this->object_data->total_localtax2 = (double) $object->total_localtax2; + $this->object_data->revenue_stamp = (double) $object->revenue_stamp; + $this->object_data->date_pointoftax = (double) $object->date_pointoftax; + $this->object_data->note_public = (double) $object->note_public; } elseif ($this->element == 'payment'|| $object->element == 'payment_supplier') { @@ -261,7 +315,7 @@ class BlockedLog $langs->load("blockedlog"); - $sql = "SELECT b.rowid, b.signature, b.amounts, b.action, b.element, b.fk_object, b.certified, b.tms, b.fk_user, b.date_object, b.ref_object, b.object_data"; + $sql = "SELECT b.rowid, b.date_creation, b.signature, b.signature_line, b.amounts, b.action, b.element, b.fk_object, b.certified, b.tms, b.fk_user, b.user_fullname, b.date_object, b.ref_object, b.object_data"; $sql.= " FROM ".MAIN_DB_PREFIX."blockedlog as b"; if ($id) $sql.= " WHERE b.rowid = ". $id; @@ -275,7 +329,9 @@ class BlockedLog $this->id = $obj->rowid; $this->ref = $obj->rowid; - $this->signature = $obj->signature; + $this->date_creation = $this->db->jdate($obj->date_creation); + $this->tms = $this->db->jdate($obj->tms); + $this->amounts = (double) $obj->amounts; $this->action = $obj->action; $this->element = $obj->element; @@ -284,14 +340,15 @@ class BlockedLog $this->date_object = $this->db->jdate($obj->date_object); $this->ref_object = $obj->ref_object; - $this->certified = ($obj->certified == 1); - $this->fk_user = $obj->fk_user; - - $this->tms = $this->db->jdate($obj->tms); + $this->user_fullname = $obj->user_fullname; $this->object_data = unserialize($obj->object_data); + $this->signature = $obj->signature; + $this->signature_line = $obj->signature_line; + $this->certified = ($obj->certified == 1); + return 1; } else @@ -337,11 +394,12 @@ class BlockedLog $error=0; - dol_syslog(get_class($this).'::create', LOG_DEBUG); - - $this->getSignatureRecursive(); + // Clean data + $this->amounts=(double) $this->amounts; + dol_syslog(get_class($this).'::create action='.$this->action.' fk_user='.$this->fk_user.' user_fullname='.$this->user_fullname, LOG_DEBUG); + // Check parameters/properties if (is_null($this->amounts)) { $this->error=$langs->trans("BlockLogNeedAmountsValue"); @@ -355,18 +413,27 @@ class BlockedLog return -2; } - if(empty($this->action)) { - $this->error=$langs->trans("BlockLogNeedAction"); + if (empty($this->action) || empty($this->fk_user) || empty($this->user_fullname)) { + $this->error=$langs->trans("BadParameterWhenCallingCreateOfBlockedLog"); dol_syslog($this->error, LOG_WARNING); return -3; } - $this->fk_user = $user->id; + $this->date_creation = dol_now(); $this->db->begin(); + $previoushash = $this->getPreviousHash(1); // This get last record and lock database until insert is done + + $keyforsignature = $this->buildKeyForSignature(); + + $this->signature_line = dol_hash($keyforsignature, '5'); // Not really usefull + $this->signature = dol_hash($previoushash . $keyforsignature, '5'); + //var_dump($keyforsignature);var_dump($previoushash);var_dump($this->signature_line);var_dump($this->signature); + $sql = "INSERT INTO ".MAIN_DB_PREFIX."blockedlog ("; - $sql.= "action,"; + $sql.= " date_creation,"; + $sql.= " action,"; $sql.= " amounts,"; $sql.= " signature,"; $sql.= " signature_line,"; @@ -377,19 +444,22 @@ class BlockedLog $sql.= " object_data,"; $sql.= " certified,"; $sql.= " fk_user,"; + $sql.= " user_fullname,"; $sql.= " entity"; $sql.= ") VALUES ("; + $sql.= "'".$this->db->idate($this->date_creation)."',"; $sql.= "'".$this->db->escape($this->action)."',"; - $sql.= "".$this->amounts.","; + $sql.= $this->amounts.","; $sql.= "'".$this->db->escape($this->signature)."',"; $sql.= "'".$this->db->escape($this->signature_line)."',"; $sql.= "'".$this->db->escape($this->element)."',"; - $sql.= "".$this->fk_object.","; + $sql.= $this->fk_object.","; $sql.= "'".$this->db->idate($this->date_object)."',"; $sql.= "'".$this->db->escape($this->ref_object)."',"; $sql.= "'".$this->db->escape(serialize($this->object_data))."',"; $sql.= "0,"; - $sql.= "".$user->id.","; + $sql.= $this->fk_user.","; + $sql.= "'".$this->db->escape($this->user_fullname)."',"; $sql.= $conf->entity; $sql.= ")"; @@ -419,93 +489,122 @@ class BlockedLog return -1; } + // The commit will release the lock so we can insert nex record } /** - * return crypted value. + * Check if current signature still correct compare to the chain * - * @param string $value string to crypt - * @return string crypted string + * @return boolean True if OK, False if KO */ - private function crypt($value) { + public function checkSignature() + { - return hash('sha256',$value); + //$oldblockedlog = new BlockedLog($this->db); + //$previousrecord = $oldblockedlog->fetch($this->id - 1); + $previoushash = $this->getPreviousHash(0, $this->id); - } + // Recalculate hash + $keyforsignature = $this->buildKeyForSignature(); + $signature_line = dol_hash($keyforsignature, '5'); // Not really usefull + $signature = dol_hash($previoushash . $keyforsignature, '5'); + //var_dump($previoushash); var_dump($keyforsignature); var_dump($signature_line); var_dump($signature); - /** - * check if current signature still correct compare to the chain - * - * @return boolean - */ - public function checkSignature() { + $res = ($signature === $this->signature); - $signature_to_test = $this->signature; - - $this->getSignatureRecursive(); - - $res = ($signature_to_test === $this->signature); - - if(!$res) { - $this->error++; + if (!$res) { + $this->error = 'Signature KO'; } return $res; } /** - * set current signatures + * Return a string for signature + * + * @return string Key for signature */ - private function getSignatureRecursive(){ + private function buildKeyForSignature() + { + //print_r($this->object_data); + return $this->date_creation.'|'.$this->action.'|'.$this->amounts.'|'.$this->ref_object.'|'.$this->date_object.'|'.$this->user_fullname.'|'.print_r($this->object_data, true); + } - $this->signature_line = $this->crypt( $this->action . $this->getSignature() . $this->amounts . print_r($this->object_data, true) ); - /*if($this->signature=='d6320580a02c1ab67fcc0a6d49d453c7d96dda0148901736f7f55725bfe1b900' || $this->signature=='ea65d435ff12ca929936a406aa9d707d99fb334c127878d256b602a5541bbbc9') { - var_dump($this->signature_line,$this->action ,$this->getSignature() , $this->amounts , $this->object_data); - }*/ - $this->signature = $this->signature_line; - $logs = $this->getLog('all', 0, 0, 1) ; - if($logs!==false) { - foreach($logs as &$b) { + /** + * Get previous signature/hash in chain + * + * @param int $withlock 1=With a lock + * @param int $beforeid Before id + * @return string Hash of last record + */ + private function getPreviousHash($withlock=0, $beforeid=0) + { + global $conf; - if($this->id>0 && $b->id == $this->id) break; // on arrête sur un enregistrement précis pour recalculer une signature + $previoussignature=''; - $b->getCurrentValue(); // on récupère la valeur actuelle en base de l'élément enregistré + $sql="SELECT rowid, signature FROM ".MAIN_DB_PREFIX."blockedlog WHERE entity=".$conf->entity; + if ($beforeid) $sql.= " AND rowid < ".(int) $beforeid; + $sql.=" ORDER BY rowid DESC LIMIT 1"; + $sql.=($withlock ? " FOR UPDATE ": ""); - $this->signature = $this->crypt($this->signature. $this->action . $b->signature . $b->amounts); - } - } + $resql = $this->db->query($sql); + if ($resql) { + $obj = $this->db->fetch_object($resql); + if ($obj) + { + $previoussignature = $obj->signature; + } + } + else + { + dol_print_error($this->db); + exit; + } + if (empty($previoussignature)) + { + // First signature line (line 0) + $previoussignature = $this->getSignature(); + } + + return $previoussignature; } /** - * return log object for a element. + * Return array of log objects (with criterias) * * @param string $element element to search * @param int $fk_object id of object to search * @param int $limit max number of element, 0 for all - * @param string $order sort of query + * @param string $sortfield sort field + * @param string $sortorder sort order + * @param int $search_start start time limit + * @param int $search_end end time limit + * @param string $search_ref search ref + * @param string $search_amount search amount * @return array array of object log */ - public function getLog($element, $fk_object, $limit = 0, $order = -1) { - global $conf,$cachedlogs ; + public function getLog($element, $fk_object, $limit = 0, $sortfield = '', $sortorder = '', $search_start = -1, $search_end = -1, $search_ref='', $search_amount='') + { + global $conf, $cachedlogs; /* $cachedlogs allow fastest search */ - if(empty($cachedlogs)) $cachedlogs=array(); + if (empty($cachedlogs)) $cachedlogs=array(); - - if($element=='all') { + if ($element=='all') { $sql="SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog WHERE entity=".$conf->entity; } - else if($element=='not_certified') { + else if ($element=='not_certified') { $sql="SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog WHERE entity=".$conf->entity." AND certified = 0"; } - else if($element=='just_certified') { + else if ($element=='just_certified') { $sql="SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog WHERE entity=".$conf->entity." AND certified = 1"; @@ -513,10 +612,14 @@ class BlockedLog else{ $sql="SELECT rowid FROM ".MAIN_DB_PREFIX."blockedlog WHERE element='".$element."' AND fk_object=".(int) $fk_object; - } - $sql.=($order<0 ? ' ORDER BY rowid DESC ' : ' ORDER BY rowid ASC '); + if ($search_start > 0) $sql.=" AND date_creation >= '".$this->db->idate($search_start)."'"; + if ($search_end > 0) $sql.=" AND date_creation <= '".$this->db->idate($search_end)."'"; + if ($search_ref != '') $sql.=natural_search("ref_object", $search_ref); + if ($search_amount != '') $sql.=natural_search("amounts", $search_amount, 1); + + $sql.=$this->db->order($sortfield, $sortorder); if($limit > 0 )$sql.=' LIMIT '.$limit; @@ -526,9 +629,9 @@ class BlockedLog $results=array(); - while($obj = $this->db->fetch_object($res)) { + while ($obj = $this->db->fetch_object($res)) { - if(!isset($cachedlogs[$obj->rowid])) { + if (!isset($cachedlogs[$obj->rowid])) { $b=new BlockedLog($this->db); $b->fetch($obj->rowid); @@ -536,7 +639,6 @@ class BlockedLog } $results[] = $cachedlogs[$obj->rowid]; - } return $results; @@ -547,52 +649,19 @@ class BlockedLog } /** - * set amounts of log from current element value in order to compare signature. - */ - private function getCurrentValue() { - - if($this->element === 'payment') { - $sql="SELECT amount FROM ".MAIN_DB_PREFIX."paiement WHERE rowid=".$this->fk_object; - - $res = $this->db->query($sql); - - if($res && $obj = $this->db->fetch_object($res)) { - $this->amounts = (double) $obj->amount; - } - } - if($this->element === 'payment_supplier') { - $sql="SELECT amount FROM ".MAIN_DB_PREFIX."paiementfourn WHERE rowid=".$this->fk_object; - - $res = $this->db->query($sql); - - if($res && $obj = $this->db->fetch_object($res)) { - $this->amounts = (double) $obj->amount; - } - } - elseif($this->element === 'facture') { - $sql="SELECT total_ttc FROM ".MAIN_DB_PREFIX."facture WHERE rowid=".$this->fk_object; - - $res = $this->db->query($sql); - if($res && $obj = $this->db->fetch_object($res)) { - $this->amounts = (double) $obj->total_ttc; - } - } - - } - - /** - * Return and set the entity signature included into line signature + * Return the signature (hash) of the "genesis-block" (Block 0) * - * @return string current entity signature + * @return string Signature of genesis-block for current conf->entity */ - public function getSignature() { + public function getSignature() + { global $db,$conf,$mysoc; if (empty($conf->global->BLOCKEDLOG_ENTITY_FINGERPRINT)) { // creation of a unique fingerprint require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; - $fingerprint = $this->crypt(print_r($mysoc,true).time().rand(0,1000)); + $fingerprint = dol_hash(print_r($mysoc,true).getRandomPassword(1), '5'); dolibarr_set_const($db, 'BLOCKEDLOG_ENTITY_FINGERPRINT', $fingerprint, 'chaine',0,'Numeric Unique Fingerprint', $conf->entity); diff --git a/htdocs/blockedlog/lib/blockedlog.lib.php b/htdocs/blockedlog/lib/blockedlog.lib.php index cffac7cbff9..d377384f1c4 100644 --- a/htdocs/blockedlog/lib/blockedlog.lib.php +++ b/htdocs/blockedlog/lib/blockedlog.lib.php @@ -38,7 +38,7 @@ function blockedlogadmin_prepare_head() $head[$h][2] = 'blockedlog'; $h++; - $head[$h][0] = DOL_URL_ROOT."/blockedlog/admin/fingerprints.php"; + $head[$h][0] = DOL_URL_ROOT."/blockedlog/admin/blockedlog_list.php"; $head[$h][1] = $langs->trans("Fingerprints"); $head[$h][2] = 'fingerprints'; $h++; diff --git a/htdocs/bookmarks/bookmarks.lib.php b/htdocs/bookmarks/bookmarks.lib.php index dc91b259018..319c44c9d73 100644 --- a/htdocs/bookmarks/bookmarks.lib.php +++ b/htdocs/bookmarks/bookmarks.lib.php @@ -35,7 +35,7 @@ function printBookmarksList($aDb, $aLangs) $db = $aDb; $langs = $aLangs; - $ret.= ''."\n"; + $ret = ''."\n"; if (! empty($conf->use_javascript_ajax)) { // Bookmark autosubmit can't work when javascript is off. @@ -67,17 +67,15 @@ function printBookmarksList($aDb, $aLangs) $url.=($tmpurl?'?'.$tmpurl:''); } - $ret = ''; - // Menu bookmark - $ret.= ''."\n"; + $ret = ''."\n"; $ret.= ''."\n"; $ret.= '
    '; $ret.= '
    '.$langs->trans("RepeatEvent").''; + print ''; + $arrayrecurrulefreq=array( + 'no'=>$langs->trans("No"), + 'MONTHLY'=>$langs->trans("EveryMonth"), + 'WEEKLY'=>$langs->trans("EveryWeek"), + //'DAYLY'=>$langs->trans("EveryDay") + ); + $selectedrecurrulefreq='no'; + $selectedrecurrulebymonthday=''; + $selectedrecurrulebyday=''; + if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i',$object->recurrule,$reg)) $selectedrecurrulefreq=$reg[1]; + if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY=(\d+)/i',$object->recurrule,$reg)) $selectedrecurrulebymonthday=$reg[1]; + if ($object->recurrule && preg_match('/FREQ=WEEKLY.*BYDAY(\d+)/i',$object->recurrule,$reg)) $selectedrecurrulebyday=$reg[1]; + print $form->selectarray('recurrulefreq', $arrayrecurrulefreq, $selectedrecurrulefreq, 0, 0, 0, '', 0, 0, 0, '', 'marginrightonly'); + // If recurrulefreq is MONTHLY + print ''; + // If recurrulefreq is WEEKLY + print ''; + print ''; + print '
    '.$langs->trans("Status").' / '.$langs->trans("Percentage").''; @@ -712,7 +783,7 @@ if ($action == 'create') // Location if (empty($conf->global->AGENDA_DISABLE_LOCATION)) { - print '
    '.$langs->trans("Location").'
    '.$langs->trans("Location").'
    '; - print '

    '; + + + print '


    '; print ''; - // Related company - print ''; + + // Related contact + print ''; } - print ''; - - // Related contact - print ''; - // Project if (! empty($conf->projet->enabled)) @@ -791,19 +870,16 @@ if ($action == 'create') // Projet associe $langs->load("projects"); - print ''; } if (!empty($origin) && !empty($originid)) { include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; - print ''; + print ''; print ''; print ''; print ''; @@ -817,14 +893,14 @@ if ($action == 'create') } // Priority - print ''; // Description print ''; @@ -876,10 +952,12 @@ if ($id > 0) $object->fulldayevent= GETPOST("fullday")?1:0; $object->location = GETPOST('location'); $object->socid = GETPOST("socid"); + $socpeopleassigned = GETPOST("socpeopleassigned",'array'); + foreach ($socpeopleassigned as $tmpid) $object->socpeopleassigned[$id] = array('id' => $tmpid); $object->contactid = GETPOST("contactid",'int'); $object->fk_project = GETPOST("projectid",'int'); - $object->note = GETPOST("note"); + $object->note = GETPOST("note",'none'); } if ($result1 < 0 || $result2 < 0 || $result3 < 0 || $result4 < 0 || $result5 < 0) @@ -966,7 +1044,7 @@ if ($id > 0) } // Title - print 'global->AGENDA_USE_EVENT_TYPE)?' class="fieldrequired"':'').'>'.$langs->trans("Title").''; + print 'global->AGENDA_USE_EVENT_TYPE)?' class="fieldrequired"':'').'>'.$langs->trans("Title").''; // Full day event print ''; @@ -1003,13 +1081,13 @@ if ($id > 0) if ($object->recurrule && preg_match('/FREQ=([A-Z]+)/i',$object->recurrule,$reg)) $selectedrecurrulefreq=$reg[1]; if ($object->recurrule && preg_match('/FREQ=MONTHLY.*BYMONTHDAY=(\d+)/i',$object->recurrule,$reg)) $selectedrecurrulebymonthday=$reg[1]; if ($object->recurrule && preg_match('/FREQ=WEEKLY.*BYDAY(\d+)/i',$object->recurrule,$reg)) $selectedrecurrulebyday=$reg[1]; - print $form->selectarray('recurrulefreq', $arrayrecurrulefreq, $selectedrecurrulefreq); + print $form->selectarray('recurrulefreq', $arrayrecurrulefreq, $selectedrecurrulefreq, 0, 0, 0, '', 0, 0, 0, '', 'marginrightonly'); // If recurrulefreq is MONTHLY - print '
    '; + print ''; // If recurrulefreq is WEEKLY - print '
    '; + print ''; print '' . "\n"; + // Code to enable drag and drop + $s.='jQuery( "div.sortable" ).sortable({connectWith: ".sortable", placeholder: "ui-state-highlight", items: "div.movable", receive: function( event, ui ) {'."\n"; + // Code to submit form + $s.='console.log("submit form to record new event");'."\n"; + //$s.='console.log(event.target);'; + $s.='var newval = jQuery(event.target).closest("div.dayevent").attr("id");'."\n"; + $s.='console.log("found parent div.dayevent with id = "+newval);'."\n"; + $s.='var frm=jQuery("#searchFormList");'."\n"; + $s.='var newurl = ui.item.find("a.cal_event").attr("href");'."\n"; + $s.='console.log(newurl);'."\n"; + $s.='frm.attr("action", newurl).children("#newdate").val(newval);frm.submit();}'."\n"; + $s.='});'."\n"; + } + $s.='});' . "\n"; + $s.='' . "\n"; // Local calendar $s.='
    ' . $langs->trans("LocalAgenda").'  
    '; @@ -698,7 +705,7 @@ if ($showbirthday) $event->type_code='BIRTHDAY'; $event->libelle=$langs->trans("Birthday").' '.dolGetFirstLastname($obj->firstname,$obj->lastname); $event->percentage=100; - $event->fulldayevent=true; + $event->fulldayevent=1; $event->date_start_in_calendar=$event->datep; $event->date_end_in_calendar=$event->datef; @@ -871,7 +878,7 @@ if (count($listofextcals)) $dateend=dol_stringtotime($icalevent['DTEND;VALUE=DATE'],1)-1; // We remove one second to get last second of day //print 'x'.$datestart.'-'.$dateend;exit; //print dol_print_date($dateend,'dayhour','gmt'); - $event->fulldayevent=true; + $event->fulldayevent=1; $addevent=true; } elseif (!is_array($icalevent['DTSTART'])) // not fullday event (DTSTART is not array. It is a value like '19700101T000000Z' for 00:00 in greenwitch) @@ -1022,8 +1029,11 @@ if (empty($action) || $action == 'show_month') // View by month $newparam=preg_replace('/viewcal=[0-9]+&?/i','',$newparam); $newparam=preg_replace('/showbirthday_=/i','showbirthday=',$newparam); // Restore correct parameter $newparam.='&viewcal=1'; - echo '
    '.$langs->trans("ActionOnCompany").''; - if (GETPOST('socid','int') > 0) + if ($conf->societe->enabled) { - $societe = new Societe($db); - $societe->fetch(GETPOST('socid','int')); - print $societe->getNomUrl(1); - print ''; - } - else - { - $events=array(); - $events[]=array('method' => 'getContacts', 'url' => dol_buildpath('/core/ajax/contacts.php?showempty=1',1), 'htmlname' => 'contactid', 'params' => array('add-customer-contact' => 'disabled')); - //For external user force the company to user company - if (!empty($user->societe_id)) { - print $form->select_company($user->societe_id, 'socid', '', 1, 1, 0, $events, 0, 'minwidth300'); - } else { - print $form->select_company('', 'socid', '', 'SelectThirdParty', 1, 0, $events, 0, 'minwidth300'); + // Related company + print '
    '.$langs->trans("ActionOnCompany").''; + if (GETPOST('socid','int') > 0) + { + $societe = new Societe($db); + $societe->fetch(GETPOST('socid','int')); + print $societe->getNomUrl(1); + print ''; } + else + { + $events=array(); + $events[]=array('method' => 'getContacts', 'url' => dol_buildpath('/core/ajax/contacts.php?showempty=1',1), 'htmlname' => 'contactid', 'params' => array('add-customer-contact' => 'disabled')); + //For external user force the company to user company + if (!empty($user->societe_id)) { + print $form->select_company($user->societe_id, 'socid', '', 1, 1, 0, $events, 0, 'minwidth300'); + } else { + print $form->select_company('', 'socid', '', 'SelectThirdParty', 1, 0, $events, 0, 'minwidth300'); + } + } + print '
    '.$langs->trans("ActionOnContact").''; + $preselectedids=GETPOST('socpeopleassigned', 'array'); + if (GETPOST('contactid','int')) $preselectedids[GETPOST('contactid','int')]=GETPOST('contactid','int'); + print $form->selectcontacts(GETPOST('socid','int'), $preselectedids, 'socpeopleassigned[]', 1, '', '', 0, 'quatrevingtpercent', false, 0, array(), false, 'multiple', 'contactid'); + print '
    '.$langs->trans("ActionOnContact").''; - print $form->selectcontacts(GETPOST('socid','int'), GETPOST('contactid'), 'contactid', 1, '', '', 0, 'minwidth300'); - print '
    '.$langs->trans("Project").''; + print '
    '.$langs->trans("Project").''; - $numproject=$formproject->select_projects((! empty($societe->id)?$societe->id:-1),GETPOST("projectid")?GETPOST("projectid"):'','projectid'); - if ($numproject==0) - { - print '   '.$langs->trans("AddProject").''; - } + $numproject=$formproject->select_projects((! empty($societe->id)?$societe->id:-1), GETPOST("projectid")?GETPOST("projectid"):'', 'projectid', 0, 0, 1, 1); + print '   '.$langs->trans("AddProject").''; print '
    '.$langs->trans("LinkedObject").'
    '.$langs->trans("LinkedObject").''.dolGetElementUrl($originid,$origin,1).'
    '.$langs->trans("Priority").''; + print '
    '.$langs->trans("Priority").''; print ''; print '
    '.$langs->trans("Description").''; require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('note',(GETPOST('note','none')?GETPOST('note','none'):$object->note),'',180,'dolibarr_notes','In',true,true,$conf->fckeditor->enabled,ROWS_5,'90%'); + $doleditor=new DolEditor('note',(GETPOST('note','none')?GETPOST('note','none'):$object->note),'',180,'dolibarr_notes','In',true,true,$conf->fckeditor->enabled,ROWS_4,'90%'); $doleditor->Create(); print '
    '.$langs->trans("EventOnFullDay").'fulldayevent?' checked':'').'>
    '; - echo ' '; + + + print '
    '; + print '
    '; + print ' '; $i=0; while ($i < 7) { @@ -1087,13 +1097,12 @@ if (empty($action) || $action == 'show_month') // View by month } echo " \n"; } - echo "
    \n"; - echo ''; - echo ''; - echo ''; - echo '' ; - echo ''; + print "
    \n"; + print ''; + print ''; + print ''; + print '' ; } elseif ($action == 'show_week') // View by week { @@ -1107,8 +1116,10 @@ elseif ($action == 'show_week') // View by week $newparam=preg_replace('/viewweek=[0-9]+&?/i','',$newparam); $newparam=preg_replace('/showbirthday_=/i','showbirthday=',$newparam); // Restore correct parameter $newparam.='&viewweek=1'; - echo ''; - echo ' '; + + print '
    '; + print '
    '; + print ' '; $i=0; while ($i < 7) { @@ -1141,12 +1152,12 @@ elseif ($action == 'show_week') // View by week } echo " \n"; - echo "
    \n"; - echo '
    '; + print "
    \n"; + print ''; + + echo ''; echo ''; - echo ''; echo '' ; - echo ''; } else // View by day { @@ -1164,6 +1175,8 @@ else // View by day $timestamp=dol_mktime(12,0,0,$month,$day,$year); $arraytimestamp=dol_getdate($timestamp); + + print '
    '; // You can use div-table-responsive-no-min if you dont need reserved height for your table echo ''; echo ' '; echo ' \n"; @@ -1175,8 +1188,11 @@ else // View by day echo "\n"; echo " \n"; echo '
    '.$langs->trans("Day".$arraytimestamp['wday'])."
    '; + print '
    '; } +print "\n".''; + llxFooter(); $db->close(); @@ -1240,11 +1256,12 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa print '
    '; //$curtime = dol_mktime (0, 0, 0, $month, $day, $year); - $i=0; $nummytasks=0; $numother=0; $numbirthday=0; $numical=0; $numicals=array(); + $i=0; $numother=0; $numbirthday=0; $numical=0; $numicals=array(); $ymd=sprintf("%04d",$year).sprintf("%02d",$month).sprintf("%02d",$day); - $nextindextouse=count($colorindexused); // At first run this is 0, so fist user has 0, next 1, ... - //print $nextindextouse; + $colorindexused[$user->id] = 0; // Color index for current user (user->id) is always 0 + $nextindextouse=count($colorindexused); // At first run this is 0, so first user has 0, next 1, ... + //var_dump($colorindexused); foreach ($eventarray as $daykey => $notused) { @@ -1258,25 +1275,24 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa if ($i < $maxprint || $maxprint == 0 || ! empty($conf->global->MAIN_JS_SWITCH_AGENDA)) { $keysofuserassigned=array_keys($event->userassigned); - $ponct=($event->date_start_in_calendar == $event->date_end_in_calendar); // Define $color (Hex string like '0088FF') and $cssclass of event - $color=-1; $colorindex=-1; + $color=-1; $cssclass=''; $colorindex=-1; if (in_array($user->id, $keysofuserassigned)) { - $nummytasks++; $cssclass='family_mytasks'; + $cssclass='family_mytasks'; - if (empty($cacheusers[$event->userownerid])) - { - $newuser=new User($db); - $newuser->fetch($event->userownerid); - $cacheusers[$event->userownerid]=$newuser; - } - //var_dump($cacheusers[$event->userownerid]->color); + if (empty($cacheusers[$event->userownerid])) + { + $newuser=new User($db); + $newuser->fetch($event->userownerid); + $cacheusers[$event->userownerid]=$newuser; + } + //var_dump($cacheusers[$event->userownerid]->color); - // We decide to choose color of owner of event (event->userownerid is user id of owner, event->userassigned contains all users assigned to event) - if (! empty($cacheusers[$event->userownerid]->color)) $color=$cacheusers[$event->userownerid]->color; + // We decide to choose color of owner of event (event->userownerid is user id of owner, event->userassigned contains all users assigned to event) + if (! empty($cacheusers[$event->userownerid]->color)) $color=$cacheusers[$event->userownerid]->color; } else if ($event->type_code == 'ICALEVENT') // Event come from external ical file { @@ -1287,6 +1303,7 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa } $numicals[dol_string_nospecial($event->icalname)]++; } + $color=($event->icalcolor?$event->icalcolor:-1); $cssclass=(! empty($event->icalname)?'family_ext'.md5($event->icalname):'family_other'); } @@ -1311,7 +1328,8 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa // We decide to choose color of owner of event (event->userownerid is user id of owner, event->userassigned contains all users assigned to event) if (! empty($cacheusers[$event->userownerid]->color)) $color=$cacheusers[$event->userownerid]->color; } - if ($color == -1) // Color was not forced. Set color according to color index. + + if ($color < 0) // Color was not set on user card. Set color according to color index. { // Define color index if not yet defined $idusertouse=($event->userownerid?$event->userownerid:0); @@ -1321,8 +1339,8 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa } else { - $colorindex=$nextindextouse; - $colorindexused[$idusertouse]=$colorindex; + $colorindex=$nextindextouse; + $colorindexused[$idusertouse]=$colorindex; if (! empty($theme_datacolor[$nextindextouse+1])) $nextindextouse++; // Prepare to use next color } //print '|'.($color).'='.($idusertouse?$idusertouse:0).'='.$colorindex.'
    '; @@ -1358,7 +1376,6 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa }else{ $cssclass.= " unmovable"; } - } $h=''; $nowrapontd=1; @@ -1373,9 +1390,18 @@ function show_day_events($db, $day, $month, $year, $monthshown, $style, &$eventa //print ' position: absolute; top: 40px; width: 50%;'; //print '"'; print '>'; - print 'transparency)?' cal_event_notbusy':' cal_event_busy').'" style="'.$h; + if (empty($event->transparency) && empty($conf->global->AGENDA_NO_TRANSPARENT_ON_NOT_BUSY)) + { + print 'border: 2px solid #'.$color.';'; + } + else + { + print 'background: #'.$color.';'; + print 'background: -webkit-gradient(linear, left top, left bottom, from(#'.dol_color_minus($color, -3).'), to(#'.dol_color_minus($color, -1).'));'; + } //if (! empty($event->transparency)) print 'background: #'.$color.'; background: -webkit-gradient(linear, left top, left bottom, from(#'.$color.'), to(#'.dol_color_minus($color,1).'));'; //else print 'background-color: transparent !important; background: none; border: 1px solid #bbb;'; //print ' -moz-border-radius:4px;"'; diff --git a/htdocs/comm/action/listactions.php b/htdocs/comm/action/list.php similarity index 79% rename from htdocs/comm/action/listactions.php rename to htdocs/comm/action/list.php index 8faeb365cb6..b34c5d0e0b7 100644 --- a/htdocs/comm/action/listactions.php +++ b/htdocs/comm/action/list.php @@ -20,7 +20,7 @@ */ /** - * \file htdocs/comm/action/listactions.php + * \file htdocs/comm/action/list.php * \ingroup agenda * \brief Page to list actions */ @@ -121,8 +121,8 @@ $hookmanager->initHooks(array('agendalist')); $arrayfields=array( 'a.id'=>array('label'=>"Ref", 'checked'=>1), 'owner'=>array('label'=>"Owner", 'checked'=>1), - 'a.label'=>array('label'=>"Title", 'checked'=>1), 'c.libelle'=>array('label'=>"Type", 'checked'=>1), + 'a.label'=>array('label'=>"Title", 'checked'=>1), 'a.datep'=>array('label'=>"DateStart", 'checked'=>1), 'a.datep2'=>array('label'=>"DateEnd", 'checked'=>1), 's.nom'=>array('label'=>"ThirdParty", 'checked'=>1), @@ -168,10 +168,11 @@ include DOL_DOCUMENT_ROOT.'/core/actions_changeselectedfields.inc.php'; // Purge search criteria if (GETPOST('button_removefilter_x','alpha') || GETPOST('button_removefilter.x','alpha') || GETPOST('button_removefilter','alpha')) // All tests are required to be compatible with all browsers { - $actioncode=''; + //$actioncode=''; $search_title=''; $datestart=''; $dateend=''; + $status=''; $search_array_options=array(); } @@ -222,12 +223,7 @@ if (GETPOST('dateendday','int')) $param.='&dateendday='.GETPOST('dateendday','in if (GETPOST('dateendmonth','int')) $param.='&dateendmonth='.GETPOST('dateendmonth','int'); if (GETPOST('dateendyear','int')) $param.='&dateendyear='.GETPOST('dateendyear','int'); // Add $param from extra fields -foreach ($search_array_options as $key => $val) -{ - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); -} +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; $sql = "SELECT"; if ($usergroup > 0) $sql.=" DISTINCT"; @@ -311,19 +307,8 @@ if ($dateselect > 0) $sql.= " AND ((a.datep2 >= '".$db->idate($dateselect)."' AN if ($datestart > 0) $sql.= " AND a.datep BETWEEN '".$db->idate($datestart)."' AND '".$db->idate($datestart+3600*24-1)."'"; if ($dateend > 0) $sql.= " AND a.datep2 BETWEEN '".$db->idate($dateend)."' AND '".$db->idate($dateend+3600*24-1)."'"; // Add where from extra fields -foreach ($search_array_options as $key => $val) -{ - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $typ=$extrafields->attribute_type[$tmpkey]; - $mode_search=0; - if (in_array($typ, array('int','double','real'))) $mode_search=1; // Search on a numeric - if (in_array($typ, array('sellist','link')) && $crit != '0' && $crit != '-1') $mode_search=2; // Search on a foreign key int - if ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0') && (! in_array($typ, array('link')) || $crit != '-1')) - { - $sql .= natural_search('ef.'.$tmpkey, $crit, $mode_search); - } -} +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; + $sql.= $db->order($sortfield,$sortorder); $nbtotalofrecords = ''; @@ -336,7 +321,7 @@ if (empty($conf->global->MAIN_DISABLE_FULL_SCANLIST)) $sql.= $db->plimit($limit + 1, $offset); //print $sql; -dol_syslog("comm/action/listactions.php", LOG_DEBUG); +dol_syslog("comm/action/list.php", LOG_DEBUG); $resql=$db->query($sql); if ($resql) { @@ -357,6 +342,28 @@ if ($resql) $head = calendars_prepare_head($param); + print ''."\n"; + + if ($optioncss != '') print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + print ''; + $nav=''; + if ($optioncss != '') $nav.= ''; + //if ($actioncode) $nav.=''; + if ($resourceid) $nav.=''; + if ($filter) $nav.=''; + if ($filtert) $nav.=''; + if ($socid) $nav.=''; + if ($showbirthday) $nav.=''; + if ($pid) $nav.=''; + if ($usergroup) $nav.=''; + print $nav; + dol_fiche_head($head, $tabactive, $langs->trans('Agenda'), 0, 'action'); print_actions_filter($form,$canedit,$status,$year,$month,$day,$showbirthday,0,$filtert,0,$pid,$socid,$action,-1,$actioncode,$usergroup,'',$resourceid); dol_fiche_end(); @@ -392,28 +399,6 @@ if ($resql) $s = $hookmanager->resPrint; } - - print ''."\n"; - if ($optioncss != '') print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - print ''; - $nav=''; - if ($optioncss != '') $nav.= ''; - if ($actioncode) $nav.=''; - if ($resourceid) $nav.=''; - if ($filter) $nav.=''; - if ($filtert) $nav.=''; - if ($socid) $nav.=''; - if ($showbirthday) $nav.=''; - if ($pid) $nav.=''; - if ($usergroup) $nav.=''; - print $nav; - if ($user->rights->agenda->myactions->create || $user->rights->agenda->allactions->create) { $tmpforcreatebutton=dol_getdate(dol_now(), true); @@ -427,7 +412,7 @@ if ($resql) $link.= ''; } - print_barre_liste($s, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $link, $num, -1 * $nbtotalofrecords, '', 0, $nav, '', $limit); + print_barre_liste($s, $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, '', $num, -1 * $nbtotalofrecords, '', 0, $nav.$link, '', $limit); $moreforfilter=''; @@ -456,34 +441,10 @@ if ($resql) if (! empty($arrayfields['s.nom']['checked'])) print ''; if (! empty($arrayfields['a.fk_contact']['checked'])) print ''; if (! empty($arrayfields['a.fk_element']['checked'])) print ''; + // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $typeofextrafield=$extrafields->attribute_type[$key]; - print ''; - } - } - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; + // Fields from hook $parameters=array('arrayfields'=>$arrayfields); $reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook @@ -503,31 +464,20 @@ if ($resql) print "\n"; print ''; - if (! empty($arrayfields['a.id']['checked'])) print_liste_field_titre($arrayfields['a.id']['label'] , $_SERVER["PHP_SELF"],"a.id",$param,"","",$sortfield,$sortorder); - if (! empty($arrayfields['owner']['checked'])) print_liste_field_titre($arrayfields['owner']['label'] , $_SERVER["PHP_SELF"],"",$param,"","",$sortfield,$sortorder); - if (! empty($arrayfields['c.libelle']['checked'])) print_liste_field_titre($arrayfields['c.libelle']['label'] , $_SERVER["PHP_SELF"],"c.libelle",$param,"","",$sortfield,$sortorder); - if (! empty($arrayfields['a.label']['checked'])) print_liste_field_titre($arrayfields['a.label']['label'] , $_SERVER["PHP_SELF"],"a.label",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['a.id']['checked'])) print_liste_field_titre($arrayfields['a.id']['label'], $_SERVER["PHP_SELF"],"a.id",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['owner']['checked'])) print_liste_field_titre($arrayfields['owner']['label'], $_SERVER["PHP_SELF"],"",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['c.libelle']['checked'])) print_liste_field_titre($arrayfields['c.libelle']['label'], $_SERVER["PHP_SELF"],"c.libelle",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['a.label']['checked'])) print_liste_field_titre($arrayfields['a.label']['label'], $_SERVER["PHP_SELF"],"a.label",$param,"","",$sortfield,$sortorder); //if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) - if (! empty($arrayfields['a.datep']['checked'])) print_liste_field_titre($arrayfields['a.datep']['label'] , $_SERVER["PHP_SELF"],"a.datep",$param,'','align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['a.datep2']['checked'])) print_liste_field_titre($arrayfields['a.datep2']['label'] , $_SERVER["PHP_SELF"],"a.datep2",$param,'','align="center"',$sortfield,$sortorder); - if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'] , $_SERVER["PHP_SELF"],"s.nom",$param,"","",$sortfield,$sortorder); + if (! empty($arrayfields['a.datep']['checked'])) print_liste_field_titre($arrayfields['a.datep']['label'], $_SERVER["PHP_SELF"],"a.datep",$param,'','align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['a.datep2']['checked'])) print_liste_field_titre($arrayfields['a.datep2']['label'], $_SERVER["PHP_SELF"],"a.datep2",$param,'','align="center"',$sortfield,$sortorder); + if (! empty($arrayfields['s.nom']['checked'])) print_liste_field_titre($arrayfields['s.nom']['label'], $_SERVER["PHP_SELF"],"s.nom",$param,"","",$sortfield,$sortorder); if (! empty($arrayfields['a.fk_contact']['checked'])) print_liste_field_titre($arrayfields['a.fk_contact']['label'], $_SERVER["PHP_SELF"],"a.fk_contact",$param,"","",$sortfield,$sortorder); if (! empty($arrayfields['a.fk_element']['checked'])) print_liste_field_titre($arrayfields['a.fk_element']['label'], $_SERVER["PHP_SELF"],"a.fk_element",$param,"","",$sortfield,$sortorder); // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $sortonfield = "ef.".$key; - if (! empty($extrafields->attribute_computed[$key])) $sortonfield=''; - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],$sortonfield,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; + // Hook fields $parameters=array('arrayfields'=>$arrayfields,'param'=>$param,'sortfield'=>$sortfield,'sortorder'=>$sortorder); $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook @@ -542,7 +492,7 @@ if ($resql) require_once DOL_DOCUMENT_ROOT.'/comm/action/class/cactioncomm.class.php'; $caction=new CActionComm($db); - $arraylist=$caction->liste_array(1, 'code', '', (empty($conf->global->AGENDA_USE_EVENT_TYPE)?1:0)); + $arraylist=$caction->liste_array(1, 'code', '', (empty($conf->global->AGENDA_USE_EVENT_TYPE)?1:0), '', 1); $var=true; while ($i < min($num,$limit)) @@ -575,7 +525,7 @@ if ($resql) // User owner if (! empty($arrayfields['owner']['checked'])) { - print ''; } - if (! empty($arrayfields['c.libelle']['checked'])) { - // Type + + // Type + if (! empty($arrayfields['c.libelle']['checked'])) + { print ''; } + + // Label if (! empty($arrayfields['a.label']['checked'])) { - // Label print ''; } + // Start date if (! empty($arrayfields['a.datep']['checked'])) { - // Start date print ''; } + + // End date if (! empty($arrayfields['a.datep2']['checked'])) { - // End date print ''; } + + // Third party if (! empty($arrayfields['s.nom']['checked'])) { - // Third party print ''; } + + // Contact if (! empty($arrayfields['a.fk_contact']['checked'])) { - // Contact print ''; } + + // Linked object if (! empty($arrayfields['a.fk_element']['checked'])) { - // Linked object print ''; } + // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - print 'getAlignFlag($key); - if ($align) print ' align="'.$align.'"'; - print '>'; - $tmpkey='options_'.$key; - print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1); - print ''; - if (! $i) $totalarray['nbfield']++; - } - } - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); $reshook=$hookmanager->executeHooks('printFieldListValue',$parameters); // Note that $action and $object may have been modified by hook diff --git a/htdocs/comm/action/pertype.php b/htdocs/comm/action/pertype.php index b10ab8dc05b..cc3688a4793 100644 --- a/htdocs/comm/action/pertype.php +++ b/htdocs/comm/action/pertype.php @@ -724,7 +724,7 @@ jQuery(document).ready(function() { else if (ids.indexOf(",") > -1) /* There is several events */ { /* alert(\'several events\'); */ - url = "'.DOL_URL_ROOT.'/comm/action/listactions.php?filtert="+userid+"&dateselectyear="+year+"&dateselectmonth="+month+"&dateselectday="+day; + url = "'.DOL_URL_ROOT.'/comm/action/list.php?filtert="+userid+"&dateselectyear="+year+"&dateselectmonth="+month+"&dateselectday="+day; window.location.href = url; } else /* One event */ @@ -772,7 +772,7 @@ function show_day_events_pertype($username, $day, $month, $year, $monthshown, $s global $user, $conf, $langs, $hookmanager, $action; global $filter, $filtert, $status, $actioncode; // Filters used into search form global $theme_datacolor; // Array with a list of different we can use (come from theme) - global $cachethirdparties, $cachecontacts, $colorindexused; + global $cachethirdparties, $cachecontacts, $cacheprojects, $colorindexused; global $begin_h, $end_h; $cases1 = array(); // Color first half hour @@ -894,33 +894,33 @@ function show_day_events_pertype($username, $day, $month, $year, $monthshown, $s $cases1[$h][$event->id]['color']=$color; if ($event->fk_project > 0) { - if (empty($cache_project[$event->fk_project])) + if (empty($cacheprojects[$event->fk_project])) { $tmpproj=new Project($db); $tmpproj->fetch($event->fk_project); - $cache_project[$event->fk_project]=$tmpproj; + $cacheprojects[$event->fk_project]=$tmpproj; } - $cases1[$h][$event->id]['string'].=', '.$langs->trans("Project").': '.$cache_project[$event->fk_project]->ref.' - '.$cache_project[$event->fk_project]->title; + $cases1[$h][$event->id]['string'].=', '.$langs->trans("Project").': '.$cacheprojects[$event->fk_project]->ref.' - '.$cacheprojects[$event->fk_project]->title; } if ($event->socid > 0) { - if (empty($cache_thirdparty[$event->socid])) + if (empty($cachethirdparties[$event->socid])) { $tmpthirdparty=new Societe($db); $tmpthirdparty->fetch($event->socid); - $cache_thirdparty[$event->socid]=$tmpthirdparty; + $cachethirdparties[$event->socid]=$tmpthirdparty; } - $cases1[$h][$event->id]['string'].=', '.$cache_thirdparty[$event->socid]->name; + $cases1[$h][$event->id]['string'].=', '.$cachethirdparties[$event->socid]->name; } if ($event->contactid > 0) { - if (empty($cache_contact[$event->contactid])) + if (empty($cachecontacts[$event->contactid])) { $tmpcontact=new Contact($db); $tmpcontact->fetch($event->contactid); - $cache_contact[$event->contactid]=$tmpcontact; + $cachecontacts[$event->contactid]=$tmpcontact; } - $cases1[$h][$event->id]['string'].=', '.$cache_contact[$event->contactid]->getFullName($langs); + $cases1[$h][$event->id]['string'].=', '.$cachecontacts[$event->contactid]->getFullName($langs); } } if ($event->date_start_in_calendar < $c && $dateendtouse > $b) @@ -940,33 +940,33 @@ function show_day_events_pertype($username, $day, $month, $year, $monthshown, $s $cases2[$h][$event->id]['color']=$color; if ($event->fk_project > 0) { - if (empty($cache_project[$event->fk_project])) + if (empty($cacheprojects[$event->fk_project])) { $tmpproj=new Project($db); $tmpproj->fetch($event->fk_project); - $cache_project[$event->fk_project]=$tmpproj; + $cacheprojects[$event->fk_project]=$tmpproj; } - $cases2[$h][$event->id]['string'].=', '.$langs->trans("Project").': '.$cache_project[$event->fk_project]->ref.' - '.$cache_project[$event->fk_project]->title; + $cases2[$h][$event->id]['string'].=', '.$langs->trans("Project").': '.$cacheprojects[$event->fk_project]->ref.' - '.$cacheprojects[$event->fk_project]->title; } if ($event->socid > 0) { - if (empty($cache_thirdparty[$event->socid])) + if (empty($cachethirdparties[$event->socid])) { $tmpthirdparty=new Societe($db); $tmpthirdparty->fetch($event->socid); - $cache_thirdparty[$event->socid]=$tmpthirdparty; + $cachethirdparties[$event->socid]=$tmpthirdparty; } - $cases2[$h][$event->id]['string'].=', '.$cache_thirdparty[$event->socid]->name; + $cases2[$h][$event->id]['string'].=', '.$cachethirdparties[$event->socid]->name; } if ($event->contactid > 0) { - if (empty($cache_contact[$event->contactid])) + if (empty($cachecontacts[$event->contactid])) { $tmpcontact=new Contact($db); $tmpcontact->fetch($event->contactid); - $cache_contact[$event->contactid]=$tmpcontact; + $cachecontacts[$event->contactid]=$tmpcontact; } - $cases2[$h][$event->id]['string'].=', '.$cache_contact[$event->contactid]->getFullName($langs); + $cases2[$h][$event->id]['string'].=', '.$cachecontacts[$event->contactid]->getFullName($langs); } } } diff --git a/htdocs/comm/action/peruser.php b/htdocs/comm/action/peruser.php index 05eba093cfd..a4154f5a9e4 100644 --- a/htdocs/comm/action/peruser.php +++ b/htdocs/comm/action/peruser.php @@ -218,8 +218,13 @@ if ($showbirthday) $param.="&showbirthday=1"; if ($pid) $param.="&projectid=".$pid; if ($type) $param.="&type=".$type; if ($action == 'show_day' || $action == 'show_week' || $action == 'show_month' || $action != 'show_peruser') $param.='&action='.$action; +if ($begin_h != '') $param.='&begin_h='.$begin_h; +if ($end_h != '') $param.='&end_h='.$end_h; +if ($begin_d != '') $param.='&begin_d='.$begin_d; +if ($end_d != '') $param.='&end_d='.$end_d; $param.="&maxprint=".$maxprint; + $prev = dol_get_first_day_week($day, $month, $year); //print "day=".$day." month=".$month." year=".$year; //var_dump($prev); exit; @@ -248,15 +253,15 @@ $lastdaytoshow=dol_time_plus_duree($firstdaytoshow, 7, 'd'); $max_day_in_month = date("t",dol_mktime(0,0,0,$month,1,$year)); $tmpday = $first_day; +$picto='calendarweek'; $nav ="trans("Previous"))."\">   \n"; $nav.=" ".dol_print_date(dol_mktime(0,0,0,$first_month,$first_day,$first_year),"%Y").", ".$langs->trans("Week")." ".$week; $nav.=" \n"; $nav.="   trans("Next"))."\">\n"; $nav.="   (".$langs->trans("Today").")"; -$picto='calendarweek'; -$nav.='   '; +/*$nav.='   '; $nav.=''; $nav.=''; $nav.=''; @@ -271,10 +276,10 @@ $nav.=''; $nav.=''; $nav.=''; $nav.=''; - +*/ $nav.=$form->select_date($dateselect, 'dateselect', 0, 0, 1, '', 1, 0, 1); $nav.=' '; -$nav.=''; +//$nav.=''; // Must be after the nav definition $param.='&year='.$year.'&month='.$month.($day?'&day='.$day:''); @@ -294,6 +299,8 @@ $paramnoaction=preg_replace('/action=[a-z_]+/','',$param); $head = calendars_prepare_head($paramnoaction); +print '
    '."\n"; + dol_fiche_head($head, $tabactive, $langs->trans('Agenda'), 0, 'action'); print_actions_filter($form, $canedit, $status, $year, $month, $day, $showbirthday, 0, $filtert, 0, $pid, $socid, $action, $listofextcals, $actioncode, $usergroup, '', $resourceid); dol_fiche_end(); @@ -581,6 +588,7 @@ else $maxnbofchar=18; $cachethirdparties=array(); $cachecontacts=array(); +$cacheusers=array(); // Define theme_datacolor array $color_file = DOL_DOCUMENT_ROOT."/theme/".$conf->theme."/graph-color.php"; @@ -602,11 +610,9 @@ $newparam=preg_replace('/viewweek=[0-9]+&?/i','',$newparam); $newparam=preg_replace('/showbirthday_=/i','showbirthday=',$newparam); // Restore correct parameter $newparam.='&viewweek=1'; -echo ''; +echo ''; echo ''; -echo ''; echo '' ; -echo ''; // Line header with list of days @@ -792,7 +798,7 @@ foreach ($usernames as $username) echo "
    '; - if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select')) && empty($extrafields->attribute_computed[$key])) - { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $searchclass=''; - if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; - if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; - print ''; - } - else - { - // for the type as 'checkbox', 'chkbxlst', 'sellist' we should use code instead of id (example: I declare a 'chkbxlst' to have a link with dictionnairy, I have to extend it with the 'code' instead 'rowid') - echo $extrafields->showInputField($key, $search_array_options['search_options_'.$key], '', '', 'search_'); - } - print '
    '; + print ''; // With edge and chrom the td overflow is not supported correctly when content is not full text. if ($obj->fk_user_action > 0) { $userstatic->fetch($obj->fk_user_action); @@ -584,17 +534,21 @@ if ($resql) else print ' '; print ''; if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) { if ($actionstatic->type_picto) print img_picto('', $actionstatic->type_picto); else { - if ($actionstatic->type_code == 'AC_RDV') print img_picto('', 'object_group').' '; - if ($actionstatic->type_code == 'AC_TEL') print img_picto('', 'object_phoning').' '; - if ($actionstatic->type_code == 'AC_FAX') print img_picto('', 'object_phoning_fax').' '; - if ($actionstatic->type_code == 'AC_EMAIL') print img_picto('', 'object_email').' '; + if ($actionstatic->type_code == 'AC_RDV') print img_picto('', 'object_group', '', false, 0, 0, '', 'paddingright').' '; + elseif ($actionstatic->type_code == 'AC_TEL') print img_picto('', 'object_phoning', '', false, 0, 0, '', 'paddingright').' '; + elseif ($actionstatic->type_code == 'AC_FAX') print img_picto('', 'object_phoning_fax', '', false, 0, 0, '', 'paddingright').' '; + elseif ($actionstatic->type_code == 'AC_EMAIL') print img_picto('', 'object_email', '', false, 0, 0, '', 'paddingright').' '; + elseif ($actionstatic->type_code == 'AC_INT') print img_picto('', 'object_intervention', '', false, 0, 0, '', 'paddingright').' '; + elseif (! preg_match('/_AUTO/', $actionstatic->type_code)) print img_picto('', 'object_action', '', false, 0, 0, '', 'paddingright').' '; } } $labeltype=$obj->type_code; @@ -603,15 +557,16 @@ if ($resql) print dol_trunc($labeltype,28); print ''; print $actionstatic->label; print ''; print dol_print_date($db->jdate($obj->dp),"dayhour"); $late=0; @@ -622,14 +577,16 @@ if ($resql) if ($late) print img_warning($langs->trans("Late")).' '; print ''; print dol_print_date($db->jdate($obj->dp2),"dayhour"); print ''; if ($obj->socid) { @@ -641,8 +598,9 @@ if ($resql) else print ' '; print ''; if ($obj->fk_contact > 0) { @@ -657,8 +615,9 @@ if ($resql) } print ''; if ($obj->fk_element > 0 && ! empty($obj->elementtype)) { include_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; @@ -669,24 +628,9 @@ if ($resql) print '
    \n"; echo '
    '; -if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) +if (! empty($conf->global->AGENDA_USE_EVENT_TYPE) && ! empty($conf->global->AGENDA_USE_COLOR_PER_EVENT_TYPE)) { $langs->load("commercial"); print '
    '.$langs->trans("Legend").':
    '; @@ -817,6 +823,9 @@ if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) */ } +print "\n".''; +print "\n"; + // Add js code to manage click on a box print ''."\n"; - } -//} + // Enable jquery handlers button to delete files + print 'jQuery(document).ready(function() {'."\n"; + print ' jQuery(".deletefilelink").click(function(e) { '."\n"; + print ' console.log("We click on button with class deletefilelink, param='.$param.', we set urlfile to "+jQuery(this).attr("rel"));'."\n"; + print ' jQuery("#urlfile").val(jQuery(this).attr("rel"));'."\n"; + //print ' jQuery("#section_dir").val(\'aaa\');'."\n"; + print ' jQuery("#dialog-confirm-deletefile").dialog("open");'."\n"; + print ' return false;'."\n"; + print ' });'."\n"; + print '});'."\n"; + print ''."\n"; +} // Close db if mode is not noajax if ((! isset($mode) || $mode != 'noajax') && is_object($db)) $db->close(); diff --git a/htdocs/core/ajax/ajaxdirtree.php b/htdocs/core/ajax/ajaxdirtree.php index ae2f349a644..796ced332ab 100644 --- a/htdocs/core/ajax/ajaxdirtree.php +++ b/htdocs/core/ajax/ajaxdirtree.php @@ -198,10 +198,13 @@ if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE print '
    '.img_view($langs->trans("Edit").' - '.$langs->trans("View"), 0, 'class="valignmiddle"').''.img_view($langs->trans("Edit").' - '.$langs->trans("View"), 0, 'class="valignmiddle"').''.img_edit_add().''.img_edit_add().' 
    '; - elseif ($notabs == 2) $s.='
    '; + elseif ($notabs == 2) $s.='
    '; // Define value if value is before if ($direction < 0) { $s.='<'.$tag.$paramfortooltipimg; @@ -497,9 +498,10 @@ class Form * @param int $noencodehtmltext Do not encode into html entity the htmltext * @param int $notabs 0=Include table and tr tags, 1=Do not include table and tr tags, 2=use div, 3=use span * @param string $tooltiptrigger ''=Tooltip on hover, 'abc'=Tooltip on click (abc is a unique key) + * @param int $forcenowrap Force no wrap between text and picto (works with notabs=2 only) * @return string HTML code of text, picto, tooltip */ - function textwithpicto($text, $htmltext, $direction = 1, $type = 'help', $extracss = '', $noencodehtmltext = 0, $notabs = 2, $tooltiptrigger='') + function textwithpicto($text, $htmltext, $direction = 1, $type = 'help', $extracss = '', $noencodehtmltext = 0, $notabs = 2, $tooltiptrigger='', $forcenowrap=0) { global $conf, $langs; @@ -534,7 +536,7 @@ class Form elseif ($type == 'warning') $img = img_warning($alt); else $img = img_picto($alt, $type); - return $this->textwithtooltip($text, $htmltext, (($tooltiptrigger && ! $img)?3:2), $direction, $img, $extracss, $notabs, '', $noencodehtmltext, $tooltiptrigger); + return $this->textwithtooltip($text, $htmltext, (($tooltiptrigger && ! $img)?3:2), $direction, $img, $extracss, $notabs, '', $noencodehtmltext, $tooltiptrigger, $forcenowrap); } /** @@ -569,26 +571,28 @@ class Form $ret.=$hookmanager->resPrint; $ret.=''; - // Warning: if you set submit button to disabled, post using 'Enter' will no more work. - $ret.=''; + // Warning: if you set submit button to disabled, post using 'Enter' will no more work if there is no another input submit. So we add a hidden button + $ret.=''; // Hidden button BEFORE so it is the one used when we submit with ENTER. + $ret.=''; $ret.='
    '; if (! empty($conf->use_javascript_ajax)) { $ret.=' @@ -763,7 +766,7 @@ class Form $out .= ''; } - $out.= ''; $out.= ''; $num = $this->db->num_rows($resql); $i = 0; @@ -1094,11 +1097,10 @@ class Form $resql=$this->db->query($sql); if ($resql) { - if ($conf->use_javascript_ajax && ! $forcecombo) + if (! $forcecombo) { include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; - $comboenhancement =ajax_combobox($htmlname, $events, $conf->global->COMPANY_USE_SEARCH_TO_SELECT); - $out.= $comboenhancement; + $out .= ajax_combobox($htmlname, $events, $conf->global->COMPANY_USE_SEARCH_TO_SELECT); } // Construct $out and $outarray @@ -1272,12 +1274,14 @@ class Form * @param int $forcecombo Force to use combo box * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) * @param bool $options_only Return options only (for ajax treatment) + * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container + * @param string $htmlid Html id to use instead of htmlname * @return int <0 if KO, Nb of contact in list if OK * @deprected You can use selectcontacts directly (warning order of param was changed) */ - function select_contacts($socid,$selected='',$htmlname='contactid',$showempty=0,$exclude='',$limitto='',$showfunction=0, $moreclass='', $showsoc=0, $forcecombo=0, $events=array(), $options_only=false) + function select_contacts($socid,$selected='',$htmlname='contactid',$showempty=0,$exclude='',$limitto='',$showfunction=0, $moreclass='', $showsoc=0, $forcecombo=0, $events=array(), $options_only=false, $moreparam='', $htmlid='') { - print $this->selectcontacts($socid,$selected,$htmlname,$showempty,$exclude,$limitto,$showfunction, $moreclass, $options_only, $showsoc, $forcecombo, $events); + print $this->selectcontacts($socid,$selected,$htmlname,$showempty,$exclude,$limitto,$showfunction, $moreclass, $options_only, $showsoc, $forcecombo, $events, $moreparam, $htmlid); return $this->num; } @@ -1285,27 +1289,30 @@ class Form * Return HTML code of the SELECT of list of all contacts (for a third party or all). * This also set the number of contacts found into $this->num * - * @param int $socid Id ot third party or 0 for all - * @param string $selected Id contact pre-selectionne - * @param string $htmlname Name of HTML field ('none' for a not editable field) - * @param int $showempty 0=no empty value, 1=add an empty value, 2=add line 'Internal' (used by user edit) - * @param string $exclude List of contacts id to exclude - * @param string $limitto Disable answers that are not id in this array list - * @param integer $showfunction Add function into label - * @param string $moreclass Add more class to class style - * @param bool $options_only Return options only (for ajax treatment) - * @param integer $showsoc Add company into label - * @param int $forcecombo Force to use combo box - * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) - * @return int <0 if KO, Nb of contact in list if OK + * @param int $socid Id ot third party or 0 for all + * @param array|int $selected Array of ID of pre-selected contact id + * @param string $htmlname Name of HTML field ('none' for a not editable field) + * @param int $showempty 0=no empty value, 1=add an empty value, 2=add line 'Internal' (used by user edit) + * @param string $exclude List of contacts id to exclude + * @param string $limitto Disable answers that are not id in this array list + * @param integer $showfunction Add function into label + * @param string $moreclass Add more class to class style + * @param bool $options_only Return options only (for ajax treatment) + * @param integer $showsoc Add company into label + * @param int $forcecombo Force to use combo box + * @param array $events Event options. Example: array(array('method'=>'getContacts', 'url'=>dol_buildpath('/core/ajax/contacts.php',1), 'htmlname'=>'contactid', 'params'=>array('add-customer-contact'=>'disabled'))) + * @param string $moreparam Add more parameters onto the select tag. For example 'style="width: 95%"' to avoid select2 component to go over parent container + * @param string $htmlid Html id to use instead of htmlname + * @return int <0 if KO, Nb of contact in list if OK */ - function selectcontacts($socid,$selected='',$htmlname='contactid',$showempty=0,$exclude='',$limitto='',$showfunction=0, $moreclass='', $options_only=false, $showsoc=0, $forcecombo=0, $events=array()) + function selectcontacts($socid, $selected='', $htmlname='contactid', $showempty=0, $exclude='', $limitto='', $showfunction=0, $moreclass='', $options_only=false, $showsoc=0, $forcecombo=0, $events=array(), $moreparam='', $htmlid='') { global $conf,$langs; $langs->load('companies'); - $out=''; + if (empty($htmlid)) $htmlid = $htmlname; + $out=''; // On recherche les societes $sql = "SELECT sp.rowid, sp.lastname, sp.statut, sp.firstname, sp.poste"; @@ -1326,11 +1333,10 @@ class Form if ($conf->use_javascript_ajax && ! $forcecombo && ! $options_only) { include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; - $comboenhancement = ajax_combobox($htmlname, $events, $conf->global->CONTACT_USE_SEARCH_TO_SELECT); - $out.= $comboenhancement; + $out .= ajax_combobox($htmlid, $events, $conf->global->CONTACT_USE_SEARCH_TO_SELECT); } - if ($htmlname != 'none' || $options_only) $out.= ''; if ($showempty == 1) $out.= ''; if ($showempty == 2) $out.= ''; $num = $this->db->num_rows($resql); @@ -1340,6 +1346,7 @@ class Form include_once DOL_DOCUMENT_ROOT.'/contact/class/contact.class.php'; $contactstatic=new Contact($this->db); + if (!is_array($selected)) $selected = array($selected); while ($i < $num) { $obj = $this->db->fetch_object($resql); @@ -1353,7 +1360,7 @@ class Form $disabled=0; if (is_array($exclude) && count($exclude) && in_array($obj->rowid,$exclude)) $disabled=1; if (is_array($limitto) && count($limitto) && ! in_array($obj->rowid,$limitto)) $disabled=1; - if ($selected && $selected == $obj->rowid) + if (!empty($selected) && in_array($obj->rowid, $selected)) { $out.= '
    '; + // Ref print ''; + // Onwer print ''; - print ''; + // Label print ''; + // Date print ''; + print ''; + + // File name print '\n"; + // Size print ''; + // Date print ''; // Preview @@ -1142,7 +1152,7 @@ class FormFile print ''; + print ''; //edit mode if ($action == 'update' && $selected === $link->id) { @@ -1673,7 +1680,7 @@ class FormFile * @param array $file File * @param string $modulepart propal, facture, facture_fourn, ... * @param string $relativepath Relative path of docs - * @param string $ruleforpicto Rule for picto: 0=Preview picto, 1=Use picto of mime type of file) + * @param string $ruleforpicto Rule for picto: 0=Use the generic preview picto, 1=Use the picto of mime type of file) * @param string $param More param on http links * @return string $out Output string with HTML */ diff --git a/htdocs/core/class/html.formmail.class.php b/htdocs/core/class/html.formmail.class.php index a9ebafc4769..6423d9709e9 100644 --- a/htdocs/core/class/html.formmail.class.php +++ b/htdocs/core/class/html.formmail.class.php @@ -325,6 +325,7 @@ class FormMail extends Form if ($this->withform == 1) { $out.= ''."\n"; + $out.= ''; $out.= ''; $out.= ''; @@ -401,7 +402,7 @@ class FormMail extends Form $out.= '
    '.$ref.''; if (! empty($action->userownerid)) { @@ -235,20 +240,27 @@ class FormActions print $userstatic->getNomUrl(-1, '', 0, 0, 16, 0, '', ''); } print ''; - if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) - { - if ($action->type_picto) print img_picto('', $action->type_picto); - else { - if ($action->type_code == 'AC_RDV') print img_picto('', 'object_group').' '; - if ($action->type_code == 'AC_TEL') print img_picto('', 'object_phoning').' '; - if ($action->type_code == 'AC_FAX') print img_picto('', 'object_phoning_fax').' '; - if ($action->type_code == 'AC_EMAIL') print img_picto('', 'object_email').' '; - } - } - print $action->type; + // Type + print ''; + $imgpicto=''; + if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) + { + if ($action->type_picto) $imgpicto=img_picto('', $action->type_picto); + else { + if ($action->type_code == 'AC_RDV') $imgpicto=img_picto('', 'object_group', '', false, 0, 0, '', 'paddingright').' '; + elseif ($action->type_code == 'AC_TEL') $imgpicto=img_picto('', 'object_phoning', '', false, 0, 0, '', 'paddingright').' '; + elseif ($action->type_code == 'AC_FAX') $imgpicto=img_picto('', 'object_phoning_fax', '', false, 0, 0, '', 'paddingright').' '; + elseif ($action->type_code == 'AC_EMAIL') $imgpicto=img_picto('', 'object_email', '', false, 0, 0, '', 'paddingright').' '; + elseif ($action->type_code == 'AC_INT') $imgpicto=img_picto('', 'object_intervention', '', false, 0, 0, '', 'paddingright').' '; + elseif (! preg_match('/_AUTO/', $action->type_code)) $imgpicto=img_picto('', 'object_action', '', false, 0, 0, '', 'paddingright').' '; + } + } + print $imgpicto; + print $action->type_short ? $action->type_short : $action->type; print ''.$label.''.dol_print_date($action->datep, 'dayhour', 'tzuserrel'); if ($action->datef) { diff --git a/htdocs/core/class/html.formbarcode.class.php b/htdocs/core/class/html.formbarcode.class.php index 2e93eaf9f5d..e1ee7ae04ff 100644 --- a/htdocs/core/class/html.formbarcode.class.php +++ b/htdocs/core/class/html.formbarcode.class.php @@ -148,6 +148,7 @@ class FormBarCode $i++; } print ""; + print ajax_combobox("select_".$htmlname); } else { dol_print_error($this->db); diff --git a/htdocs/core/class/html.formfile.class.php b/htdocs/core/class/html.formfile.class.php index ee49d15cfac..6e8b1cd6340 100644 --- a/htdocs/core/class/html.formfile.class.php +++ b/htdocs/core/class/html.formfile.class.php @@ -6,7 +6,7 @@ * Copyright (C) 2013 Cédric Salvador * Copyright (C) 2014 Marcos García * Copyright (C) 2015 Bahfir Abbes - * Copyright (C) 2016 Ferran Marcet + * Copyright (C) 2016-2017 Ferran Marcet * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -55,24 +55,25 @@ class FormFile /** - * Show form to upload a new file + * Show form to upload a new file. * * @param string $url Url * @param string $title Title zone (Title or '' or 'none') - * @param int $addcancel 1=Add 'Cancel' button - * @param int $sectionid If upload must be done inside a particular ECM section - * @param int $perm Value of permission to allow upload - * @param int $size Length of input file area. Deprecated. + * @param int $addcancel 1=Add 'Cancel' button + * @param int $sectionid If upload must be done inside a particular ECM section (is sectionid defined, sectiondir must not be) + * @param int $perm Value of permission to allow upload + * @param int $size Length of input file area. Deprecated. * @param Object $object Object to use (when attachment is done on an element) * @param string $options Add an option column - * @param integer $useajax Use fileupload ajax (0=never, 1=if enabled, 2=always whatever is option). 2 should never be used. + * @param integer $useajax Use fileupload ajax (0=never, 1=if enabled, 2=always whatever is option). @deprecated 2 should never be used and if 1 is used, option should no be enabled. * @param string $savingdocmask Mask to use to define output filename. For example 'XXXXX-__YYYYMMDD__-__file__' * @param integer $linkfiles 1=Also add form to link files, 0=Do not show form to link files * @param string $htmlname Name and id of HTML form ('formuserfile' by default, 'formuserfileecm' when used to upload a file in ECM) * @param string $accept Specifies the types of files accepted (This is not a security check but an user interface facility. eg '.pdf,image/*' or '.png,.jpg' or 'video/*') - * @return int <0 if KO, >0 if OK + * @param string $sectiondir If upload must be done inside a particular directory (is sectiondir defined, sectionid must not be) + * @return int <0 if KO, >0 if OK */ - function form_attach_new_file($url, $title='', $addcancel=0, $sectionid=0, $perm=1, $size=50, $object='', $options='', $useajax=1, $savingdocmask='', $linkfiles=1, $htmlname='formuserfile', $accept='') + function form_attach_new_file($url, $title='', $addcancel=0, $sectionid=0, $perm=1, $size=50, $object='', $options='', $useajax=1, $savingdocmask='', $linkfiles=1, $htmlname='formuserfile', $accept='', $sectiondir='') { global $conf,$langs, $hookmanager; $hookmanager->initHooks(array('formfile')); @@ -103,7 +104,7 @@ class FormFile if ($title != 'none') $out.=load_fiche_titre($title, null, null); $out .= '
    '; - $out .= ''; + $out .= ''; $out .= ''; $out .= ''; @@ -957,10 +958,10 @@ class FormFile if ($object->element == 'invoice_supplier') $relativepath=get_exdir($object->id,2,0,0,$object,'invoice_supplier').$relativepath; // TODO Call using a defined value for $relativepath if ($object->element == 'project_task') $relativepath='Call_not_supported_._Call_function_using_a_defined_relative_path_.'; } - // For backward compatiblity, we detect file is stored into an old path - if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO) && $file['level1name'] == 'photos') + // For backward compatiblity, we detect file stored into an old path + if (! empty($conf->global->PRODUCT_USE_OLD_PATH_FOR_PHOTO) && $filearray[0]['level1name'] == 'photos') { - $relativepath=preg_replace('/^.*\/produit\//','',$file['path']).'/'; + $relativepath=preg_replace('/^.*\/produit\//','',$filearray[0]['path']).'/'; } // Defined relative dir to DOL_DATA_ROOT $relativedir = ''; @@ -1067,7 +1068,7 @@ class FormFile $nboffiles=count($filearray); if ($nboffiles > 0) include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; - $var=true; $i=0; $nboflines = 0; $lastrowid=0; + $i=0; $nboflines = 0; $lastrowid=0; foreach($filearray as $key => $file) // filearray must be only files here { if ($file['name'] != '.' @@ -1082,7 +1083,9 @@ class FormFile print ''."\n"; // Do we have entry into database ? print ''."\n"; - print '
    '; // Show file name with link to download @@ -1095,9 +1098,11 @@ class FormFile print img_mime($file['name'], $file['name'].' ('.dol_print_size($file['size'],0,0).')', 'inline-block valignbottom paddingright'); if ($showrelpart == 1) print $relativepath; //print dol_trunc($file['name'],$maxlength,'middle'); - if (GETPOST('action','aZ09') == 'editfile' && $file['name'] == basename(GETPOST('urlfile'))) + if (GETPOST('action','aZ09') == 'editfile' && $file['name'] == basename(GETPOST('urlfile','alpha'))) { print ''; + $section_dir=dirname(GETPOST('urlfile','alpha')); + print ''; print ''; print ''; $editline=1; @@ -1107,12 +1112,17 @@ class FormFile print $file['name']; print ''; } + // Preview link if (! $editline) print $this->showPreview($file, $modulepart, $filepath); + // Public share link + if (! $editline && ! empty($filearray[$key]['hashp'])) print 'ee'; print "'.dol_print_size($file['size'],1,1).''.dol_print_date($file['date'],"dayhour","tzuser").''; if ($useinecm == 1) { - print ''.img_view('default', 0, 'class="paddingrightonly"').''; + print ''.img_view('default', 0, 'class="paddingrightonly"').''; } if (! $useinecm || $useinecm == 2) { @@ -1260,7 +1270,7 @@ class FormFile * @param int $addfilterfields Add line with filters * @return int <0 if KO, nb of files shown if OK */ - function list_of_autoecmfiles($upload_dir,$filearray,$modulepart,$param,$forcedownload=0,$relativepath='',$permtodelete=1,$useinecm=0,$textifempty='',$maxlength=0,$url='',$addfilterfields=0) + function list_of_autoecmfiles($upload_dir, $filearray, $modulepart, $param, $forcedownload=0, $relativepath='', $permtodelete=1, $useinecm=0, $textifempty='', $maxlength=0, $url='', $addfilterfields=0) { global $user, $conf, $langs, $form; global $bc; @@ -1379,7 +1389,6 @@ class FormFile $object_instance=new ExpenseReport($this->db); } - $var=true; foreach($filearray as $key => $file) { if (!is_dir($file['name']) @@ -1607,11 +1616,9 @@ class FormFile $nboflinks = count($links); if ($nboflinks > 0) include_once DOL_DOCUMENT_ROOT.'/core/lib/images.lib.php'; - $var = true; foreach ($links as $link) { - $var =! $var; - print '
    '."\n"; // Substitution array - if (! empty($this->withsubstit)) // Unset of set ->withsubstit=0 to disable this. + if (! empty($this->withsubstit)) // Unset or set ->withsubstit=0 to disable this. { $out.= '\n"; } else { - $out.= '\n"; } } @@ -518,7 +551,7 @@ class FormMail extends Form // To if (! empty($this->withto) || is_array($this->withto)) { - $out.= ''; } @@ -606,7 +642,7 @@ class FormMail extends Form } else { - $out.= 'withtocc) : (isset($_POST["sendtocc"])?$_POST["sendtocc"]:"") ).'" />'; + $out.= 'withtocc) : (isset($_POST["sendtocc"])?$_POST["sendtocc"]:"") ).'" />'; if (! empty($this->withtocc) && is_array($this->withtocc)) { $out.= " ".$langs->trans("and")."/".$langs->trans("or")." "; @@ -635,7 +671,7 @@ class FormMail extends Form } else { - $out.= 'withtoccc) : (isset($_POST["sendtoccc"])?$_POST["sendtoccc"]:"") ).'" />'; + $out.= 'withtoccc) : (isset($_POST["sendtoccc"])?$_POST["sendtoccc"]:"") ).'" />'; if (! empty($this->withtoccc) && is_array($this->withtoccc)) { $out.= " ".$langs->trans("and")."/".$langs->trans("or")." "; @@ -762,7 +798,7 @@ class FormMail extends Form if (is_numeric($this->withfile)) { - // TODO Trick to have param removedfile containing nb of image to delete. But this does not works without javascript + // TODO Trick to have param removedfile containing nb of file to delete. But this does not works without javascript $out.= ''."\n"; $out.= ''; - $out.= ''; - } - $out.= ''; - } - else // In most cases, this is not used. We used instead function with no specific list of colors - { - if (empty($conf->dol_use_jmobile)) - { - $out.= ''; - $out.= ''; - $out.= ''; - } - $out.= ''; - } - - return $out; - } - - /** - * Creation d'un icone de couleur - * - * @param string $color Couleur de l'image - * @param string $module Nom du module - * @param string $name Nom de l'image - * @param int $x Largeur de l'image en pixels - * @param int $y Hauteur de l'image en pixels - * @return void - */ - function CreateColorIcon($color,$module,$name,$x='12',$y='12') - { - global $conf; - - $file = $conf->$module->dir_temp.'/'.$name.'.png'; - - // On cree le repertoire contenant les icones - if (! file_exists($conf->$module->dir_temp)) - { - dol_mkdir($conf->$module->dir_temp); - } - - // On cree l'image en vraies couleurs - $image = imagecreatetruecolor($x,$y); - - $color = substr($color,1,6); - - $rouge = hexdec(substr($color,0,2)); //conversion du canal rouge - $vert = hexdec(substr($color,2,2)); //conversion du canal vert - $bleu = hexdec(substr($color,4,2)); //conversion du canal bleu - - $couleur = imagecolorallocate($image,$rouge,$vert,$bleu); - //print $rouge.$vert.$bleu; - imagefill($image,0,0,$couleur); //on remplit l'image - // On cree la couleur et on l'attribue a une variable pour ne pas la perdre - ImagePng($image,$file); //renvoie une image sous format png - ImageDestroy($image); - } - - /** - * Return HTML combo list of week - * - * @param string $selected Preselected value - * @param string $htmlname Nom de la zone select - * @param int $useempty Affiche valeur vide dans liste - * @return string - */ - function select_dayofweek($selected='',$htmlname='weekid',$useempty=0) - { - global $langs; - - $week = array( 0=>$langs->trans("Day0"), - 1=>$langs->trans("Day1"), - 2=>$langs->trans("Day2"), - 3=>$langs->trans("Day3"), - 4=>$langs->trans("Day4"), - 5=>$langs->trans("Day5"), - 6=>$langs->trans("Day6")); - - $select_week = ''; - return $select_week; - } - - /** - * Return HTML combo list of month - * - * @param string $selected Preselected value - * @param string $htmlname Name of HTML select object - * @param int $useempty Show empty in list - * @param int $longlabel Show long label - * @return string - */ - function select_month($selected='',$htmlname='monthid',$useempty=0,$longlabel=0) - { - global $langs; - - require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; - - if ($longlabel) $montharray = monthArray($langs, 0); // Get array - else $montharray = monthArray($langs, 1); - - $select_month = ''; - return $select_month; - } - - /** - * Return HTML combo list of years - * - * @param string $selected Preselected value (''=current year, -1=none, year otherwise) - * @param string $htmlname Name of HTML select object - * @param int $useempty Affiche valeur vide dans liste - * @param int $min_year Offset of minimum year into list (by default current year -10) - * @param int $max_year Offset of maximum year into list (by default current year + 5) - * @param int $offset Offset - * @param int $invert Invert - * @param string $option Option - * @return string - */ - function select_year($selected='',$htmlname='yearid',$useempty=0, $min_year=10, $max_year=5, $offset=0, $invert=0, $option='') - { - print $this->selectyear($selected,$htmlname,$useempty,$min_year,$max_year,$offset,$invert,$option); - } - - /** - * Return HTML combo list of years - * - * @param string $selected Preselected value (''=current year, -1=none, year otherwise) - * @param string $htmlname Name of HTML select object - * @param int $useempty Affiche valeur vide dans liste - * @param int $min_year Offset of minimum year into list (by default current year -10) - * @param int $max_year Offset of maximum year into list (by default current year + 5) - * @param int $offset Offset - * @param int $invert Invert - * @param string $option Option - * @return string - */ - function selectyear($selected='',$htmlname='yearid',$useempty=0, $min_year=10, $max_year=5, $offset=0, $invert=0, $option='') - { - $out=''; - - $currentyear = date("Y")+$offset; - $max_year = $currentyear+$max_year; - $min_year = $currentyear-$min_year; - if(empty($selected) && empty($useempty)) $selected = $currentyear; - - $out.= '\n"; - - return $out; - } - - /** - * Show form to select address - * - * @param int $page Page - * @param string $selected Id condition pre-selectionne - * @param int $socid Id of third party - * @param string $htmlname Nom du formulaire select - * @param string $origin Origine de l'appel pour pouvoir creer un retour - * @param int $originid Id de l'origine - * @return void - */ - function form_address($page, $selected, $socid, $htmlname='address_id', $origin='', $originid='') - { - global $langs,$conf; - global $form; - - if ($htmlname != "none") - { - print ''; - print ''; - print ''; - $form->select_address($selected, $socid, $htmlname, 1); - print ''; - $langs->load("companies"); - print '   '.$langs->trans("AddAddress").''; - print ''; - } - else - { - if ($selected) - { - require_once DOL_DOCUMENT_ROOT .'/societe/class/address.class.php'; - $address=new Address($this->db); - $result=$address->fetch_address($selected); - print ''.$address->label.''; - } - else - { - print " "; - } - } - } - - - - /** - * Get array with HTML tabs with boxes of a particular area including personalized choices of user. - * Class 'Form' must be known. - * - * @param User $user Object User - * @param String $areacode Code of area for pages ('0'=value for Home page) - * @return array array('selectboxlist'=>, 'boxactivated'=>, 'boxlista'=>, 'boxlistb'=>) - */ - static function getBoxesArea($user,$areacode) - { - global $conf,$langs,$db; - - include_once DOL_DOCUMENT_ROOT.'/core/class/infobox.class.php'; - - $confuserzone='MAIN_BOXES_'.$areacode; - - // $boxactivated will be array of boxes enabled into global setup - // $boxidactivatedforuser will be array of boxes choosed by user - - $selectboxlist=''; - $boxactivated=InfoBox::listBoxes($db, 'activated', $areacode, (empty($user->conf->$confuserzone)?null:$user), array(), 0); // Search boxes of common+user (or common only if user has no specific setup) - - $boxidactivatedforuser=array(); - foreach($boxactivated as $box) - { - if (empty($user->conf->$confuserzone) || $box->fk_user == $user->id) $boxidactivatedforuser[$box->id]=$box->id; // We keep only boxes to show for user - } - - // Define selectboxlist - $arrayboxtoactivatelabel=array(); - if (! empty($user->conf->$confuserzone)) - { - $boxorder=''; - $langs->load("boxes"); // Load label of boxes - foreach($boxactivated as $box) - { - if (! empty($boxidactivatedforuser[$box->id])) continue; // Already visible for user - $label=$langs->transnoentitiesnoconv($box->boxlabel); - if (preg_match('/graph/',$box->class)) $label.=' ('.$langs->trans("Graph").')'; - //$label = ''.$label; KO with select2. No html rendering. - $arrayboxtoactivatelabel[$box->id]=$label; // We keep only boxes not shown for user, to show into combo list - } - foreach($boxidactivatedforuser as $boxid) - { - if (empty($boxorder)) $boxorder.='A:'; - $boxorder.=$boxid.','; - } - - //var_dump($boxidactivatedforuser); - - // Class Form must have been already loaded - $selectboxlist.=''; - $selectboxlist.=''; - $selectboxlist.=''; - $selectboxlist.=''; - $selectboxlist.=''; - $selectboxlist.=Form::selectarray('boxcombo', $arrayboxtoactivatelabel, -1, $langs->trans("ChooseBoxToAdd").'...', 0, 0, '', 0, 0, 0, 'ASC', 'maxwidth150onsmartphone', 0, 'hidden selected', 0, 1); - if (empty($conf->use_javascript_ajax)) $selectboxlist.=' '; - $selectboxlist.=''; - $selectboxlist.=ajax_combobox("boxcombo"); - } - - // Javascript code for dynamic actions - if (! empty($conf->use_javascript_ajax)) - { - $selectboxlist.=''."\n"; - } - - // Define boxlista and boxlistb - $nbboxactivated=count($boxidactivatedforuser); - - if ($nbboxactivated) - { - $langs->load("boxes"); - $langs->load("projects"); - - $emptybox=new ModeleBoxes($db); - - $boxlista ="\n\n"; - $boxlista.='
    '."\n"; - - // Define $box_max_lines - $box_max_lines=5; - if (! empty($conf->global->MAIN_BOXES_MAXLINES)) $box_max_lines=$conf->global->MAIN_BOXES_MAXLINES; - - $ii=0; - foreach ($boxactivated as $key => $box) - { - if ((! empty($user->conf->$confuserzone) && $box->fk_user == 0) || (empty($user->conf->$confuserzone) && $box->fk_user != 0)) continue; - if (empty($box->box_order) && $ii < ($nbboxactivated / 2)) $box->box_order='A'.sprintf("%02d",($ii+1)); // When box_order was not yet set to Axx or Bxx and is still 0 - if (preg_match('/^A/i',$box->box_order)) // column A - { - $ii++; - //print 'box_id '.$boxactivated[$ii]->box_id.' '; - //print 'box_order '.$boxactivated[$ii]->box_order.'
    '; - // Show box - $box->loadBox($box_max_lines); - $boxlista.= $box->outputBox(); - } - } - - if (empty($conf->browser->phone)) - { - $emptybox->box_id='A'; - $emptybox->info_box_head=array(); - $emptybox->info_box_contents=array(); - $boxlista.= $emptybox->outputBox(array(),array()); - } - $boxlista.= "
    \n"; - $boxlista.= "\n"; - - $boxlistb = "\n\n"; - $boxlistb.= '\n"; - $boxlistb.= "\n"; - - } - - return array('selectboxlist'=>count($boxactivated)?$selectboxlist:'', 'boxactivated'=>$boxactivated, 'boxlista'=>$boxlista, 'boxlistb'=>$boxlistb); - } - - - /** - * Return a HTML select list of bank accounts - * - * @param string $htmlname Name of select zone - * @param string $dictionarytable Dictionary table - * @param string $keyfield Field for key - * @param string $labelfield Label field - * @param string $selected Selected value - * @param int $useempty 1=Add an empty value in list, 2=Add an empty value in list only if there is more than 2 entries. - * @param string $moreattrib More attributes on HTML select tag - * @return void - */ - function select_dictionary($htmlname,$dictionarytable,$keyfield='code',$labelfield='label',$selected='',$useempty=0,$moreattrib='') - { - global $langs, $conf; - - $langs->load("admin"); - - $sql = "SELECT rowid, ".$keyfield.", ".$labelfield; - $sql.= " FROM ".MAIN_DB_PREFIX.$dictionarytable; - $sql.= " ORDER BY ".$labelfield; - - dol_syslog(get_class($this)."::select_dictionary", LOG_DEBUG); - $result = $this->db->query($sql); - if ($result) - { - $num = $this->db->num_rows($result); - $i = 0; - if ($num) - { - print '"; - } - else - { - print $langs->trans("DictionaryEmpty"); - } - } - else { - dol_print_error($this->db); - } - } - } - diff --git a/htdocs/core/class/menu.class.php b/htdocs/core/class/menu.class.php index d4570218ff2..17d5e06589f 100644 --- a/htdocs/core/class/menu.class.php +++ b/htdocs/core/class/menu.class.php @@ -62,11 +62,12 @@ class Menu * @param string $id Id * @param string $idsel Id sel * @param string $classname Class name + * @param string $prefix Prefix to title (image or picto) * @return void */ - function add($url, $titre, $level=0, $enabled=1, $target='',$mainmenu='',$leftmenu='',$position=0, $id='', $idsel='', $classname='') + function add($url, $titre, $level=0, $enabled=1, $target='',$mainmenu='',$leftmenu='',$position=0, $id='', $idsel='', $classname='', $prefix='') { - $this->liste[]=array('url'=>$url,'titre'=>$titre,'level'=>$level,'enabled'=>$enabled,'target'=>$target,'mainmenu'=>$mainmenu,'leftmenu'=>$leftmenu, 'position'=>$position, 'id'=>$id, 'idsel'=>$idsel, 'classname'=>$classname); + $this->liste[]=array('url'=>$url,'titre'=>$titre,'level'=>$level,'enabled'=>$enabled,'target'=>$target,'mainmenu'=>$mainmenu,'leftmenu'=>$leftmenu, 'position'=>$position, 'id'=>$id, 'idsel'=>$idsel, 'classname'=>$classname, 'prefix'=>$prefix); } /** @@ -84,12 +85,13 @@ class Menu * @param string $id Id * @param string $idsel Id sel * @param string $classname Class name + * @param string $prefix Prefix to title (image or picto) * @return void */ - function insert($idafter, $url, $titre, $level=0, $enabled=1, $target='',$mainmenu='',$leftmenu='',$position=0, $id='', $idsel='', $classname='') + function insert($idafter, $url, $titre, $level=0, $enabled=1, $target='',$mainmenu='',$leftmenu='',$position=0, $id='', $idsel='', $classname='', $prefix='') { $array_start = array_slice($this->liste,0,($idafter+1)); - $array_new = array(0=>array('url'=>$url,'titre'=>$titre,'level'=>$level,'enabled'=>$enabled,'target'=>$target,'mainmenu'=>$mainmenu,'leftmenu'=>$leftmenu,'position'=>$position, 'id'=>$id, 'idsel'=>$idsel, 'classname'=>$classname)); + $array_new = array(0=>array('url'=>$url,'titre'=>$titre,'level'=>$level,'enabled'=>$enabled,'target'=>$target,'mainmenu'=>$mainmenu,'leftmenu'=>$leftmenu,'position'=>$position, 'id'=>$id, 'idsel'=>$idsel, 'classname'=>$classname, 'prefix'=>$prefix)); $array_end = array_slice($this->liste,($idafter+1)); $this->liste=array_merge($array_start,$array_new,$array_end); } diff --git a/htdocs/core/class/menubase.class.php b/htdocs/core/class/menubase.class.php index f011119e08e..a96f62e8cbc 100644 --- a/htdocs/core/class/menubase.class.php +++ b/htdocs/core/class/menubase.class.php @@ -520,8 +520,8 @@ class Menubase $sql.= " ORDER BY m.position, m.rowid"; //print $sql; -//$tmp1=microtime(true); -//print '>>> 1 0
    '; + //$tmp1=microtime(true); + //print '>>> 1 0
    '; dol_syslog(get_class($this)."::menuLoad mymainmenu=".$mymainmenu." myleftmenu=".$myleftmenu." type_user=".$type_user." menu_handler=".$menu_handler." tabMenu size=".count($tabMenu)."", LOG_DEBUG); $resql = $this->db->query($sql); if ($resql) @@ -558,7 +558,8 @@ class Menubase // Define $title if ($enabled) { - $title = $langs->trans($menu['titre']); + $title = $langs->trans($menu['titre']); // If $menu['titre'] start with $, a dol_eval is done. + //var_dump($title.'-'.$menu['titre']); if ($title == $menu['titre']) // Translation not found { if (! empty($menu['langs'])) // If there is a dedicated translation file @@ -567,6 +568,9 @@ class Menubase $langs->load($menu['langs']); } + $substitarray = array('__LOGIN__' => $user->login, '__USER_ID__' => $user->id, '__USER_SUPERVISOR_ID__' => $user->fk_user); + $menu['titre'] = make_substitutions($menu['titre'], $substitarray); + if (preg_match("/\//",$menu['titre'])) // To manage translation when title is string1/string2 { $tab_titre = explode("/",$menu['titre']); @@ -584,8 +588,8 @@ class Menubase $title = $langs->trans($menu['titre']); } } -//$tmp4=microtime(true); -//print '>>> 3 '.($tmp4 - $tmp3).'
    '; + //$tmp4=microtime(true); + //print '>>> 3 '.($tmp4 - $tmp3).'
    '; // We complete tabMenu $tabMenu[$b]['rowid'] = $menu['rowid']; diff --git a/htdocs/core/class/rssparser.class.php b/htdocs/core/class/rssparser.class.php index 56e338b7eb8..1d3af953375 100644 --- a/htdocs/core/class/rssparser.class.php +++ b/htdocs/core/class/rssparser.class.php @@ -278,12 +278,19 @@ class RssParser dol_syslog(get_class($this)."::parser cache file ".$newpathofdestfile." is saved onto disk."); if (! dol_is_dir($cachedir)) dol_mkdir($cachedir); $fp = fopen($newpathofdestfile, 'w'); - fwrite($fp, $str); - fclose($fp); - if (! empty($conf->global->MAIN_UMASK)) $newmask=$conf->global->MAIN_UMASK; - @chmod($newpathofdestfile, octdec($newmask)); + if ($fp) + { + fwrite($fp, $str); + fclose($fp); + if (! empty($conf->global->MAIN_UMASK)) $newmask=$conf->global->MAIN_UMASK; + @chmod($newpathofdestfile, octdec($newmask)); - $this->_lastfetchdate=$nowgmt; + $this->_lastfetchdate=$nowgmt; + } + else + { + print 'Error, failed to open file '.$newpathofdestfile.' for write'; + } } unset($str); // Free memory diff --git a/htdocs/core/class/smtps.class.php b/htdocs/core/class/smtps.class.php index 7ddb71315b7..c4176d2b81b 100644 --- a/htdocs/core/class/smtps.class.php +++ b/htdocs/core/class/smtps.class.php @@ -427,7 +427,18 @@ class SMTPs if ($usetls) $host='tls://'.$host; - if ( $_retVal = $this->socket_send_str('EHLO ' . $host, '250') ) + $hosth = $host; + + if (! empty($conf->global->MAIL_SMTP_USE_FROM_FOR_HELO)) + { + // If the from to is 'aaa ', we will keep 'ccc.com' + $hosth = $this->getFrom('addr'); + $hosth = preg_replace('/^.*.*$/', '', $hosth); + $hosth = preg_replace('/.*@/', '', $hosth); + } + + if ( $_retVal = $this->socket_send_str('EHLO ' . $hosth, '250') ) { if ($usetls) { @@ -512,6 +523,8 @@ class SMTPs */ function sendMsg($_bolTestMsg = false, $_bolDebug = false) { + global $conf; + /** * Default return value */ @@ -538,7 +551,18 @@ class SMTPs $host=preg_replace('@ssl://@i','',$host); // Remove prefix $host=preg_replace('@tls://@i','',$host); // Remove prefix - $_retVal = $this->socket_send_str('HELO ' . $host, '250'); + $hosth = $host; + + if (! empty($conf->global->MAIL_SMTP_USE_FROM_FOR_HELO)) + { + // If the from to is 'aaa ', we will keep 'ccc.com' + $hosth = $this->getFrom('addr'); + $hosth = preg_replace('/^.*.*$/', '', $hosth); + $hosth = preg_replace('/.*@/', '', $hosth); + } + + $_retVal = $this->socket_send_str('HELO ' . $hosth, '250'); } // Well, did we get to the server? @@ -1283,6 +1307,7 @@ class SMTPs { $_header .= 'Message-ID: <' . time() . '.SMTPs@' . $host . ">\r\n"; } + if (! empty($_SERVER['REMOTE_ADDR'])) $_header .= "X-RemoteAddr: " . $_SERVER['REMOTE_ADDR']. "\r\n"; if ( $this->getMoreInHeader() ) $_header .= $this->getMoreInHeader(); // Value must include the "\r\n"; @@ -1724,7 +1749,7 @@ class SMTPs * using SMTP Extensions * * @param Handler $socket Socket handler - * @param string $response Response + * @param string $response Response. Example: "550 5.7.1 https://support.google.com/a/answer/6140680#invalidcred j21sm814390wre.3" * @return boolean True or false */ function server_parse($socket, $response) @@ -1736,20 +1761,22 @@ class SMTPs $_retVal = true; $server_response = ''; + // avoid infinite loop $limit=0; - while ( substr($server_response,3,1) != ' ' && $limit<100) + while (substr($server_response,3,1) != ' ' && $limit<100) { - if( !( $server_response = fgets($socket, 256) ) ) + if (! ($server_response = fgets($socket, 256))) { $this->_setErr(121, "Couldn't get mail server response codes"); $_retVal = false; + break; } $limit++; } - if( !( substr($server_response, 0, 3) == $response ) ) + if (! (substr($server_response, 0, 3) == $response)) { $this->_setErr(120, "Ran into problems sending Mail.\r\nResponse: $server_response"); $_retVal = false; diff --git a/htdocs/core/class/stats.class.php b/htdocs/core/class/stats.class.php index 8e3c70c0829..dfb070aa5b9 100644 --- a/htdocs/core/class/stats.class.php +++ b/htdocs/core/class/stats.class.php @@ -39,9 +39,10 @@ abstract class Stats * @param int $endyear Start year * @param int $startyear End year * @param int $cachedelay Delay we accept for cache file (0=No read, no save of cache, -1=No read but save) + * @param int $format 0=Label of absiss is a translated text, 1=Label of absiss is month number, 2=Label of absiss is first letter of month * @return array Array of values */ - function getNbByMonthWithPrevYear($endyear,$startyear,$cachedelay=0) + function getNbByMonthWithPrevYear($endyear, $startyear, $cachedelay=0, $format=0) { global $conf,$user,$langs; @@ -76,7 +77,6 @@ abstract class Stats dol_syslog(get_class($this).'::'.__FUNCTION__." cache file ".$newpathofdestfile." is not found or older than now - cachedelay (".$nowgmt." - ".$cachedelay.") so we can't use it."); } } - // Load file into $data if ($foundintocache) // Cache file found and is not too old { @@ -88,7 +88,7 @@ abstract class Stats $year=$startyear; while ($year <= $endyear) { - $datay[$year] = $this->getNbByMonth($year); + $datay[$year] = $this->getNbByMonth($year, $format); $year++; } @@ -133,9 +133,10 @@ abstract class Stats * @param int $endyear Start year * @param int $startyear End year * @param int $cachedelay Delay we accept for cache file (0=No read, no save of cache, -1=No read but save) + * @param int $format 0=Label of absiss is a translated text, 1=Label of absiss is month number, 2=Label of absiss is first letter of month * @return array Array of values */ - function getAmountByMonthWithPrevYear($endyear,$startyear,$cachedelay=0) + function getAmountByMonthWithPrevYear($endyear, $startyear, $cachedelay=0, $format=0) { global $conf,$user,$langs; @@ -182,7 +183,7 @@ abstract class Stats $year=$startyear; while($year <= $endyear) { - $datay[$year] = $this->getAmountByMonth($year); + $datay[$year] = $this->getAmountByMonth($year, $format); $year++; } @@ -409,11 +410,13 @@ abstract class Stats * * @param int $year Year * @param string $sql SQL - * @param int $format 0=Label of absiss is a translated text, 1=Label of absiss is a number + * @param int $format 0=Label of absiss is a translated text, 1=Label of absiss is month number, 2=Label of absiss is first letter of month * @return array Array of nb each month */ function _getNbByMonth($year, $sql, $format=0) { + global $langs; + $result=array(); $res=array(); @@ -446,8 +449,12 @@ abstract class Stats for ($i = 1 ; $i < 13 ; $i++) { - $month=dol_print_date(dol_mktime(12,0,0,$i,1,$year),($format?"%m":"%b")); - $month=dol_substr($month,0,3); + $month='unknown'; + if ($format == 0) $month=$langs->transnoentitiesnoconv('MonthShort'.sprintf("%02d", $i)); + elseif ($format == 1) $month=$i; + elseif ($format == 2) $month=$langs->transnoentitiesnoconv('MonthVeryShort'.sprintf("%02d", $i)); + //$month=dol_print_date(dol_mktime(12,0,0,$i,1,$year),($format?"%m":"%b")); + //$month=dol_substr($month,0,3); $data[$i-1] = array($month, $res[$i]); } @@ -460,11 +467,13 @@ abstract class Stats * * @param int $year Year * @param string $sql SQL - * @param int $format 0=Label of absiss is a translated text, 1=Label of absiss is a number + * @param int $format 0=Label of absiss is a translated text, 1=Label of absiss is month number, 2=Label of absiss is first letter of month * @return array */ function _getAmountByMonth($year, $sql, $format=0) { + global $langs; + $result=array(); $res=array(); @@ -495,8 +504,12 @@ abstract class Stats for ($i = 1 ; $i < 13 ; $i++) { - $month=dol_print_date(dol_mktime(12,0,0,$i,1,$year),($format?"%m":"%b")); - $month=dol_substr($month,0,3); + $month='unknown'; + if ($format == 0) $month=$langs->transnoentitiesnoconv('MonthShort'.sprintf("%02d", $i)); + elseif ($format == 1) $month=$i; + elseif ($format == 2) $month=$langs->transnoentitiesnoconv('MonthVeryShort'.sprintf("%02d", $i)); + //$month=dol_print_date(dol_mktime(12,0,0,$i,1,$year),($format?"%m":"%b")); + //$month=dol_substr($month,0,3); $data[$i-1] = array($month, $res[$i]); } @@ -508,11 +521,13 @@ abstract class Stats * * @param int $year Year * @param string $sql SQL - * @param int $format 0=Label of absiss is a translated text, 1=Label of absiss is a number + * @param int $format 0=Label of absiss is a translated text, 1=Label of absiss is month number, 2=Label of absiss is first letter of month * @return array */ function _getAverageByMonth($year, $sql, $format=0) { + global $langs; + $result=array(); $res=array(); @@ -542,8 +557,12 @@ abstract class Stats for ($i = 1 ; $i < 13 ; $i++) { - $month=dol_print_date(dol_mktime(12,0,0,$i,1,$year),($format?"%m":"%b")); - $month=dol_substr($month,0,3); + $month='unknown'; + if ($format == 0) $month=$langs->transnoentitiesnoconv('MonthShort'.sprintf("%02d", $i)); + elseif ($format == 1) $month=$i; + elseif ($format == 2) $month=$langs->transnoentitiesnoconv('MonthVeryShort'.sprintf("%02d", $i)); + //$month=dol_print_date(dol_mktime(12,0,0,$i,1,$year),($format?"%m":"%b")); + //$month=dol_substr($month,0,3); $data[$i-1] = array($month, $res[$i]); } diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php index 55aac773420..7b6ef9bbde1 100644 --- a/htdocs/core/class/translate.class.php +++ b/htdocs/core/class/translate.class.php @@ -45,10 +45,10 @@ class Translate /** * Constructor * - * @param string $dir Force directory that contains /langs subdirectory (value is sometine '..' like into install/* pages or support/* pages). + * @param string $dir Force directory that contains /langs subdirectory (value is sometimes '..' like into install/* pages or support/* pages). Use '' by default. * @param Conf $conf Object with Dolibarr configuration */ - function __construct($dir,$conf) + function __construct($dir, $conf) { if (! empty($conf->file->character_set_client)) $this->charset_output=$conf->file->character_set_client; // If charset output is forced if ($dir) $this->dir=array($dir); @@ -98,12 +98,13 @@ class Translate // We redefine $srclang $langpart=explode("_",$codetouse); - //print "Short before _ : ".$langpart[0].'/ Short after _ : '.$langpart[1].'
    '; + //print "Short code before _ : ".$langpart[0].' / Short code after _ : '.$langpart[1].'
    '; if (! empty($langpart[1])) // If it's for a codetouse that is a long code xx_YY { // Array force long code from first part, even if long code is defined $longforshort=array('ar'=>'ar_SA'); - if (isset($longforshort[strtolower($langpart[0])])) $srclang=$longforshort[strtolower($langpart[0])]; + $longforshortexcep=array('ar_EG'); + if (isset($longforshort[strtolower($langpart[0])]) && ! in_array($codetouse, $longforshortexcep)) $srclang=$longforshort[strtolower($langpart[0])]; else if (! is_numeric($langpart[1])) { // Second part YY may be a numeric with some Chrome browser $srclang=strtolower($langpart[0])."_".strtoupper($langpart[1]); $longforlong=array('no_nb'=>'nb_NO'); @@ -339,7 +340,8 @@ class Translate // This function MUST NOT contains call to syslog //dol_syslog("Translate::Load loading alternate translation file (to complete ".$this->defaultlang."/".$newdomain.".lang file)", LOG_DEBUG); $langofdir=strtolower($langarray[0]).'_'.strtoupper($langarray[0]); - if ($langofdir == 'el_EL') $langofdir = 'el_GR'; // main parent for el_CY is not el_EL but el_GR + if ($langofdir == 'el_EL') $langofdir = 'el_GR'; // main parent for el_CY is not 'el_EL' but 'el_GR' + if ($langofdir == 'ar_AR') $langofdir = 'ar_SA'; // main parent for ar_EG is not 'ar_AR' but 'ar_SA' $this->load($domain,$alt+1,$stopafterdirection,$langofdir); } @@ -633,7 +635,7 @@ class Translate } else // Translation is not available { - if ($key[0] == '$') { return dol_eval($key,1); } + //if ($key[0] == '$') { return dol_eval($key,1); } return $this->getTradFromKey($key); } } diff --git a/htdocs/core/class/utils.class.php b/htdocs/core/class/utils.class.php index cf5d02a7b31..4502eb03240 100644 --- a/htdocs/core/class/utils.class.php +++ b/htdocs/core/class/utils.class.php @@ -90,10 +90,10 @@ class Utils if ($choice=='logfile') { - // Define files log + // Define files log if ($dolibarr_main_data_root) { - $filesarray=dol_dir_list($dolibarr_main_data_root, "files", 0, '.*\.log[\.0-9]*$', 'install\.lock$'); + $filesarray=dol_dir_list($dolibarr_main_data_root, "files", 0, '.*\.log[\.0-9]*$', 'install\.lock$'); } $filelog=''; @@ -105,7 +105,7 @@ class Utils $alreadyincluded=false; foreach ($filesarray as $tmpcursor) { - if ($tmpcursor['fullname'] == $filelog) { $alreadyincluded=true; } + if ($tmpcursor['fullname'] == $filelog) { $alreadyincluded=true; } } if (! $alreadyincluded) $filesarray[]=array('fullname'=>$filelog,'type'=>'file'); } @@ -121,24 +121,24 @@ class Utils //print "x ".$filesarray[$key]['fullname']."-".$filesarray[$key]['type']."
    \n"; if ($filesarray[$key]['type'] == 'dir') { - $startcount=0; - $tmpcountdeleted=0; + $startcount=0; + $tmpcountdeleted=0; $result=dol_delete_dir_recursive($filesarray[$key]['fullname'], $startcount, 1, 0, $tmpcountdeleted); - $count+=$result; - $countdeleted+=$tmpcountdeleted; + $count+=$result; + $countdeleted+=$tmpcountdeleted; } elseif ($filesarray[$key]['type'] == 'file') { // If (file that is not logfile) or (if logfile with option logfile) if ($filesarray[$key]['fullname'] != $filelog || $choice=='logfile') { - $result=dol_delete_file($filesarray[$key]['fullname'], 1, 1); - if ($result) - { - $count++; - $countdeleted++; - } - else $counterror++; + $result=dol_delete_file($filesarray[$key]['fullname'], 1, 1); + if ($result) + { + $count++; + $countdeleted++; + } + else $counterror++; } } } @@ -154,8 +154,8 @@ class Utils if ($count > 0) { - $this->output=$langs->trans("PurgeNDirectoriesDeleted", $countdeleted); - if ($count > $countdeleted) $this->output.='
    '.$langs->trans("PurgeNDirectoriesFailed", ($count - $countdeleted)); + $this->output=$langs->trans("PurgeNDirectoriesDeleted", $countdeleted); + if ($count > $countdeleted) $this->output.='
    '.$langs->trans("PurgeNDirectoriesFailed", ($count - $countdeleted)); } else $this->output=$langs->trans("PurgeNothingToDelete").($choice == 'tempfilesold' ? ' (older than 24h)':''); @@ -189,29 +189,29 @@ class Utils // Check compression parameter if (! in_array($compression, array('none', 'gz', 'bz', 'zip'))) { - $langs->load("errors"); - $this->error=$langs->transnoentitiesnoconv("ErrorBadValueForParameter", $compression, "Compression"); - return -1; + $langs->load("errors"); + $this->error=$langs->transnoentitiesnoconv("ErrorBadValueForParameter", $compression, "Compression"); + return -1; } // Check type parameter if ($type == 'auto') $type = $db->type; - if (! in_array($type, array('pgsql', 'mysql', 'mysqli','mysqlnobin'))) + if (! in_array($type, array('postgresql', 'pgsql', 'mysql', 'mysqli', 'mysqlnobin'))) { - $langs->load("errors"); - $this->error=$langs->transnoentitiesnoconv("ErrorBadValueForParameter", $type, "Basetype"); - return -1; + $langs->load("errors"); + $this->error=$langs->transnoentitiesnoconv("ErrorBadValueForParameter", $type, "Basetype"); + return -1; } // Check file parameter if ($file == 'auto') { - $prefix='dump'; - $ext='.sql'; - if (in_array($type, array('mysql', 'mysqli'))) { $prefix='mysqldump'; $ext='sql'; } - //if ($label == 'PostgreSQL') { $prefix='pg_dump'; $ext='dump'; } - if (in_array($type, array('pgsql'))) { $prefix='pg_dump'; $ext='sql'; } - $file=$prefix.'_'.$dolibarr_main_db_name.'_'.dol_sanitizeFileName(DOL_VERSION).'_'.strftime("%Y%m%d%H%M").'.'.$ext; + $prefix='dump'; + $ext='.sql'; + if (in_array($type, array('mysql', 'mysqli'))) { $prefix='mysqldump'; $ext='sql'; } + //if ($label == 'PostgreSQL') { $prefix='pg_dump'; $ext='dump'; } + if (in_array($type, array('pgsql'))) { $prefix='pg_dump'; $ext='sql'; } + $file=$prefix.'_'.$dolibarr_main_db_name.'_'.dol_sanitizeFileName(DOL_VERSION).'_'.strftime("%Y%m%d%H%M").'.'.$ext; } $outputdir = $conf->admin->dir_output.'/backup'; @@ -221,229 +221,229 @@ class Utils // MYSQL if ($type == 'mysql' || $type == 'mysqli') { - $cmddump=$conf->global->SYSTEMTOOLS_MYSQLDUMP; + $cmddump=$conf->global->SYSTEMTOOLS_MYSQLDUMP; - $outputfile = $outputdir.'/'.$file; - // for compression format, we add extension - $compression=$compression ? $compression : 'none'; - if ($compression == 'gz') $outputfile.='.gz'; - if ($compression == 'bz') $outputfile.='.bz2'; - $outputerror = $outputfile.'.err'; - dol_mkdir($conf->admin->dir_output.'/backup'); + $outputfile = $outputdir.'/'.$file; + // for compression format, we add extension + $compression=$compression ? $compression : 'none'; + if ($compression == 'gz') $outputfile.='.gz'; + if ($compression == 'bz') $outputfile.='.bz2'; + $outputerror = $outputfile.'.err'; + dol_mkdir($conf->admin->dir_output.'/backup'); - // Parameteres execution - $command=$cmddump; - if (preg_match("/\s/",$command)) $command=escapeshellarg($command); // Use quotes on command + // Parameteres execution + $command=$cmddump; + if (preg_match("/\s/",$command)) $command=escapeshellarg($command); // Use quotes on command - //$param=escapeshellarg($dolibarr_main_db_name)." -h ".escapeshellarg($dolibarr_main_db_host)." -u ".escapeshellarg($dolibarr_main_db_user)." -p".escapeshellarg($dolibarr_main_db_pass); - $param=$dolibarr_main_db_name." -h ".$dolibarr_main_db_host; - $param.=" -u ".$dolibarr_main_db_user; - if (! empty($dolibarr_main_db_port)) $param.=" -P ".$dolibarr_main_db_port; - if (! GETPOST("use_transaction")) $param.=" -l --single-transaction"; - if (GETPOST("disable_fk") || $usedefault) $param.=" -K"; - if (GETPOST("sql_compat") && GETPOST("sql_compat") != 'NONE') $param.=" --compatible=".escapeshellarg(GETPOST("sql_compat","alpha")); - if (GETPOST("drop_database")) $param.=" --add-drop-database"; - if (GETPOST("sql_structure") || $usedefault) - { - if (GETPOST("drop") || $usedefault) $param.=" --add-drop-table=TRUE"; - else $param.=" --add-drop-table=FALSE"; - } - else - { - $param.=" -t"; - } - if (GETPOST("disable-add-locks")) $param.=" --add-locks=FALSE"; - if (GETPOST("sql_data") || $usedefault) - { - $param.=" --tables"; - if (GETPOST("showcolumns") || $usedefault) $param.=" -c"; - if (GETPOST("extended_ins") || $usedefault) $param.=" -e"; - else $param.=" --skip-extended-insert"; - if (GETPOST("delayed")) $param.=" --delayed-insert"; - if (GETPOST("sql_ignore")) $param.=" --insert-ignore"; - if (GETPOST("hexforbinary") || $usedefault) $param.=" --hex-blob"; - } - else - { - $param.=" -d"; // No row information (no data) - } - $param.=" --default-character-set=utf8"; // We always save output into utf8 charset - $paramcrypted=$param; - $paramclear=$param; - if (! empty($dolibarr_main_db_pass)) - { - $paramcrypted.=' -p"'.preg_replace('/./i','*',$dolibarr_main_db_pass).'"'; - $paramclear.=' -p"'.str_replace(array('"','`'),array('\"','\`'),$dolibarr_main_db_pass).'"'; - } + //$param=escapeshellarg($dolibarr_main_db_name)." -h ".escapeshellarg($dolibarr_main_db_host)." -u ".escapeshellarg($dolibarr_main_db_user)." -p".escapeshellarg($dolibarr_main_db_pass); + $param=$dolibarr_main_db_name." -h ".$dolibarr_main_db_host; + $param.=" -u ".$dolibarr_main_db_user; + if (! empty($dolibarr_main_db_port)) $param.=" -P ".$dolibarr_main_db_port; + if (! GETPOST("use_transaction")) $param.=" -l --single-transaction"; + if (GETPOST("disable_fk") || $usedefault) $param.=" -K"; + if (GETPOST("sql_compat") && GETPOST("sql_compat") != 'NONE') $param.=" --compatible=".escapeshellarg(GETPOST("sql_compat","alpha")); + if (GETPOST("drop_database")) $param.=" --add-drop-database"; + if (GETPOST("sql_structure") || $usedefault) + { + if (GETPOST("drop") || $usedefault) $param.=" --add-drop-table=TRUE"; + else $param.=" --add-drop-table=FALSE"; + } + else + { + $param.=" -t"; + } + if (GETPOST("disable-add-locks")) $param.=" --add-locks=FALSE"; + if (GETPOST("sql_data") || $usedefault) + { + $param.=" --tables"; + if (GETPOST("showcolumns") || $usedefault) $param.=" -c"; + if (GETPOST("extended_ins") || $usedefault) $param.=" -e"; + else $param.=" --skip-extended-insert"; + if (GETPOST("delayed")) $param.=" --delayed-insert"; + if (GETPOST("sql_ignore")) $param.=" --insert-ignore"; + if (GETPOST("hexforbinary") || $usedefault) $param.=" --hex-blob"; + } + else + { + $param.=" -d"; // No row information (no data) + } + $param.=" --default-character-set=utf8"; // We always save output into utf8 charset + $paramcrypted=$param; + $paramclear=$param; + if (! empty($dolibarr_main_db_pass)) + { + $paramcrypted.=' -p"'.preg_replace('/./i','*',$dolibarr_main_db_pass).'"'; + $paramclear.=' -p"'.str_replace(array('"','`'),array('\"','\`'),$dolibarr_main_db_pass).'"'; + } - $errormsg=''; + $errormsg=''; - // Debut appel methode execution - $fullcommandcrypted=$command." ".$paramcrypted." 2>&1"; - $fullcommandclear=$command." ".$paramclear." 2>&1"; - if ($compression == 'none') $handle = fopen($outputfile, 'w'); - if ($compression == 'gz') $handle = gzopen($outputfile, 'w'); - if ($compression == 'bz') $handle = bzopen($outputfile, 'w'); + // Debut appel methode execution + $fullcommandcrypted=$command." ".$paramcrypted." 2>&1"; + $fullcommandclear=$command." ".$paramclear." 2>&1"; + if ($compression == 'none') $handle = fopen($outputfile, 'w'); + if ($compression == 'gz') $handle = gzopen($outputfile, 'w'); + if ($compression == 'bz') $handle = bzopen($outputfile, 'w'); - if ($handle) - { - $ok=0; - dol_syslog("Run command ".$fullcommandcrypted); - $handlein = popen($fullcommandclear, 'r'); - $i=0; - while (!feof($handlein)) - { - $i++; // output line number - $read = fgets($handlein); - // Exclude warning line we don't want - if ($i == 1 && preg_match('/Warning.*Using a password/i', $read)) continue; - fwrite($handle,$read); - if (preg_match('/'.preg_quote('-- Dump completed').'/i',$read)) $ok=1; - elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i',$read)) $ok=1; - } - pclose($handlein); + if ($handle) + { + $ok=0; + dol_syslog("Run command ".$fullcommandcrypted); + $handlein = popen($fullcommandclear, 'r'); + $i=0; + while (!feof($handlein)) + { + $i++; // output line number + $read = fgets($handlein); + // Exclude warning line we don't want + if ($i == 1 && preg_match('/Warning.*Using a password/i', $read)) continue; + fwrite($handle,$read); + if (preg_match('/'.preg_quote('-- Dump completed').'/i',$read)) $ok=1; + elseif (preg_match('/'.preg_quote('SET SQL_NOTES=@OLD_SQL_NOTES').'/i',$read)) $ok=1; + } + pclose($handlein); - if ($compression == 'none') fclose($handle); - if ($compression == 'gz') gzclose($handle); - if ($compression == 'bz') bzclose($handle); + if ($compression == 'none') fclose($handle); + if ($compression == 'gz') gzclose($handle); + if ($compression == 'bz') bzclose($handle); - if (! empty($conf->global->MAIN_UMASK)) - @chmod($outputfile, octdec($conf->global->MAIN_UMASK)); - } - else - { - $langs->load("errors"); - dol_syslog("Failed to open file ".$outputfile,LOG_ERR); - $errormsg=$langs->trans("ErrorFailedToWriteInDir"); - } + if (! empty($conf->global->MAIN_UMASK)) + @chmod($outputfile, octdec($conf->global->MAIN_UMASK)); + } + else + { + $langs->load("errors"); + dol_syslog("Failed to open file ".$outputfile,LOG_ERR); + $errormsg=$langs->trans("ErrorFailedToWriteInDir"); + } - // Get errorstring - if ($compression == 'none') $handle = fopen($outputfile, 'r'); - if ($compression == 'gz') $handle = gzopen($outputfile, 'r'); - if ($compression == 'bz') $handle = bzopen($outputfile, 'r'); - if ($handle) - { - // Get 2048 first chars of error message. - $errormsg = fgets($handle,2048); - // Close file - if ($compression == 'none') fclose($handle); - if ($compression == 'gz') gzclose($handle); - if ($compression == 'bz') bzclose($handle); - if ($ok && preg_match('/^-- MySql/i',$errormsg)) $errormsg=''; // Pas erreur - else - { - // Renommer fichier sortie en fichier erreur - //print "$outputfile -> $outputerror"; - @dol_delete_file($outputerror,1); - @rename($outputfile,$outputerror); - // Si safe_mode on et command hors du parametre exec, on a un fichier out vide donc errormsg vide - if (! $errormsg) - { - $langs->load("errors"); - $errormsg=$langs->trans("ErrorFailedToRunExternalCommand"); - } - } - } - // Fin execution commande + // Get errorstring + if ($compression == 'none') $handle = fopen($outputfile, 'r'); + if ($compression == 'gz') $handle = gzopen($outputfile, 'r'); + if ($compression == 'bz') $handle = bzopen($outputfile, 'r'); + if ($handle) + { + // Get 2048 first chars of error message. + $errormsg = fgets($handle,2048); + // Close file + if ($compression == 'none') fclose($handle); + if ($compression == 'gz') gzclose($handle); + if ($compression == 'bz') bzclose($handle); + if ($ok && preg_match('/^-- MySql/i',$errormsg)) $errormsg=''; // Pas erreur + else + { + // Renommer fichier sortie en fichier erreur + //print "$outputfile -> $outputerror"; + @dol_delete_file($outputerror,1); + @rename($outputfile,$outputerror); + // Si safe_mode on et command hors du parametre exec, on a un fichier out vide donc errormsg vide + if (! $errormsg) + { + $langs->load("errors"); + $errormsg=$langs->trans("ErrorFailedToRunExternalCommand"); + } + } + } + // Fin execution commande - $this->output = $errormsg; - $this->error = $errormsg; - $this->result = array("commandbackuplastdone" => $command." ".$paramcrypted, "commandbackuptorun" => ""); - //if (empty($this->output)) $this->output=$this->result['commandbackuplastdone']; + $this->output = $errormsg; + $this->error = $errormsg; + $this->result = array("commandbackuplastdone" => $command." ".$paramcrypted, "commandbackuptorun" => ""); + //if (empty($this->output)) $this->output=$this->result['commandbackuplastdone']; } // MYSQL NO BIN if ($type == 'mysqlnobin') { - $outputfile = $outputdir.'/'.$file; - $outputfiletemp = $outputfile.'-TMP.sql'; - // for compression format, we add extension - $compression=$compression ? $compression : 'none'; - if ($compression == 'gz') $outputfile.='.gz'; - if ($compression == 'bz') $outputfile.='.bz2'; - $outputerror = $outputfile.'.err'; - dol_mkdir($conf->admin->dir_output.'/backup'); + $outputfile = $outputdir.'/'.$file; + $outputfiletemp = $outputfile.'-TMP.sql'; + // for compression format, we add extension + $compression=$compression ? $compression : 'none'; + if ($compression == 'gz') $outputfile.='.gz'; + if ($compression == 'bz') $outputfile.='.bz2'; + $outputerror = $outputfile.'.err'; + dol_mkdir($conf->admin->dir_output.'/backup'); - if ($compression == 'gz' or $compression == 'bz') - { - backup_tables($outputfiletemp); - dol_compress_file($outputfiletemp, $outputfile, $compression); - unlink($outputfiletemp); - } - else - { - backup_tables($outputfile); - } + if ($compression == 'gz' or $compression == 'bz') + { + backup_tables($outputfiletemp); + dol_compress_file($outputfiletemp, $outputfile, $compression); + unlink($outputfiletemp); + } + else + { + backup_tables($outputfile); + } - $this->output = ""; - $this->result = array("commandbackuplastdone" => "", "commandbackuptorun" => ""); + $this->output = ""; + $this->result = array("commandbackuplastdone" => "", "commandbackuptorun" => ""); } // POSTGRESQL - if ($type == 'postgresql') + if ($type == 'postgresql' || $type == 'pgsql') { - $cmddump=$conf->global->SYSTEMTOOLS_POSTGRESQLDUMP; + $cmddump=$conf->global->SYSTEMTOOLS_POSTGRESQLDUMP; - $outputfile = $outputdir.'/'.$file; - // for compression format, we add extension - $compression=$compression ? $compression : 'none'; - if ($compression == 'gz') $outputfile.='.gz'; - if ($compression == 'bz') $outputfile.='.bz2'; - $outputerror = $outputfile.'.err'; - dol_mkdir($conf->admin->dir_output.'/backup'); + $outputfile = $outputdir.'/'.$file; + // for compression format, we add extension + $compression=$compression ? $compression : 'none'; + if ($compression == 'gz') $outputfile.='.gz'; + if ($compression == 'bz') $outputfile.='.bz2'; + $outputerror = $outputfile.'.err'; + dol_mkdir($conf->admin->dir_output.'/backup'); - // Parameteres execution - $command=$cmddump; - if (preg_match("/\s/",$command)) $command=escapeshellarg($command); // Use quotes on command + // Parameteres execution + $command=$cmddump; + if (preg_match("/\s/",$command)) $command=escapeshellarg($command); // Use quotes on command - //$param=escapeshellarg($dolibarr_main_db_name)." -h ".escapeshellarg($dolibarr_main_db_host)." -u ".escapeshellarg($dolibarr_main_db_user)." -p".escapeshellarg($dolibarr_main_db_pass); - //$param="-F c"; - $param="-F p"; - $param.=" --no-tablespaces --inserts -h ".$dolibarr_main_db_host; - $param.=" -U ".$dolibarr_main_db_user; - if (! empty($dolibarr_main_db_port)) $param.=" -p ".$dolibarr_main_db_port; - if (GETPOST("sql_compat") && GETPOST("sql_compat") == 'ANSI') $param.=" --disable-dollar-quoting"; - if (GETPOST("drop_database")) $param.=" -c -C"; - if (GETPOST("sql_structure")) - { - if (GETPOST("drop")) $param.=" --add-drop-table"; - if (! GETPOST("sql_data")) $param.=" -s"; - } - if (GETPOST("sql_data")) - { - if (! GETPOST("sql_structure")) $param.=" -a"; - if (GETPOST("showcolumns")) $param.=" -c"; - } - $param.=' -f "'.$outputfile.'"'; - //if ($compression == 'none') - if ($compression == 'gz') $param.=' -Z 9'; - //if ($compression == 'bz') - $paramcrypted=$param; - $paramclear=$param; - /*if (! empty($dolibarr_main_db_pass)) - { - $paramcrypted.=" -W".preg_replace('/./i','*',$dolibarr_main_db_pass); - $paramclear.=" -W".$dolibarr_main_db_pass; - }*/ - $paramcrypted.=" -w ".$dolibarr_main_db_name; - $paramclear.=" -w ".$dolibarr_main_db_name; + //$param=escapeshellarg($dolibarr_main_db_name)." -h ".escapeshellarg($dolibarr_main_db_host)." -u ".escapeshellarg($dolibarr_main_db_user)." -p".escapeshellarg($dolibarr_main_db_pass); + //$param="-F c"; + $param="-F p"; + $param.=" --no-tablespaces --inserts -h ".$dolibarr_main_db_host; + $param.=" -U ".$dolibarr_main_db_user; + if (! empty($dolibarr_main_db_port)) $param.=" -p ".$dolibarr_main_db_port; + if (GETPOST("sql_compat") && GETPOST("sql_compat") == 'ANSI') $param.=" --disable-dollar-quoting"; + if (GETPOST("drop_database")) $param.=" -c -C"; + if (GETPOST("sql_structure")) + { + if (GETPOST("drop")) $param.=" --add-drop-table"; + if (! GETPOST("sql_data")) $param.=" -s"; + } + if (GETPOST("sql_data")) + { + if (! GETPOST("sql_structure")) $param.=" -a"; + if (GETPOST("showcolumns")) $param.=" -c"; + } + $param.=' -f "'.$outputfile.'"'; + //if ($compression == 'none') + if ($compression == 'gz') $param.=' -Z 9'; + //if ($compression == 'bz') + $paramcrypted=$param; + $paramclear=$param; + /*if (! empty($dolibarr_main_db_pass)) + { + $paramcrypted.=" -W".preg_replace('/./i','*',$dolibarr_main_db_pass); + $paramclear.=" -W".$dolibarr_main_db_pass; + }*/ + $paramcrypted.=" -w ".$dolibarr_main_db_name; + $paramclear.=" -w ".$dolibarr_main_db_name; - $this->output = ""; - $this->result = array("commandbackuplastdone" => "", "commandbackuptorun" => $command." ".$paramcrypted); + $this->output = ""; + $this->result = array("commandbackuplastdone" => "", "commandbackuptorun" => $command." ".$paramcrypted); } // Clean old files if ($keeplastnfiles > 0) { - $tmpfiles = dol_dir_list($conf->admin->dir_output.'/backup', 'files', 0, '', '(\.err|\.old|\.sav)$', 'date', SORT_DESC); - $i=0; - foreach($tmpfiles as $key => $val) - { - $i++; - if ($i <= $keeplastnfiles) continue; - dol_delete_file($val['fullname']); - } + $tmpfiles = dol_dir_list($conf->admin->dir_output.'/backup', 'files', 0, '', '(\.err|\.old|\.sav)$', 'date', SORT_DESC); + $i=0; + foreach($tmpfiles as $key => $val) + { + $i++; + if ($i <= $keeplastnfiles) continue; + dol_delete_file($val['fullname']); + } } @@ -523,4 +523,149 @@ class Utils return array('result'=>$result, 'output'=>$output, 'error'=>$error); } + /** + * Generate documentation of a Module + * + * @param string $module Module name + * @return int <0 if KO, >0 if OK + */ + function generateDoc($module) + { + global $conf, $langs; + global $dirins; + + $error = 0; + + $modulelowercase=strtolower($module); + + // Dir for module + $dir = $dirins.'/'.$modulelowercase; + // Zip file to build + $FILENAMEDOC=''; + + // Load module + dol_include_once($modulelowercase.'/core/modules/mod'.$module.'.class.php'); + $class='mod'.$module; + + if (class_exists($class)) + { + try { + $moduleobj = new $class($this->db); + } + catch(Exception $e) + { + $error++; + dol_print_error($e->getMessage()); + } + } + else + { + $error++; + $langs->load("errors"); + dol_print_error($langs->trans("ErrorFailedToLoadModuleDescriptorForXXX", $module)); + exit; + } + + $arrayversion=explode('.',$moduleobj->version,3); + if (count($arrayversion)) + { + $FILENAMEASCII=strtolower($module).'.asciidoc'; + $FILENAMEDOC=strtolower($module).'.html'; // TODO Use/text PDF + + $dirofmodule = dol_buildpath(strtolower($module), 0).'/doc'; + $dirofmoduletmp = dol_buildpath(strtolower($module), 0).'/doc/temp'; + $outputfiledoc = $dirofmodule.'/'.$FILENAMEDOC; + if ($dirofmodule) + { + if (! dol_is_dir($dirofmodule)) dol_mkdir($dirofmodule); + if (! dol_is_dir($dirofmoduletmp)) dol_mkdir($dirofmoduletmp); + if (! is_writable($dirofmoduletmp)) + { + $this->error = 'Dir '.$dirofmoduletmp.' does not exists or is not writable'; + return -1; + } + + $destfile=$dirofmoduletmp.'/'.$FILENAMEASCII; + + $fhandle = fopen($destfile, 'w+'); + if ($fhandle) + { + $specs=dol_dir_list(dol_buildpath(strtolower($module).'/doc', 0), 'files', 1, '(\.md|\.asciidoc)$', array('\/temp\/')); + + $i = 0; + foreach ($specs as $spec) + { + if (preg_match('/notindoc/', $spec['relativename'])) continue; // Discard file + if (preg_match('/disabled/', $spec['relativename'])) continue; // Discard file + + $pathtofile = strtolower($module).'/doc/'.$spec['relativename']; + $format='asciidoc'; + if (preg_match('/\.md$/i', $spec['name'])) $format='markdown'; + + $filecursor = @file_get_contents($spec['fullname']); + if ($filecursor) + { + fwrite($fhandle, ($i ? "\n<<<\n\n" : "").$filecursor."\n"); + } + else + { + $this->error = 'Failed to concat content of file '.$spec['fullname']; + return -1; + } + + $i++; + } + + fwrite($fhandle, "\n\n\n== DATA SPECIFICATIONS...\n\n"); + + // TODO + fwrite($fhandle, "TODO..."); + + fclose($fhandle); + } + + $conf->global->MODULEBUILDER_ASCIIDOCTOR='asciidoctor'; + if (empty($conf->global->MODULEBUILDER_ASCIIDOCTOR)) + { + dol_print_error('', 'Module setup not complete'); + exit; + } + + $command=$conf->global->MODULEBUILDER_ASCIIDOCTOR.' '.$destfile.' -n -o '.$dirofmodule.'/'.$FILENAMEDOC; + $outfile=$dirofmoduletmp.'/out.tmp'; + + require_once DOL_DOCUMENT_ROOT.'/core/class/utils.class.php'; + $utils = new Utils($db); + $resarray = $utils->executeCLI($command, $outfile); + if ($resarray['result'] != '0') + { + $this->error = $resarray['error'].' '.$resarray['output']; + } + $result = ($resarray['result'] == 0) ? 1 : 0; + } + else + { + $result = 0; + } + + if ($result > 0) + { + return 1; + } + else + { + $error++; + $langs->load("errors"); + $this->error = $langs->trans("ErrorFailToGenerateFile", $outputfiledoc); + } + } + else + { + $error++; + $langs->load("errors"); + $this->error = $langs->trans("ErrorCheckVersionIsDefined"); + } + + return -1; + } } diff --git a/htdocs/core/db/Database.interface.php b/htdocs/core/db/Database.interface.php index 28623f780a5..65699585f4a 100644 --- a/htdocs/core/db/Database.interface.php +++ b/htdocs/core/db/Database.interface.php @@ -280,7 +280,7 @@ interface Database /** * Create a table into database * - * @param string $table Nom de la table + * @param string $table Name of table * @param array $fields Tableau associatif [nom champ][tableau des descriptions] * @param string $primary_key Nom du champ qui sera la clef primaire * @param string $type Type de la table @@ -291,6 +291,14 @@ interface Database */ function DDLCreateTable($table, $fields, $primary_key, $type, $unique_keys = null, $fulltext_keys = null, $keys = null); + /** + * Drop a table into database + * + * @param string $table Name of table + * @return int <0 if KO, >=0 if OK + */ + function DDLDropTable($table); + /** * Return list of available charset that can be used to store data in database * diff --git a/htdocs/core/db/DoliDB.class.php b/htdocs/core/db/DoliDB.class.php index fa87fb3a4d6..64f84471e40 100644 --- a/htdocs/core/db/DoliDB.class.php +++ b/htdocs/core/db/DoliDB.class.php @@ -220,9 +220,9 @@ abstract class DoliDB implements Database /** * Define sort criteria of request * - * @param string $sortfield List of sort fields, separated by comma. Example: 't1.fielda, t2.fieldb' - * @param 'ASC'|'DESC' $sortorder Sort order - * @return string String to provide syntax of a sort sql string + * @param string $sortfield List of sort fields, separated by comma. Example: 't1.fielda, t2.fieldb' + * @param string $sortorder Sort order, separated by comma. Example: 'ASC, DESC'; + * @return string String to provide syntax of a sort sql string */ function order($sortfield=null,$sortorder=null) { diff --git a/htdocs/core/db/mssql.class.php b/htdocs/core/db/mssql.class.php index 97c72160d76..79a0e212dfc 100644 --- a/htdocs/core/db/mssql.class.php +++ b/htdocs/core/db/mssql.class.php @@ -863,6 +863,22 @@ class DoliDBMssql extends DoliDB return 1; } + /** + * Drop a table into database + * + * @param string $table Name of table + * @return int <0 if KO, >=0 if OK + */ + function DDLDropTable($table) + { + $sql = "DROP TABLE ".$table; + + if (! $this->query($sql)) + return -1; + else + return 1; + } + /** * Return a pointer of line with description of a table or field * diff --git a/htdocs/core/db/mysqli.class.php b/htdocs/core/db/mysqli.class.php index 4206e75a165..7721ebb975d 100644 --- a/htdocs/core/db/mysqli.class.php +++ b/htdocs/core/db/mysqli.class.php @@ -109,12 +109,17 @@ class DoliDBMysqli extends DoliDB $this->database_name = $name; $this->ok = true; - // If client connected with different charset than Dolibarr HTML output - $clientmustbe=''; - if (preg_match('/UTF-8/i',$conf->file->character_set_client)) $clientmustbe='utf8'; - if (preg_match('/ISO-8859-1/i',$conf->file->character_set_client)) $clientmustbe='latin1'; + // If client is old latin, we force utf8 + $clientmustbe=empty($conf->db->dolibarr_main_db_character_set)?'utf8':$conf->db->dolibarr_main_db_character_set; + if (preg_match('/latin1/', $clientmustbe)) $clientmustbe='utf8'; + if ($this->db->character_set_name() != $clientmustbe) { - $this->db->set_charset($clientmustbe); + $this->db->set_charset($clientmustbe); // This set charset, but with a bad collation + + $collation = $conf->db->dolibarr_main_db_collation; + if (preg_match('/latin1/', $collation)) $collation='utf8_unicode_ci'; + + if (! preg_match('/general/', $collation)) $this->db->query("SET collation_connection = ".$collation); } } else @@ -133,14 +138,19 @@ class DoliDBMysqli extends DoliDB if ($this->connected) { - // If client connected with different charset than Dolibarr HTML output - $clientmustbe=''; - if (preg_match('/UTF-8/i',$conf->file->character_set_client)) $clientmustbe='utf8'; - if (preg_match('/ISO-8859-1/i',$conf->file->character_set_client)) $clientmustbe='latin1'; + // If client is old latin, we force utf8 + $clientmustbe=empty($conf->db->dolibarr_main_db_character_set)?'utf8':$conf->db->dolibarr_main_db_character_set; + if (preg_match('/latin1/', $clientmustbe)) $clientmustbe='utf8'; + if ($this->db->character_set_name() != $clientmustbe) { - $this->db->set_charset($clientmustbe); + $this->db->set_charset($clientmustbe); // This set utf8_general_ci + + $collation = $conf->db->dolibarr_main_db_collation; + if (preg_match('/latin1/', $collation)) $collation='utf8_unicode_ci'; + + if (! preg_match('/general/', $collation)) $this->db->query("SET collation_connection = ".$collation); } - } + } } } @@ -629,7 +639,7 @@ class DoliDBMysqli extends DoliDB /** * Create a table into database * - * @param string $table Nom de la table + * @param string $table Name of table * @param array $fields Tableau associatif [nom champ][tableau des descriptions] * @param string $primary_key Nom du champ qui sera la clef primaire * @param string $type Type de la table @@ -702,13 +712,28 @@ class DoliDBMysqli extends DoliDB $sql .= ",".implode(',',$sqlk); $sql .=") engine=".$type; - dol_syslog($sql,LOG_DEBUG); - if(! $this -> query($sql)) + if(! $this->query($sql)) return -1; else return 1; } + /** + * Drop a table into database + * + * @param string $table Name of table + * @return int <0 if KO, >=0 if OK + */ + function DDLDropTable($table) + { + $sql = "DROP TABLE ".$table; + + if (! $this->query($sql)) + return -1; + else + return 1; + } + /** * Return a pointer of line with description of a table or field * diff --git a/htdocs/core/db/pgsql.class.php b/htdocs/core/db/pgsql.class.php index f0c437e0b96..1ba8f183cbb 100644 --- a/htdocs/core/db/pgsql.class.php +++ b/htdocs/core/db/pgsql.class.php @@ -999,6 +999,22 @@ class DoliDBPgsql extends DoliDB return 1; } + /** + * Drop a table into database + * + * @param string $table Name of table + * @return int <0 if KO, >=0 if OK + */ + function DDLDropTable($table) + { + $sql = "DROP TABLE ".$table; + + if (! $this->query($sql)) + return -1; + else + return 1; + } + /** * Create a user to connect to database * diff --git a/htdocs/core/db/sqlite3.class.php b/htdocs/core/db/sqlite3.class.php index 2c52092b9c9..78762f282b4 100644 --- a/htdocs/core/db/sqlite3.class.php +++ b/htdocs/core/db/sqlite3.class.php @@ -945,6 +945,22 @@ class DoliDBSqlite3 extends DoliDB return 1; } + /** + * Drop a table into database + * + * @param string $table Name of table + * @return int <0 if KO, >=0 if OK + */ + function DDLDropTable($table) + { + $sql = "DROP TABLE ".$table; + + if (! $this->query($sql)) + return -1; + else + return 1; + } + /** * Return a pointer of line with description of a table or field * diff --git a/htdocs/core/get_menudiv.php b/htdocs/core/get_menudiv.php index 451747b4a6e..3ff299fa00c 100644 --- a/htdocs/core/get_menudiv.php +++ b/htdocs/core/get_menudiv.php @@ -105,7 +105,8 @@ print ' li.lilevel1 { padding: 1em 15px 0.5em 40px; border-top: 1px solid #aaa; - margin-right: 20px; + margin-right: 0px; + margin-left: 0px; border-right: 0px ! important; } li.lilevel1:first-child { @@ -121,17 +122,29 @@ print ' display: block; } li.lilevel2 a { - padding: 0 15px 0.5em 40px; + padding: 0.7em 15px 0.7em 40px; color: #000; cursor: pointer; display: block; } li.lilevel3 a { + padding: 0.2em 15px 0.2em 60px; + color: #000; + cursor: pointer; + display: block; + } + li.lilevel4 a { padding: 0.2em 15px 8px 60px; color: #000; cursor: pointer; display: block; } + li.lilevel5 a { + padding: 0.2em 15px 0.2em 60px; + color: #000; + cursor: pointer; + display: block; + } li.lilevel3:last-child { padding-bottom: 10px; } diff --git a/htdocs/core/js/jnotify.js b/htdocs/core/js/jnotify.js deleted file mode 100644 index 088e106177d..00000000000 --- a/htdocs/core/js/jnotify.js +++ /dev/null @@ -1,41 +0,0 @@ -// Copyright (C) 2011 Regis Houssin -// Copyright (C) 2009 Laurent Destailleur -// -// 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 -// the Free Software Foundation; either version 3 of the License, or -// (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program. If not, see . -// or see http://www.gnu.org/ -// - -// -// \file htdocs/core/js/jnotify.js -// \brief File that include javascript functions for jnotify default options -// - -$(document).ready(function() { - $.jnotify.setup({ - delay: 3000 // the default time to show each notification (in milliseconds) - , sticky: false // determines if the message should be considered "sticky" (user must manually close notification) - , closeLabel: "×" // the HTML to use for the "Close" link - , showClose: true // determines if the "Close" link should be shown if notification is also sticky - , fadeSpeed: 1000 // the speed to fade messages out (in milliseconds) - , slideSpeed: 250 // the speed used to slide messages out (in milliseconds) - , classContainer: "jnotify-container" - , classNotification: "jnotify-notification" - , classBackground: "jnotify-background" - , classClose: "jnotify-close" - , classMessage: "jnotify-message" - , init: null // callback that occurs when the main jnotify container is created - , create: null // callback that occurs when when the note is created (occurs just before appearing in DOM) - , beforeRemove: null // callback that occurs when before the notification starts to fade away - }); -}); \ No newline at end of file diff --git a/htdocs/core/js/lib_foot.js.php b/htdocs/core/js/lib_foot.js.php index f9ee9ea3ad4..68d183e1573 100644 --- a/htdocs/core/js/lib_foot.js.php +++ b/htdocs/core/js/lib_foot.js.php @@ -44,6 +44,7 @@ else header('Cache-Control: no-cache'); //var_dump($conf); + // Wrapper to show tooltips (html or onclick popup) if (empty($conf->dol_no_mouse_hover)) { @@ -107,7 +108,7 @@ if (! defined('JS_JQUERY_DISABLE_DROPDOWN')) }); $(document).bind(\'click\', function (e) { - // TODO Use a bind on elements in dropdown only to avoid to bind/code all clicks + //console.log("We click outside of dropdown, so we close it."); var $clicked = $(e.target); if (!$clicked.parents().hasClass("dropdown")) $(".dropdown dd ul").hide(); }); diff --git a/htdocs/core/js/lib_head.js.php b/htdocs/core/js/lib_head.js.php index 8b8dd3d8a57..15dbc62ffa7 100644 --- a/htdocs/core/js/lib_head.js.php +++ b/htdocs/core/js/lib_head.js.php @@ -19,8 +19,9 @@ */ /** - * \file htdocs/core/js/lib_head.js.php - * \brief File that include javascript functions (included if option use_javascript activated) + * \file htdocs/core/js/lib_head.js.php + * \brief File that include javascript functions (included if option use_javascript activated) + * JQuery (providing object $) and JQuery-UI (providing $datepicker) libraries must be loaded before this file. */ //if (! defined('NOREQUIREUSER')) define('NOREQUIREUSER','1'); // Not disabled cause need to load personalized language @@ -919,8 +920,8 @@ function document_preview(file, type, title) if (mode == 'image' && showOriginalSizeButton) { optionsbuttons = { - "trans("OriginalSize")); ?>": function() { console.log("Click on original size"); jQuery(".ui-dialog-content.ui-widget-content > object").css({ "max-height": "none" }); }, - "trans("Close")); ?>": function() { $( this ).dialog( "close" ); } + "transnoentitiesnoconv("OriginalSize")); ?>": function() { console.log("Click on original size"); jQuery(".ui-dialog-content.ui-widget-content > object").css({ "max-height": "none" }); }, + "transnoentitiesnoconv("Close")); ?>": function() { $( this ).dialog( "close" ); } }; } @@ -1062,3 +1063,31 @@ function price2numjs(amount) { } +global->MAIN_DISABLE_JQUERY_JNOTIFY) && ! defined('DISABLE_JQUERY_JNOTIFY')) { +?> +// Defined properties for JNotify +$(document).ready(function() { + if (typeof $.jnotify == 'function') + { + $.jnotify.setup({ + delay: 3000 // the default time to show each notification (in milliseconds) + , sticky: false // determines if the message should be considered "sticky" (user must manually close notification) + , closeLabel: "×" // the HTML to use for the "Close" link + , showClose: true // determines if the "Close" link should be shown if notification is also sticky + , fadeSpeed: 1000 // the speed to fade messages out (in milliseconds) + , slideSpeed: 250 // the speed used to slide messages out (in milliseconds) + , classContainer: "jnotify-container" + , classNotification: "jnotify-notification" + , classBackground: "jnotify-background" + , classClose: "jnotify-close" + , classMessage: "jnotify-message" + , init: null // callback that occurs when the main jnotify container is created + , create: null // callback that occurs when when the note is created (occurs just before appearing in DOM) + , beforeRemove: null // callback that occurs when before the notification starts to fade away + }); + } +}); + + +// End of lib_head.js.php diff --git a/htdocs/core/js/timesheet.js b/htdocs/core/js/timesheet.js index a55424f8e8c..ba3f8b2edd1 100644 --- a/htdocs/core/js/timesheet.js +++ b/htdocs/core/js/timesheet.js @@ -113,15 +113,15 @@ function parseTime(timeStr, dt) function updateTotal(days,mode) { console.log('updateTotal days='+days+' mode='+mode); - if(mode=="hours") + if (mode=="hours") { var total = new Date(0); total.setHours(0); total.setMinutes(0); var nbline = document.getElementById('numberOfLines').value; - for (var i=0;igetVersionArray(); @@ -1132,6 +1132,71 @@ function complete_dictionary_with_modules(&$taborder,&$tabname,&$tablib,&$tabsql return 1; } +/** + * Activate external modules mandatroy when country is country_code + * + * @param string $country_code CountryCode + * @return int 1 + */ +function activateModulesRequiredByCountry($country_code) +{ + global $db, $conf, $langs; + + $modulesdir = dolGetModulesDirs(); + + foreach ($modulesdir as $dir) + { + // Load modules attributes in arrays (name, numero, orders) from dir directory + dol_syslog("Scan directory ".$dir." for modules"); + $handle=@opendir(dol_osencode($dir)); + if (is_resource($handle)) + { + while (($file = readdir($handle))!==false) + { + if (is_readable($dir.$file) && substr($file, 0, 3) == 'mod' && substr($file, dol_strlen($file) - 10) == '.class.php') + { + $modName = substr($file, 0, dol_strlen($file) - 10); + + if ($modName) + { + include_once $dir.$file; + $objMod = new $modName($db); + + $modulequalified=1; + + // We discard modules according to features level (PS: if module is activated we always show it) + $const_name = 'MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i','',get_class($objMod))); + + if ($objMod->version == 'development' && $conf->global->MAIN_FEATURES_LEVEL < 2) $modulequalified=0; + if ($objMod->version == 'experimental' && $conf->global->MAIN_FEATURES_LEVEL < 1) $modulequalified=0; + if(!empty($conf->global->$const_name)) $modulequalified=0; // already activated + + if ($modulequalified) + { + // Load languages files of module + if (isset($objMod->automatic_activation) && is_array($objMod->automatic_activation) && isset($objMod->automatic_activation[$country_code])) + { + activateModule($modName); + + setEventMessage($objMod->automatic_activation[$country_code],'warnings'); + } + + } + else dol_syslog("Module ".get_class($objMod)." not qualified"); + } + } + } + closedir($handle); + } + else + { + dol_syslog("htdocs/admin/modules.php: Failed to open directory ".$dir.". See permission and open_basedir option.", LOG_WARNING); + } + } + + return 1; +} + /** * Add external modules to list of contact element * @@ -1560,7 +1625,7 @@ function email_admin_prepare_head() $head[$h][2] = 'templates'; $h++; - if ($conf->global->MAIN_FEATURES_LEVEL >= 2) + if ($conf->global->MAIN_FEATURES_LEVEL >= 1) { $head[$h][0] = DOL_URL_ROOT."/admin/mails_senderprofile_list.php"; $head[$h][1] = $langs->trans("EmailSenderProfiles"); diff --git a/htdocs/core/lib/agenda.lib.php b/htdocs/core/lib/agenda.lib.php index 526e6386f0f..730dce5e56a 100644 --- a/htdocs/core/lib/agenda.lib.php +++ b/htdocs/core/lib/agenda.lib.php @@ -58,7 +58,7 @@ function print_actions_filter($form, $canedit, $status, $year, $month, $day, $sh $formactions=new FormActions($db); // Filters - print '
    '; + //print ''; print ''; print ''; print ''; @@ -199,7 +199,7 @@ function print_actions_filter($form, $canedit, $status, $year, $month, $day, $sh print ''; // Close fichecenter print '
    '; - print ''; + //print ''; } @@ -239,7 +239,7 @@ function show_array_actions_to_do($max=5) print '
    '; //$out.='
    '; @@ -416,18 +417,26 @@ class FormMail extends Form //$out.='
    '; } + /*var_dump(! empty($this->withfromreadonly)); + var_dump($this->withfrom); + var_dump($this->fromtype); + var_dump($this->fromname);*/ + // From if (! empty($this->withfrom)) { if (! empty($this->withfromreadonly)) { - $out.= '
    '.$langs->trans("MailFrom").''; + $out.= '
    '.$langs->trans("MailFrom").''; + // $this->fromtype is the default value to use to select sender if (! ($this->fromtype === 'user' && $this->fromid > 0) && ! ($this->fromtype === 'company') + && ! ($this->fromtype === 'robot') && ! preg_match('/user_aliases/', $this->fromtype) && ! preg_match('/global_aliases/', $this->fromtype) - && ! preg_match('/senderprofile/', $this->fromtype)) + && ! preg_match('/senderprofile/', $this->fromtype) + ) { // Use this->fromname and this->frommail or error if not defined $out.= $this->fromname; @@ -463,6 +472,19 @@ class FormMail extends Form // Add also email aliases if there is some $listaliases=array('user_aliases'=>$user->email_aliases, 'global_aliases'=>$conf->global->MAIN_INFO_SOCIETE_MAIL_ALIASES); + // Also add robot email + if (! empty($this->fromalsorobot)) + { + if (! empty($conf->global->MAIN_MAIL_EMAIL_FROM) && $conf->global->MAIN_MAIL_EMAIL_FROM != $conf->global->MAIN_INFO_SOCIETE_MAIL) + { + $liste['robot'] = $conf->global->MAIN_MAIL_EMAIL_FROM; + if ($this->frommail) + { + $liste['robot'] .= ' <'.$conf->global->MAIN_MAIL_EMAIL_FROM.'>'; + } + } + } + // Add also email aliases from the c_email_senderprofile table $sql='SELECT rowid, label, email FROM '.MAIN_DB_PREFIX.'c_email_senderprofile WHERE active = 1 ORDER BY position'; $resql = $this->db->query($sql); @@ -499,18 +521,29 @@ class FormMail extends Form } } } - $out.= ' '.$form->selectarray('fromtype', $liste, $this->fromtype, 0, 0, 0, '', 0, 0, 0, '', '', 0, '', $disablebademails); - //$out.= ajax_combobox('fromtype'); + + // Set the default "From" + $defaultfrom=''; + $reshook=$hookmanager->executeHooks('getDefaultFromEmail', $parameters, $this); + if (empty($reshook)) + { + $defaultfrom = $this->fromtype; + } + if (! empty($hookmanager->resArray['defaultfrom'])) $defaultfrom=$hookmanager->resArray['defaultfrom']; + + // Using combo here make the '' no more visible on list. + //$out.= ' '.$form->selectarray('fromtype', $liste, $this->fromtype, 0, 0, 0, '', 0, 0, 0, '', 'fromforsendingprofile maxwidth200onsmartphone', 1, '', $disablebademails); + $out.= ' '.$form->selectarray('fromtype', $liste, $defaultfrom, 0, 0, 0, '', 0, 0, 0, '', 'fromforsendingprofile maxwidth200onsmartphone', 0, '', $disablebademails); } $out.= "
    '.$langs->trans("MailFrom").""; - $out.= $langs->trans("Name").':'; + $out.= '
    '.$langs->trans("MailFrom").""; + $out.= $langs->trans("Name").':'; $out.= '    '; - $out.= $langs->trans("EMail").':<>'; + $out.= $langs->trans("EMail").':<>'; $out.= "
    '; + $out.= '
    '; if ($this->withtofree) $out.= $form->textwithpicto($langs->trans("MailTo"),$langs->trans("YouCanUseCommaSeparatorForSeveralRecipients")); else $out.= $langs->trans("MailTo"); $out.= ''; @@ -547,7 +580,7 @@ class FormMail extends Form $out.= ' <'.$this->tomail.'>'; if ($this->withtofree) { - $out.= '
    '.$langs->trans("and").' withto) :"").'" />'; + $out.= '
    '.$langs->trans("and").' withto) :"").'" />'; } } else @@ -560,7 +593,7 @@ class FormMail extends Form { if (! empty($this->withtofree)) { - $out.= 'withto) :"").'" />'; + $out.= 'withto) :"").'" />'; } if (! empty($this->withto) && is_array($this->withto)) { @@ -585,12 +618,15 @@ class FormMail extends Form // withoptiononeemailperrecipient if (! empty($this->withoptiononeemailperrecipient)) { - $out.= '
    '; + $out.= '
    '; $out.= $langs->trans("GroupEmails"); $out.= ''; $out.=' withoptiononeemailperrecipient > 0?' checked="checked"':'').'> '; - $out.= $langs->trans("OneEmailPerRecipient").' - '; + $out.= $langs->trans("OneEmailPerRecipient"); + $out.=''; + $out.=' - '; $out.= $langs->trans("WarningIfYouCheckOneRecipientPerEmail"); + $out.=''; $out.= '
    '; print ''; - print ''; + print ''; print ''; $var = true; @@ -336,7 +336,7 @@ function show_array_last_actions_done($max=5) print '
    '.$langs->trans("LastActionsToDo",$max).''.$langs->trans("FullList").''.$langs->trans("FullList").'
    '; print ''; - print ''; + print ''; print ''; $var = true; $i = 0; @@ -514,14 +514,14 @@ function calendars_prepare_head($param) $h = 0; $head = array(); - $head[$h][0] = DOL_URL_ROOT.'/comm/action/listactions.php'.($param?'?'.$param:''); + $head[$h][0] = DOL_URL_ROOT.'/comm/action/list.php'.($param?'?'.$param:''); $head[$h][1] = $langs->trans("ViewList"); $head[$h][2] = 'cardlist'; $h++; - $head[$h][0] = DOL_URL_ROOT.'/comm/action/index.php?action=show_day'.($param?'&'.$param:''); - $head[$h][1] = $langs->trans("ViewDay"); - $head[$h][2] = 'cardday'; + $head[$h][0] = DOL_URL_ROOT.'/comm/action/index.php?action=show_month'.($param?'&'.$param:''); + $head[$h][1] = $langs->trans("ViewCal"); + $head[$h][2] = 'cardmonth'; $h++; $head[$h][0] = DOL_URL_ROOT.'/comm/action/index.php?action=show_week'.($param?'&'.$param:''); @@ -529,9 +529,9 @@ function calendars_prepare_head($param) $head[$h][2] = 'cardweek'; $h++; - $head[$h][0] = DOL_URL_ROOT.'/comm/action/index.php?action=show_month'.($param?'&'.$param:''); - $head[$h][1] = $langs->trans("ViewCal"); - $head[$h][2] = 'cardmonth'; + $head[$h][0] = DOL_URL_ROOT.'/comm/action/index.php?action=show_day'.($param?'&'.$param:''); + $head[$h][1] = $langs->trans("ViewDay"); + $head[$h][2] = 'cardday'; $h++; //if (! empty($conf->global->AGENDA_USE_EVENT_TYPE)) diff --git a/htdocs/core/lib/ajax.lib.php b/htdocs/core/lib/ajax.lib.php index 711602b8503..102f8a0037f 100644 --- a/htdocs/core/lib/ajax.lib.php +++ b/htdocs/core/lib/ajax.lib.php @@ -417,7 +417,7 @@ function ajax_combobox($htmlname, $events=array(), $minLengthToAutocomplete=0, $ /* Code to add class of origin OPTION propagated to the new select2
  • tag */ if (data.element) { $(container).addClass($(data.element).attr("class")); } //console.log(data.html); - if ($(data.element).attr("html") != undefined) return htmlEntityDecodeJs($(data.element).attr("html")); // If property html set, we decode html entities and use this + if ($(data.element).attr("data-html") != undefined) return htmlEntityDecodeJs($(data.element).attr("data-html")); // If property html set, we decode html entities and use this return data.text; }, templateSelection: function (selection) { /* Format visible output of selected value */ diff --git a/htdocs/core/lib/bank.lib.php b/htdocs/core/lib/bank.lib.php index 28f97bd1805..5e1e300520c 100644 --- a/htdocs/core/lib/bank.lib.php +++ b/htdocs/core/lib/bank.lib.php @@ -67,8 +67,24 @@ function bank_prepare_head(Account $object) if ($object->courant != Account::TYPE_CASH) { + $nbReceipts=0; + + // List of all standing receipts + $sql = "SELECT COUNT(DISTINCT(b.num_releve)) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."bank as b"; + $sql.= " WHERE b.fk_account = ".$object->id; + + $resql = $db->query($sql); + if ($resql) + { + $obj = $db->fetch_object($resql); + if ($obj) $nbReceipts = $obj->nb; + $db->free($resql); + } + $head[$h][0] = DOL_URL_ROOT."/compta/bank/releve.php?account=".$object->id; $head[$h][1] = $langs->trans("AccountStatements"); + if (($nbReceipts) > 0) $head[$h][1].= ' '.($nbReceipts).''; $head[$h][2] = 'statement'; $h++; } diff --git a/htdocs/core/lib/barcode.lib.php b/htdocs/core/lib/barcode.lib.php index b0849bb913e..13956f688aa 100644 --- a/htdocs/core/lib/barcode.lib.php +++ b/htdocs/core/lib/barcode.lib.php @@ -27,9 +27,9 @@ /* ******************************************************************** */ /* COLORS */ /* ******************************************************************** */ -$bar_color=Array(0,0,0); -$bg_color=Array(255,255,255); -$text_color=Array(0,0,0); +$bar_color=array(0,0,0); +$bg_color=array(255,255,255); +$text_color=array(0,0,0); /* ******************************************************************** */ diff --git a/htdocs/core/lib/company.lib.php b/htdocs/core/lib/company.lib.php index ac98fa599a9..bf8433cb5d6 100644 --- a/htdocs/core/lib/company.lib.php +++ b/htdocs/core/lib/company.lib.php @@ -632,9 +632,10 @@ function isInEEC($object) * @param Object $object Third party object * @param string $backtopage Url to go once contact is created * @param int $nocreatelink 1=Hide create project link + * @param string $morehtmlright More html on right of title * @return void */ -function show_projects($conf, $langs, $db, $object, $backtopage='', $nocreatelink=0) +function show_projects($conf, $langs, $db, $object, $backtopage='', $nocreatelink=0, $morehtmlright='') { global $user; global $bc; @@ -655,7 +656,7 @@ function show_projects($conf, $langs, $db, $object, $backtopage='', $nocreatelin } print "\n"; - print load_fiche_titre($langs->trans("ProjectsDedicatedToThisThirdParty"),$buttoncreate,''); + print load_fiche_titre($langs->trans("ProjectsDedicatedToThisThirdParty"), $buttoncreate.$morehtmlright, ''); print '
    '; print "\n".'
  • '.$langs->trans("LastDoneTasks",$max).''.$langs->trans("FullList").''.$langs->trans("FullList").'
    '; @@ -803,23 +804,22 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') { $addcontact = (! empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("AddContact") : $langs->trans("AddContactAddress")); $buttoncreate=''.$addcontact; - if (empty($conf->dol_optimize_smallscreen)) $buttoncreate.=' '.img_picto($addcontact,'filenew'); $buttoncreate.=''."\n"; } print "\n"; $title = (! empty($conf->global->SOCIETE_ADDRESSES_MANAGEMENT) ? $langs->trans("ContactsForCompany") : $langs->trans("ContactsAddressesForCompany")); - print load_fiche_titre($title,$buttoncreate,''); + print load_fiche_titre($title, $buttoncreate,''); - print ''; + print ''; print ''; print ''; print ''; print ''; - print '
    '; // You can use div-table-responsive-no-min if you dont need reserved height for your table + print '
    '; // You can use div-table-responsive-no-min if you dont need reserved height for your table print "\n".'
    '."\n"; $param="socid=".$object->id; @@ -842,48 +842,48 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') $colspan=9; - if ($num || (GETPOST('button_search','alpha') || GETPOST('button_search.x','alpha') || GETPOST('button_search_x','alpha'))) - { - print ''; + print ''; - // Photo - Name - print ''; + // Photo - Name + print ''; - // Position - print ''; + // Position + print ''; - // Address - Phone - Email - print ''; + // Address - Phone - Email + print ''; - // Status - print ''; + // Status + print ''; - // Add to agenda - if (! empty($conf->agenda->enabled) && $user->rights->agenda->myactions->create) - { - $colspan++; - print ''; - } + // Add to agenda + if (! empty($conf->agenda->enabled) && $user->rights->agenda->myactions->create) + { + $colspan++; + print ''; + } - // Action - print ''; + // Action + print ''; - print ""; - } + print ""; + + $titlefieldaddress=$langs->trans("Address").' / '.$langs->trans("Phone").' / '.$langs->trans("Email"); + if (! empty($conf->dol_optimize_smallscreen)) $titlefieldaddress=$langs->trans("Address"); print ''; print_liste_field_titre("Name",$_SERVER["PHP_SELF"],"p.lastname","",$param,'',$sortfield,$sortorder); print_liste_field_titre("Poste",$_SERVER["PHP_SELF"],"p.poste","",$param,'',$sortfield,$sortorder); - print_liste_field_titre( $langs->trans("Address").' / '.$langs->trans("Phone").' / '.$langs->trans("Email"),$_SERVER["PHP_SELF"],"","",$param,'',$sortfield,$sortorder); - print_liste_field_titre("Status",$_SERVER["PHP_SELF"],"p.statut","",$param,'',$sortfield,$sortorder); + print_liste_field_titre($titlefieldaddress,$_SERVER["PHP_SELF"],"","",$param,'',$sortfield,$sortorder); + print_liste_field_titre("Status",$_SERVER["PHP_SELF"],"p.statut","",$param,'align="center"',$sortfield,$sortorder); // Add to agenda if (! empty($conf->agenda->enabled) && ! empty($user->rights->agenda->myactions->create)) print_liste_field_titre(''); // Edit @@ -941,7 +941,7 @@ function show_contacts($conf,$langs,$db,$object,$backtopage='') print ''; // Status - print ''; + print ''; // Add to agenda if (! empty($conf->agenda->enabled) && $user->rights->agenda->myactions->create) @@ -1099,7 +1099,7 @@ function show_actions_todo($conf,$langs,$db,$filterobj,$objcon='',$noprint=0,$ac * @param Conf $conf Object conf * @param Translate $langs Object langs * @param DoliDB $db Object db - * @param Adherent|Societe|Project $filterobj Object third party or member or project + * @param mixed $filterobj Object Adherent|Societe|Project|Product|CommandeFournisseur * @param Contact $objcon Object contact * @param int $noprint Return string but does not output it * @param string $actioncode Filter on actioncode @@ -1139,11 +1139,13 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= if (is_object($filterobj) && get_class($filterobj) == 'Societe') $sql.= ", sp.lastname, sp.firstname"; if (is_object($filterobj) && get_class($filterobj) == 'Adherent') $sql.= ", m.lastname, m.firstname"; if (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur') $sql.= ", o.ref"; + if (is_object($filterobj) && get_class($filterobj) == 'Product') $sql.= ", o.ref"; $sql.= " FROM ".MAIN_DB_PREFIX."user as u, ".MAIN_DB_PREFIX."actioncomm as a"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_actioncomm as c ON a.fk_action = c.id"; if (is_object($filterobj) && get_class($filterobj) == 'Societe') $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."socpeople as sp ON a.fk_contact = sp.rowid"; if (is_object($filterobj) && get_class($filterobj) == 'Adherent') $sql.= ", ".MAIN_DB_PREFIX."adherent as m"; if (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur') $sql.= ", ".MAIN_DB_PREFIX."commande_fournisseur as o"; + if (is_object($filterobj) && get_class($filterobj) == 'Product') $sql.= ", ".MAIN_DB_PREFIX."product as o"; $sql.= " WHERE u.rowid = a.fk_user_action"; $sql.= " AND a.entity IN (".getEntity('agenda').")"; if (is_object($filterobj) && get_class($filterobj) == 'Societe' && $filterobj->id) $sql.= " AND a.fk_soc = ".$filterobj->id; @@ -1155,8 +1157,13 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= } if (is_object($filterobj) && get_class($filterobj) == 'CommandeFournisseur') { - $sql.= " AND a.fk_element = o.rowid AND a.elementtype = 'order_supplier'"; - if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id; + $sql.= " AND a.fk_element = o.rowid AND a.elementtype = 'order_supplier'"; + if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id; + } + if (is_object($filterobj) && get_class($filterobj) == 'Product') + { + $sql.= " AND a.fk_element = o.rowid AND a.elementtype = 'product'"; + if ($filterobj->id) $sql.= " AND a.fk_element = ".$filterobj->id; } if (is_object($objcon) && $objcon->id) $sql.= " AND a.fk_contact = ".$objcon->id; // Condition on actioncode @@ -1355,7 +1362,7 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= if ($donetodo) { $tmp=''; - if (get_class($filterobj) == 'Societe') $tmp.=''; + if (get_class($filterobj) == 'Societe') $tmp.=''; $tmp.=($donetodo != 'done' ? $langs->trans("ActionsToDoShort") : ''); $tmp.=($donetodo != 'done' && $donetodo != 'todo' ? ' / ' : ''); $tmp.=($donetodo != 'todo' ? $langs->trans("ActionsDoneShort") : ''); @@ -1453,10 +1460,10 @@ function show_actions_done($conf, $langs, $db, $filterobj, $objcon='', $noprint= else $out.='-'.dol_print_date($histo[$key]['dateend'],'dayhour'); } $late=0; - if ($histo[$key]['percent'] == 0 && $histo[$key]['datestart'] && $db->jdate($histo[$key]['datestart']) < ($now - $delay_warning)) $late=1; - if ($histo[$key]['percent'] == 0 && ! $histo[$key]['datestart'] && $histo[$key]['dateend'] && $db->jdate($histo[$key]['datestart']) < ($now - $delay_warning)) $late=1; - if ($histo[$key]['percent'] > 0 && $histo[$key]['percent'] < 100 && $histo[$key]['dateend'] && $db->jdate($histo[$key]['dateend']) < ($now - $delay_warning)) $late=1; - if ($histo[$key]['percent'] > 0 && $histo[$key]['percent'] < 100 && ! $histo[$key]['dateend'] && $histo[$key]['datestart'] && $db->jdate($histo[$key]['datestart']) < ($now - $delay_warning)) $late=1; + if ($histo[$key]['percent'] == 0 && $histo[$key]['datestart'] && $histo[$key]['datestart'] < ($now - $delay_warning)) $late=1; + if ($histo[$key]['percent'] == 0 && ! $histo[$key]['datestart'] && $histo[$key]['dateend'] && $histo[$key]['datestart'] < ($now - $delay_warning)) $late=1; + if ($histo[$key]['percent'] > 0 && $histo[$key]['percent'] < 100 && $histo[$key]['dateend'] && $histo[$key]['dateend'] < ($now - $delay_warning)) $late=1; + if ($histo[$key]['percent'] > 0 && $histo[$key]['percent'] < 100 && ! $histo[$key]['dateend'] && $histo[$key]['datestart'] && $histo[$key]['datestart'] < ($now - $delay_warning)) $late=1; if ($late) $out.=img_warning($langs->trans("Late")).' '; $out.="\n"; diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php index c45c5a88e29..44c9c7285cc 100644 --- a/htdocs/core/lib/date.lib.php +++ b/htdocs/core/lib/date.lib.php @@ -706,6 +706,93 @@ function num_public_holiday($timestampStart, $timestampEnd, $countrycode='FR', $ if($jour_semaine == 0 || $jour_semaine == 6) $ferie=true; //Samedi (6) et dimanche (0) } + + if ($countrycode == 'AT') + { + $countryfound=1; + + // Definition des dates feriees fixes + if($jour == 1 && $mois == 1) $ferie=true; // Neujahr + if($jour == 6 && $mois == 1) $ferie=true; // Hl. 3 Koenige + if($jour == 1 && $mois == 5) $ferie=true; // 1. Mai + if($jour == 15 && $mois == 8) $ferie=true; // Mariae Himmelfahrt + if($jour == 26 && $mois == 10) $ferie=true; // 26. Oktober + if($jour == 1 && $mois == 11) $ferie=true; // Allerheiligen + if($jour == 8 && $mois == 12) $ferie=true; // Mariae Empfaengnis + if($jour == 24 && $mois == 12) $ferie=true; // Heilig abend + if($jour == 25 && $mois == 12) $ferie=true; // Christtag + if($jour == 26 && $mois == 12) $ferie=true; // Stefanietag + if($jour == 31 && $mois == 12) $ferie=true; // Silvester + + // Easter calculation + $date_paques = easter_date($annee); + $jour_paques = date("d", $date_paques); + $mois_paques = date("m", $date_paques); + if($jour_paques == $jour && $mois_paques == $mois) $ferie=true; + // Easter sunday + + // Monday after easter + $date_eastermonday = mktime( + date("H", $date_paques), + date("i", $date_paques), + date("s", $date_paques), + date("m", $date_paques), + date("d", $date_paques) + 1, + date("Y", $date_paques) + ); + $jour_eastermonday = date("d", $date_eastermonday); + $mois_eastermonday = date("m", $date_eastermonday); + if($jour_eastermonday == $jour && $mois_eastermonday == $mois) $ferie=true; + // Easter monday + + // Christi Himmelfahrt (39 days after easter sunday) + $date_ch = mktime( + date("H", $date_paques), + date("i", $date_paques), + date("s", $date_paques), + date("m", $date_paques), + date("d", $date_paques) + 39, + date("Y", $date_paques) + ); + $jour_ch = date("d", $date_ch); + $mois_ch = date("m", $date_ch); + if($jour_ch == $jour && $mois_ch == $mois) $ferie=true; + // Christi Himmelfahrt + + // Pfingsten (50 days after easter sunday) + $date_pentecote = mktime( + date("H", $date_paques), + date("i", $date_paques), + date("s", $date_paques), + date("m", $date_paques), + date("d", $date_paques) + 50, + date("Y", $date_paques) + ); + $jour_pentecote = date("d", $date_pentecote); + $mois_pentecote = date("m", $date_pentecote); + if($jour_pentecote == $jour && $mois_pentecote == $mois) $ferie=true; + // Pfingsten + + // Fronleichnam (60 days after easter sunday) + $date_fronleichnam = mktime( + date("H", $date_paques), + date("i", $date_paques), + date("s", $date_paques), + date("m", $date_paques), + date("d", $date_paques) + 60, + date("Y", $date_paques) + ); + $jour_fronleichnam = date("d", $date_fronleichnam); + $mois_fronleichnam = date("m", $date_fronleichnam); + if($jour_fronleichnam == $jour && $mois_fronleichnam == $mois) $ferie=true; + // Fronleichnam + + // Calul des samedis et dimanches + $jour_julien = unixtojd($timestampStart); + $jour_semaine = jddayofweek($jour_julien, 0); + if($jour_semaine == 0 || $jour_semaine == 6) $ferie=true; + //Samedi (6) et dimanche (0) + } // Cas pays non defini if (! $countryfound) diff --git a/htdocs/core/lib/ecm.lib.php b/htdocs/core/lib/ecm.lib.php index 34294f502e8..05f16e767ba 100644 --- a/htdocs/core/lib/ecm.lib.php +++ b/htdocs/core/lib/ecm.lib.php @@ -68,18 +68,30 @@ function ecm_prepare_dasboard_head($object) * Prepare array with list of tabs * * @param object $object Object related to tabs + * @param string $module Module + * @param string $section Section * @return array Array of tabs to show */ -function ecm_prepare_head($object) +function ecm_prepare_head($object, $module='ecm', $section='') { global $langs, $conf, $user; $h = 0; $head = array(); - $head[$h][0] = DOL_URL_ROOT.'/ecm/docmine.php?section='.$object->id; - $head[$h][1] = $langs->trans("Card"); - $head[$h][2] = 'card'; - $h++; + if ($module == 'ecm') + { + $head[$h][0] = DOL_URL_ROOT.'/ecm/dir_card.php?section='.$object->id; + $head[$h][1] = $langs->trans("Card"); + $head[$h][2] = 'card'; + $h++; + } + else + { + $head[$h][0] = DOL_URL_ROOT.'/ecm/dir_card.php?section='.$section.'&module='.$module; + $head[$h][1] = $langs->trans("Card"); + $head[$h][2] = 'card'; + $h++; + } return $head; } @@ -96,7 +108,7 @@ function ecm_file_prepare_head($object) $h = 0; $head = array(); - $head[$h][0] = DOL_URL_ROOT.'/ecm/docfile.php?section='.$object->section_id.'&urlfile='.urlencode($object->label); + $head[$h][0] = DOL_URL_ROOT.'/ecm/file_card.php?section='.$object->section_id.'&urlfile='.urlencode($object->label); $head[$h][1] = $langs->trans("Card"); $head[$h][2] = 'card'; $h++; diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 02e10fbd21a..220a390d577 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -46,7 +46,7 @@ function dol_basename($pathfile) * @param int $recursive Determines whether subdirectories are searched * @param string $filter Regex filter to restrict list. This regex value must be escaped for '/' by doing preg_quote($var,'/'), since this char is used for preg_match function, * but must not contains the start and end '/'. Filter is checked into basename only. - * @param array $excludefilter Array of Regex for exclude filter (example: array('(\.meta|_preview.*\.png)$','^\.')). Exclude is checked into fullpath. + * @param array $excludefilter Array of Regex for exclude filter (example: array('(\.meta|_preview.*\.png)$','^\.')). Exclude is checked both into fullpath and into basename (So '^xxx' may exclude 'xxx/dirscanned/...' and dirscanned/xxx'). * @param string $sortcriteria Sort criteria ('','fullname','relativename','name','date','size') * @param string $sortorder Sort order (SORT_ASC, SORT_DESC) * @param int $mode 0=Return array minimum keys loaded (faster), 1=Force all keys like date and size to be loaded (slower), 2=Force load of date only, 3=Force load of size only @@ -107,6 +107,7 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil while (false !== ($file = readdir($dir))) // $file is always a basename (into directory $newpath) { if (! utf8_check($file)) $file=utf8_encode($file); // To be sure data is stored in utf8 in memory + $fullpathfile=($newpath?$newpath.'/':'').$file; $qualified=1; @@ -120,10 +121,11 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil // Check if file is qualified foreach($excludefilterarray as $filt) { - if (preg_match('/'.$filt.'/i',$file)) { + if (preg_match('/'.$filt.'/i', $file) || preg_match('/'.$filt.'/i', $fullpathfile)) { $qualified=0; break; } } + //print $fullpathfile.' '.$file.' '.$qualified.'
    '; if ($qualified) { @@ -538,7 +540,7 @@ function dol_filemtime($pathoffile) * @param int $newmask Mask for new file (0 by default means $conf->global->MAIN_UMASK). Example: '0666' * @param int $indexdatabase Index new file into database. * @return int <0 if error, 0 if nothing done (dest file already exists), >0 if OK - * @see dolCopyr dolReplaceRegExInFile + * @see dol_copy dolReplaceRegExInFile */ function dolReplaceInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0, $indexdatabase=0) { @@ -608,7 +610,7 @@ function dolReplaceInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0, * @param int $newmask Mask for new file (0 by default means $conf->global->MAIN_UMASK). Example: '0666' * @param int $indexdatabase Index new file into database. * @return int <0 if error, 0 if nothing done (dest file already exists), >0 if OK - * @see dolCopyr dolReplaceInFile + * @see dol_copy dolReplaceInFile */ function dolReplaceRegExInFile($srcfile, $arrayreplacement, $destfile='', $newmask=0, $indexdatabase=0) { @@ -624,7 +626,7 @@ function dolReplaceRegExInFile($srcfile, $arrayreplacement, $destfile='', $newma * @param int $newmask Mask for new file (0 by default means $conf->global->MAIN_UMASK). Example: '0666' * @param int $overwriteifexists Overwrite file if exists (1 by default) * @return int <0 if error, 0 if nothing done (dest file already exists and overwriteifexists=0), >0 if OK - * @see dolCopyr + * @see dol_delete_file */ function dol_copy($srcfile, $destfile, $newmask=0, $overwriteifexists=1) { @@ -1203,7 +1205,7 @@ function dol_delete_file($file,$disableglob=0,$nophperrors=0,$nohook=0,$object=n * @param string $dir Directory to delete * @param int $nophperrors Disable all PHP output errors * @return boolean True if success, false if error - * @see dol_delete_file + * @see dol_delete_file dol_copy */ function dol_delete_dir($dir,$nophperrors=0) { diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index 6b759c8d2cc..1ee42f0e88e 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -105,7 +105,7 @@ function getDoliDBInstance($type, $host, $user, $pass, $name, $port) * @param string $element Current element * 'societe', 'socpeople', 'actioncomm', 'agenda', 'resource', * 'product', 'productprice', 'stock', - * 'propal', 'supplier_proposal', 'facture', 'facture_fourn', + * 'propal', 'supplier_proposal', 'facture', 'facture_fourn', 'payment_various', * 'categorie', 'bank_account', 'bank_account', 'adherent', 'user', * 'commande', 'commande_fournisseur', 'expedition', 'intervention', 'survey', * 'contract', 'tax', 'expensereport', 'holiday', 'multicurrency', 'project', @@ -199,6 +199,7 @@ function getBrowserInfo($user_agent) // Name if (preg_match('/firefox(\/|\s)([\d\.]*)/i', $user_agent, $reg)) { $name='firefox'; $version=$reg[2]; } + elseif (preg_match('/edge(\/|\s)([\d\.]*)/i', $user_agent, $reg)) { $name='edge'; $version=$reg[2]; } elseif (preg_match('/chrome(\/|\s)([\d\.]+)/i', $user_agent, $reg)) { $name='chrome'; $version=$reg[2]; } // we can have 'chrome (Mozilla...) chrome x.y' in one string elseif (preg_match('/chrome/i', $user_agent, $reg)) { $name='chrome'; } elseif (preg_match('/iceweasel/i', $user_agent)) { $name='iceweasel'; } @@ -466,7 +467,7 @@ function GETPOST($paramname, $check='none', $method=0, $filter=NULL, $options=NU } // Substitution variables for GETPOST (used to get final url with variable parameters or final default value with variable paramaters) - // Example of variables: __DAY__, __MONTH__, __YEAR__, __MYCOUNTRYID__, __USERID__, __ENTITYID__, ... + // Example of variables: __DAY__, __MONTH__, __YEAR__, __MYCOMPANY_COUNTRY_ID__, __USER_ID__, ... // We do this only if var is a GET. If it is a POST, may be we want to post the text with vars as the setup text. if (! is_array($out) && empty($_POST[$paramname]) && empty($noreplace)) { @@ -484,7 +485,7 @@ function GETPOST($paramname, $check='none', $method=0, $filter=NULL, $options=NU elseif ($reg[1] == 'NEXT_DAY') { $tmp=dol_getdate(dol_now(), true); $tmp2=dol_get_next_day($tmp['mday'], $tmp['mon'], $tmp['year']); $newout = $tmp2['day']; } elseif ($reg[1] == 'NEXT_MONTH') { $tmp=dol_getdate(dol_now(), true); $tmp2=dol_get_next_month($tmp['mday'], $tmp['mon'], $tmp['year']); $newout = $tmp2['month']; } elseif ($reg[1] == 'NEXT_YEAR') { $tmp=dol_getdate(dol_now(), true); $newout = ($tmp['year'] + 1); } - elseif ($reg[1] == 'MYCOUNTRY_ID' || $reg[1] == 'MYCOUNTRYID') + elseif ($reg[1] == 'MYCOMPANY_COUNTRY_ID' || $reg[1] == 'MYCOUNTRY_ID' || $reg[1] == 'MYCOUNTRYID') { $newout = $mysoc->country_id; } @@ -492,11 +493,11 @@ function GETPOST($paramname, $check='none', $method=0, $filter=NULL, $options=NU { $newout = $user->id; } - elseif ($reg[1] == 'SUPERVISOR_ID' || $reg[1] == 'SUPERVISORID') + elseif ($reg[1] == 'USER_SUPERVISOR_ID' || $reg[1] == 'SUPERVISOR_ID' || $reg[1] == 'SUPERVISORID') { $newout = $user->fk_user; } - elseif ($reg[1] == 'ENTITYID') + elseif ($reg[1] == 'ENTITY_ID' || $reg[1] == 'ENTITYID') { $newout = $conf->entity; } @@ -1118,7 +1119,7 @@ function dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $pi if (count($keys)) $maxkey=max($keys); } - //$conf->global->MAIN_MAXTABS_IN_CARD=3; + if (! empty($conf->dol_optimize_smallscreen)) $conf->global->MAIN_MAXTABS_IN_CARD=2; // Show tabs $bactive=false; @@ -1131,9 +1132,8 @@ function dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $pi { if ((is_numeric($active) && $i == $active) || (! empty($links[$i][2]) && ! is_numeric($active) && $active == $links[$i][2])) { - // si l'active est présent dans la box - if ($i >= $limittoshow) - $limittoshow--; + // If active tab is already present + if ($i >= $limittoshow) $limittoshow--; } } @@ -1145,7 +1145,9 @@ function dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $pi $bactive=true; } else + { $isactive=false; + } if ($i < $limittoshow || $isactive) { @@ -1154,11 +1156,11 @@ function dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $pi { if (!empty($links[$i][0])) { - $out.='
    '.$links[$i][1].''."\n"; + $out.=''.$links[$i][1].''."\n"; } else { - $out.=''.$links[$i][1].''."\n"; + $out.=''.$links[$i][1].''."\n"; } } else if (! empty($links[$i][1])) @@ -1166,11 +1168,15 @@ function dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $pi //print "x $i $active ".$links[$i][2]." z"; if ($isactive) { - $out.=''.$links[$i][1].''."\n"; + $out.=''; + $out.=$links[$i][1]; + $out.=''."\n"; } else { - $out.=''.$links[$i][1].''."\n"; + $out.=''; + $out.=$links[$i][1]; + $out.=''."\n"; } } $out.=''; @@ -1181,9 +1187,9 @@ function dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $pi if (! $popuptab) { $popuptab=1; - $outmore.='
    '; + $outmore.='
    '; // The css used to hide/show popup } - $outmore.='
    '; + $outmore.='
    '; if (isset($links[$i][2]) && $links[$i][2] == 'image') { if (!empty($links[$i][0])) @@ -1193,8 +1199,11 @@ function dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $pi } else if (! empty($links[$i][1])) - $outmore.=''.$links[$i][1].''."\n"; - + { + $outmore.=''; + $outmore.=preg_replace('/([a-z])\/([a-z])/i', '\\1 / \\2', $links[$i][1]); // Replace x/y with x / y to allow wrap on long composed texts. + $outmore.=''."\n"; + } $outmore.='
    '; $nbintab++; @@ -1205,15 +1214,21 @@ function dol_get_fiche_head($links=array(), $active='', $title='', $notab=0, $pi if ($displaytab > $limittoshow) { + $left=($langs->trans("DIRECTION") == 'rtl'?'right':'left'); + $right=($langs->trans("DIRECTION") == 'rtl'?'left':'right'); + $tabsname=str_replace("@", "", $picto); $out.='
    '; - $out.=''.$langs->trans("More").'... ('.$nbintab.')'; - $out.='
    '.$outmore.'
    '; + $out.=''.$langs->trans("More").'... ('.$nbintab.')'; + $out.='
    '; + $out.=$outmore; + $out.='
    '; + $out.='
    '; $out.="
    \n"; $out.=""; } @@ -1432,6 +1447,9 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r { $morehtmlstatus.=ajax_object_onoff($object, 'status', 'status', 'InActivity', 'ActivityCeased'); } + else { + $morehtmlstatus.=$object->getLibStatut(6); + } } elseif ($object->element == 'product') { @@ -1457,13 +1475,13 @@ function dol_banner_tab($object, $paramid, $morehtml='', $shownav=1, $fieldid='r } elseif ($object->element == 'contrat' || $object->element == 'contract') { - if ($object->statut==0) $morehtmlstatus.=$object->getLibStatut(2); + if ($object->statut == 0) $morehtmlstatus.=$object->getLibStatut(5); else $morehtmlstatus.=$object->getLibStatut(4); } elseif ($object->element == 'facturerec') { - if ($object->frequency==0) $morehtmlstatus.=$object->getLibStatut(2); - else $morehtmlstatus.=$object->getLibStatut(4); + if ($object->frequency == 0) $morehtmlstatus.=$object->getLibStatut(2); + else $morehtmlstatus.=$object->getLibStatut(5); } else { // Generic case $tmptxt=$object->getLibStatut(6); @@ -1535,14 +1553,15 @@ function dol_bc($var,$moreclass='') /** * Return a formated address (part address/zip/town/state) according to country rules * - * @param Object $object A company or contact object - * @param int $withcountry 1=Add country into address string - * @param string $sep Separator to use to build string - * @param Translate $outputlangs Object lang that contains language for text translation. - * @return string Formated string + * @param Object $object A company or contact object + * @param int $withcountry 1=Add country into address string + * @param string $sep Separator to use to build string + * @param Translate $outputlangs Object lang that contains language for text translation. + * @param int $mode 0=Standard output, 1=Remove address + * @return string Formated string * @see dol_print_address */ -function dol_format_address($object,$withcountry=0,$sep="\n",$outputlangs='') +function dol_format_address($object, $withcountry=0, $sep="\n", $outputlangs='', $mode=0) { global $conf,$langs; @@ -1550,7 +1569,9 @@ function dol_format_address($object,$withcountry=0,$sep="\n",$outputlangs='') $countriesusingstate=array('AU','CA','US','IN','GB','ES','UK','TR'); // See also MAIN_FORCE_STATE_INTO_ADDRESS // Address - $ret .= $object->address; + if (empty($mode)) { + $ret .= $object->address; + } // Zip/Town/State if (in_array($object->country_code,array('AU', 'CA', 'US')) || ! empty($conf->global->MAIN_FORCE_STATE_INTO_ADDRESS)) // US: title firstname name \n address lines \n town, state, zip \n country { @@ -1928,7 +1949,7 @@ function dol_mktime($hour,$minute,$second,$month,$day,$year,$gm=false,$check=1) /** - * Return date for now. In mot cases, we use this function without parameters (that means GMT time). + * Return date for now. In most cases, we use this function without parameters (that means GMT time). * * @param string $mode 'gmt' => we return GMT timestamp, * 'tzserver' => we add the PHP server timezone @@ -1938,7 +1959,8 @@ function dol_mktime($hour,$minute,$second,$month,$day,$year,$gm=false,$check=1) */ function dol_now($mode='gmt') { - $ret=''; + $ret=0; + // Note that gmmktime and mktime return same value (GMT) when used without parameters //if ($mode == 'gmt') $ret=gmmktime(); // Strict Standards: gmmktime(): You should be using the time() function instead if ($mode == 'gmt') $ret=time(); // Time for now at greenwich. @@ -1946,7 +1968,7 @@ function dol_now($mode='gmt') { require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; $tzsecond=getServerTimeZoneInt('now'); // Contains tz+dayling saving time - $ret=dol_now('gmt')+($tzsecond*3600); + $ret=(int) dol_now('gmt')+($tzsecond*3600); } /*else if ($mode == 'tzref') // Time for now with parent company timezone is added { @@ -1959,8 +1981,9 @@ function dol_now($mode='gmt') //print 'eeee'.time().'-'.mktime().'-'.gmmktime(); $offsettz=(empty($_SESSION['dol_tz'])?0:$_SESSION['dol_tz'])*60*60; $offsetdst=(empty($_SESSION['dol_dst'])?0:$_SESSION['dol_dst'])*60*60; - $ret=dol_now('gmt')+($offsettz+$offsetdst); + $ret=(int) dol_now('gmt')+($offsettz+$offsetdst); } + return $ret; } @@ -2556,7 +2579,7 @@ function dol_print_graph($htmlid,$width,$height,$data,$showlegend=0,$type='pie', var number=series.data[0][1]; return \''; print '
    '; - if ($url) print ''; + if ($url) print ''; print '\'+'.($showlegend?'number':'label+\' \'+number'); if (! empty($showpercent)) print '+\'
    \'+percent+\'%\''; print '+\''; @@ -3686,19 +3709,19 @@ function load_fiche_titre($titre, $morehtmlright='', $picto='title_generic.png', * @param string $options More parameters for links ('' by default, does not include sortfield neither sortorder). Value must be 'urlencoded' before calling function. * @param string $sortfield Field to sort on ('' by default) * @param string $sortorder Order to sort ('' by default) - * @param string $center String in the middle ('' by default). We often find here string $massaction comming from $form->selectMassAction() + * @param string $morehtmlcenter String in the middle ('' by default). We often find here string $massaction comming from $form->selectMassAction() * @param int $num Number of records found by select with limit+1 * @param int|string $totalnboflines Total number of records/lines for all pages (if known). Use a negative value of number to not show number. Use '' if unknown. * @param string $picto Icon to use before title (should be a 32x32 transparent png file) * @param int $pictoisfullpath 1=Icon name is a full absolute url of image - * @param string $morehtml More html to show + * @param string $morehtmlright More html to show * @param string $morecss More css to the table * @param int $limit Max number of lines (-1 = use default, 0 = no limit, > 0 = limit). * @param int $hideselectlimit Force to hide select limit * @param int $hidenavigation Force to hide all navigation tools * @return void */ -function print_barre_liste($titre, $page, $file, $options='', $sortfield='', $sortorder='', $center='', $num=-1, $totalnboflines='', $picto='title_generic.png', $pictoisfullpath=0, $morehtml='', $morecss='', $limit=-1, $hideselectlimit=0, $hidenavigation=0) +function print_barre_liste($titre, $page, $file, $options='', $sortfield='', $sortorder='', $morehtmlcenter='', $num=-1, $totalnboflines='', $picto='title_generic.png', $pictoisfullpath=0, $morehtmlright='', $morecss='', $limit=-1, $hideselectlimit=0, $hidenavigation=0) { global $conf,$langs; @@ -3732,9 +3755,9 @@ function print_barre_liste($titre, $page, $file, $options='', $sortfield='', $so print '
    '; // Center - if ($center) + if ($morehtmlcenter) { - print '
    '; + print ''; } // Right @@ -3788,7 +3811,7 @@ function print_barre_liste($titre, $page, $file, $options='', $sortfield='', $so } } - print_fleche_navigation($page, $file, $options, $nextpage, $pagelist, $morehtml, $savlimit, $totalnboflines, $hideselectlimit); // output the div and ul for previous/last completed with page numbers into $pagelist + print_fleche_navigation($page, $file, $options, $nextpage, $pagelist, $morehtmlright, $savlimit, $totalnboflines, $hideselectlimit); // output the div and ul for previous/last completed with page numbers into $pagelist print ''; @@ -4513,6 +4536,7 @@ function get_product_vat_for_country($idprod, $thirdparty_seller, $idprodfournpr { $product->get_buyprice($idprodfournprice,0,0,0); $ret=$product->vatrate_supplier; + if ($product->default_vat_code) $ret.=' ('.$product->default_vat_code.')'; } else { @@ -5346,7 +5370,8 @@ function getCommonSubstitutionArray($outputlangs, $onlykey=0, $exclude=null, $ob if (empty($exclude) || ! in_array('system', $exclude)) { - $substitutionarray['__(AnyTranslationKey)__']=$outputlangs->trans('TranslationKey'); + $substitutionarray['__(AnyTranslationKey)__']=$outputlangs->trans('TranslationOfKey'); + $substitutionarray['__[AnyConstantKey]__']=$outputlangs->trans('ValueOfConstant'); $substitutionarray['__DOL_MAIN_URL_ROOT__']=DOL_MAIN_URL_ROOT; } if (empty($exclude) || ! in_array('mycompany', $exclude)) @@ -5581,19 +5606,31 @@ function make_substitutions($text, $substitutionarray, $outputlangs=null) // Make substitution for language keys if (is_object($outputlangs)) { - while (preg_match('/__\(([^\)]*)\)__/', $text, $reg)) + while (preg_match('/__\(([^\)]+)\)__/', $text, $reg)) { + $msgishtml = 0; + if (dol_textishtml($text,1)) $msgishtml = 1; + // If key is __(TranslationKey|langfile)__, then force load of langfile.lang $tmp=explode('|',$reg[1]); if (! empty($tmp[1])) $outputlangs->load($tmp[1]); - $msgishtml = 0; - if (dol_textishtml($text,1)) $msgishtml = 1; - $text = preg_replace('/__\('.preg_quote($reg[1], '/').'\)__/', $msgishtml?dol_htmlentitiesbr($outputlangs->transnoentitiesnoconv($reg[1])):$outputlangs->transnoentitiesnoconv($reg[1]), $text); } } + // Make substitution for constant keys. Must be after the substitution of translation, so if text of translation contains a constant, + // it is also converted. + while (preg_match('/__\[([^\]]+)\]__/', $text, $reg)) + { + $msgishtml = 0; + if (dol_textishtml($text,1)) $msgishtml = 1; + + $keyfound = $reg[1]; + $newval=empty($conf->global->$keyfound)?'':$conf->global->$keyfound; + $text = preg_replace('/__\['.preg_quote($keyfound, '/').'\]__/', $msgishtml?dol_htmlentitiesbr($newval):$newval, $text); + } + // Make substitition for array $substitutionarray foreach ($substitutionarray as $key => $value) { @@ -5626,16 +5663,16 @@ function complete_substitutions_array(&$substitutionarray, $outputlangs, $object // Add a substitution key for each extrafields, using key __EXTRA_XXX__ // TODO Remove this. Already available into the getCommonSubstitutionArray used to build the substitution array. - if (is_object($object) && is_array($object->array_options)) + /*if (is_object($object) && is_array($object->array_options)) { foreach($object->array_options as $key => $val) { $keyshort=preg_replace('/^(options|extra)_/','',$key); - $substitutionarray['__EXTRA_'.$keyshort.'__']=$val; + $substitutionarray['__EXTRAFIELD_'.$keyshort.'__']=$val; // For backward compatibiliy $substitutionarray['%EXTRA_'.$keyshort.'%']=$val; } - } + }*/ // Check if there is external substitution to do, requested by plugins $dirsubstitutions=array_merge(array(),(array) $conf->modules_parts['substitutions']); @@ -6928,3 +6965,36 @@ function colorIsLight($stringcolor) } return $res; } + +/** + * Function to test if an entry is enabled or not + * + * @param string $type_user 0=We test for internal user, 1=We test for external user + * @param array $menuentry Array for feature entry to test + * @param array $listofmodulesforexternal Array with list of modules allowed to external users + * @return int 0=Hide, 1=Show, 2=Show gray + */ +function isVisibleToUserType($type_user, &$menuentry, &$listofmodulesforexternal) +{ + global $conf; + + //print 'type_user='.$type_user.' module='.$menuentry['module'].' enabled='.$menuentry['enabled'].' perms='.$menuentry['perms']; + //print 'ok='.in_array($menuentry['module'], $listofmodulesforexternal); + if (empty($menuentry['enabled'])) return 0; // Entry disabled by condition + if ($type_user && $menuentry['module']) + { + $tmploops=explode('|',$menuentry['module']); + $found=0; + foreach($tmploops as $tmploop) + { + if (in_array($tmploop, $listofmodulesforexternal)) { + $found++; break; + } + } + if (! $found) return 0; // Entry is for menus all excluded to external users + } + if (! $menuentry['perms'] && $type_user) return 0; // No permissions and user is external + if (! $menuentry['perms'] && ! empty($conf->global->MAIN_MENU_HIDE_UNAUTHORIZED)) return 0; // No permissions and option to hide when not allowed, even for internal user, is on + if (! $menuentry['perms']) return 2; // No permissions and user is external + return 1; +} diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php index e699758de99..2add3e04b63 100644 --- a/htdocs/core/lib/functions2.lib.php +++ b/htdocs/core/lib/functions2.lib.php @@ -1163,7 +1163,7 @@ function get_string_between($string, $start, $end){ * * @param string $mask Mask to use * @param string $value Value - * @return int <0 if KO, 0 if OK + * @return int|string <0 or error string if KO, 0 if OK */ function check_value($mask,$value) { @@ -1249,6 +1249,7 @@ function check_value($mask,$value) if (dol_strlen($value) != $len) $result=-1; // Define $maskLike + /* seems not used $maskLike = dol_string_nospecial($mask); $maskLike = str_replace("%","_",$maskLike); // Replace protected special codes with matching number of _ as wild card caracter @@ -1259,7 +1260,7 @@ function check_value($mask,$value) $maskLike = str_replace(dol_string_nospecial('{dd}'),'__',$maskLike); $maskLike = str_replace(dol_string_nospecial('{'.$masktri.'}'),str_pad("",dol_strlen($maskcounter),"_"),$maskLike); if ($maskrefclient) $maskLike = str_replace(dol_string_nospecial('{'.$maskrefclient.'}'),str_pad("",strlen($maskrefclient),"_"),$maskLike); - + */ dol_syslog("functions2::check_value result=".$result,LOG_DEBUG); return $result; @@ -2198,7 +2199,7 @@ function getModuleDirForApiClass($module) if ($module == 'contracts') { $moduledirforclass = 'contrat'; } - elseif (in_array($module, array('login', 'setup', 'access', 'status', 'documents'))) { + elseif (in_array($module, array('admin', 'login', 'setup', 'access', 'status', 'tools', 'documents'))) { $moduledirforclass = 'api'; } elseif ($module == 'contact' || $module == 'contacts' || $module == 'customer' || $module == 'thirdparty' || $module == 'thirdparties') { diff --git a/htdocs/core/lib/geturl.lib.php b/htdocs/core/lib/geturl.lib.php index cb594259c9f..2a45a71c4c9 100644 --- a/htdocs/core/lib/geturl.lib.php +++ b/htdocs/core/lib/geturl.lib.php @@ -123,7 +123,8 @@ function getURLContent($url,$postorget='GET',$param='',$followlocation=1,$addhea $request = curl_getinfo($ch, CURLINFO_HEADER_OUT); // Reading of request must be done after sending request dol_syslog("getURLContent request=".$request); - dol_syslog("getURLContent response=".$response); + //dol_syslog("getURLContent response =".response); // This may contains binary data, so we dont output it + dol_syslog("getURLContent response size=".strlen($response)); // This may contains binary data, so we dont output it $rep=array(); if (curl_errno($ch)) @@ -173,5 +174,38 @@ function getDomainFromURL($url) $tmpdomain = preg_replace('/\/.*$/i', '', $tmpdomain); // Remove part after domain $tmpdomain = preg_replace('/\.[^\.]+$/', '', $tmpdomain); // Remove first level domain (.com, .net, ...) $tmpdomain = preg_replace('/^[^\.]+\./', '', $tmpdomain); // Remove part www. before domain name + return $tmpdomain; } + +/** + * Function root url from a long url + * For example: https://www.abc.mydomain.com/dir/page.html return 'https://www.abc.mydomain.com' + * For example: http://www.abc.mydomain.com/ return 'https://www.abc.mydomain.com' + * + * @param string $url Full URL. + * @return string Returns root url + */ +function getRootURLFromURL($url) +{ + $prefix=''; + $tmpurl = $url; + if (preg_match('/^(https?:\/\/)/i', $tmpurl, $reg)) $prefix = $reg[1]; + $tmpurl = preg_replace('/^https?:\/\//i', '', $tmpurl); // Remove http(s):// + $tmpurl = preg_replace('/\/.*$/i', '', $tmpurl); // Remove part after domain + + return $prefix.$tmpurl; +} + +/** + * Function to remove comments into HTML content + * + * @param string $content Text content + * @return string Returns text without HTML comments + */ +function removeHtmlComment($content) +{ + $content = preg_replace('//', '', $content); + return $content; +} + diff --git a/htdocs/core/lib/json.lib.php b/htdocs/core/lib/json.lib.php index a35520998bf..4d31308b4b3 100644 --- a/htdocs/core/lib/json.lib.php +++ b/htdocs/core/lib/json.lib.php @@ -356,20 +356,20 @@ function utf82utf16($utf8) } switch(strlen($utf8)) { - case 1: - // this case should never be reached, because we are in ASCII range - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return $utf8; + case 1: + // this case should never be reached, because we are in ASCII range + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return $utf8; - case 2: - // return a UTF-16 character from a 2-byte UTF-8 char - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr(0x07 & (ord($utf8{0}) >> 2)) . chr((0xC0 & (ord($utf8{0}) << 6)) | (0x3F & ord($utf8{1}))); + case 2: + // return a UTF-16 character from a 2-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr(0x07 & (ord($utf8{0}) >> 2)) . chr((0xC0 & (ord($utf8{0}) << 6)) | (0x3F & ord($utf8{1}))); - case 3: - // return a UTF-16 character from a 3-byte UTF-8 char - // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 - return chr((0xF0 & (ord($utf8{0}) << 4)) | (0x0F & (ord($utf8{1}) >> 2))) . chr((0xC0 & (ord($utf8{1}) << 6)) | (0x7F & ord($utf8{2}))); + case 3: + // return a UTF-16 character from a 3-byte UTF-8 char + // see: http://www.cl.cam.ac.uk/~mgk25/unicode.html#utf-8 + return chr((0xF0 & (ord($utf8{0}) << 4)) | (0x0F & (ord($utf8{1}) >> 2))) . chr((0xC0 & (ord($utf8{1}) << 6)) | (0x7F & ord($utf8{2}))); } // ignoring UTF-32 for now, sorry diff --git a/htdocs/core/lib/order.lib.php b/htdocs/core/lib/order.lib.php index 92a11c907d4..cdbd46b1aa7 100644 --- a/htdocs/core/lib/order.lib.php +++ b/htdocs/core/lib/order.lib.php @@ -63,11 +63,14 @@ function commande_prepare_head(Commande $object) { $nbShipments=$object->getNbOfShipments(); $nbReceiption=0; $head[$h][0] = DOL_URL_ROOT.'/expedition/shipment.php?id='.$object->id; - if ($conf->expedition_bon->enabled) $text=$langs->trans("Shipments"); - if ($nbShipments > 0) $text.= ' '.$nbShipments.''; + $text=''; + if ($conf->expedition_bon->enabled) $text.=$langs->trans("Shipments"); if ($conf->expedition_bon->enabled && $conf->livraison_bon->enabled) $text.='/'; if ($conf->livraison_bon->enabled) $text.=$langs->trans("Receivings"); - if ($nbReceiption > 0) $text.= ' '.$nbReceiption.''; + if ($nbShipments > 0 || $nbReceiption > 0) $text.= ' '.($nbShipments?$nbShipments:0); + if ($conf->expedition_bon->enabled && $conf->livraison_bon->enabled) $text.='/'; + if ($conf->expedition_bon->enabled && $conf->livraison_bon->enabled && ($nbShipments > 0 || $nbReceiption > 0)) $text.= ($nbReceiption?$nbReceiption:0); + if ($nbShipments > 0 || $nbReceiption > 0) $text.= ''; $head[$h][1] = $text; $head[$h][2] = 'shipping'; $h++; diff --git a/htdocs/core/lib/payments.lib.php b/htdocs/core/lib/payments.lib.php index 3a398e50f69..73f8e507caf 100644 --- a/htdocs/core/lib/payments.lib.php +++ b/htdocs/core/lib/payments.lib.php @@ -292,7 +292,7 @@ function htmlPrintOnlinePaymentFooter($fromcompany,$langs,$addformmessage=0,$suf else if (! empty($conf->global->ONLINE_PAYMENT_MESSAGE_FORM)) print $langs->transnoentities($conf->global->ONLINE_PAYMENT_MESSAGE_FORM); // Add other message if VAT exists - if (! empty($object->total_vat) || ! empty($object->total_tva)) + if ($object->total_vat != 0 || $object->total_tva != 0) { $parammessageform='ONLINE_PAYMENT_MESSAGE_FORMIFVAT_'.$suffix; if (! empty($conf->global->$parammessageform)) print $langs->transnoentities($conf->global->$parammessageform); diff --git a/htdocs/core/lib/price.lib.php b/htdocs/core/lib/price.lib.php index 0cb1f755450..ba84876c93c 100644 --- a/htdocs/core/lib/price.lib.php +++ b/htdocs/core/lib/price.lib.php @@ -192,6 +192,7 @@ function calcul_price_total($qty, $pu, $remise_percent_ligne, $txtva, $uselocalt if ($type == 1) $apply_tax = true; break; } + if ($uselocaltax1_rate && $apply_tax) { $result[14] = price2num(($tot_sans_remise_wt * (1 + ( $localtax1_rate / 100))) - $tot_sans_remise_wt, 'MT'); $localtaxes[0] += $result[14]; diff --git a/htdocs/core/lib/product.lib.php b/htdocs/core/lib/product.lib.php index 36372254b61..c18fb58a49b 100644 --- a/htdocs/core/lib/product.lib.php +++ b/htdocs/core/lib/product.lib.php @@ -80,6 +80,9 @@ function product_prepare_head($object) { $head[$h][0] = DOL_URL_ROOT."/product/composition/card.php?id=".$object->id; $head[$h][1] = $langs->trans('AssociatedProducts'); + + $nbFatherAndChild = $object->hasFatherOrChild(); + if ($nbFatherAndChild > 0) $head[$h][1].= ' '.$nbFatherAndChild.''; $head[$h][2] = 'subproduct'; $h++; } @@ -165,9 +168,14 @@ function product_prepare_head($object) complete_head_from_modules($conf,$langs,$object,$head,$h,'product', 'remove'); // Log - $head[$h][0] = DOL_URL_ROOT.'/product/info.php?id='.$object->id; - $head[$h][1] = $langs->trans("Info"); - $head[$h][2] = 'info'; + $head[$h][0] = DOL_URL_ROOT.'/product/agenda.php?id='.$object->id; + $head[$h][1] = $langs->trans("Events"); + if (! empty($conf->agenda->enabled) && (!empty($user->rights->agenda->myactions->read) || !empty($user->rights->agenda->allactions->read) )) + { + $head[$h][1].= '/'; + $head[$h][1].= $langs->trans("Agenda"); + } + $head[$h][2] = 'agenda'; $h++; return $head; diff --git a/htdocs/core/lib/project.lib.php b/htdocs/core/lib/project.lib.php index 2e1c58af27c..92e44f63f02 100644 --- a/htdocs/core/lib/project.lib.php +++ b/htdocs/core/lib/project.lib.php @@ -262,11 +262,11 @@ function project_timesheet_prepare_head($mode, $fuser=null) $h++; } - /*if (empty($conf->global->PROJECT_DISABLE_TIMESHEET_PERACTION)) + /*if ($conf->global->MAIN_FEATURES_LEVEL >= 2) { - $head[$h][0] = DOL_URL_ROOT."/projet/activity/peraction.php".($mode?'?mode='.$mode:''); - $head[$h][1] = $langs->trans("InputPerAction"); - $head[$h][2] = 'inputperaction'; + $head[$h][0] = DOL_URL_ROOT."/projet/activity/perline.php".($param?'?'.$param:''); + $head[$h][1] = $langs->trans("InputDetail"); + $head[$h][2] = 'inputperline'; $h++; }*/ @@ -590,7 +590,233 @@ function projectLinesa(&$inc, $parent, &$lines, &$level, $var, $showproject, &$t * @param int $preselectedday Preselected day * @param array $isavailable Array with data that say if user is available for several days for morning and afternoon * @param int $oldprojectforbreak Old project id of last project break - * @return $inc + * @return array Array with time spent for $fuser for each day of week on tasks in $lines and substasks + */ +function projectLinesPerAction(&$inc, $parent, $fuser, $lines, &$level, &$projectsrole, &$tasksrole, $mine, $restricteditformytask, $preselectedday, &$isavailable, $oldprojectforbreak=0) +{ + global $conf, $db, $user, $bc, $langs; + global $form, $formother, $projectstatic, $taskstatic, $thirdpartystatic; + + $lastprojectid=0; + $totalforeachline=array(); + $workloadforid=array(); + $lineswithoutlevel0=array(); + + $numlines=count($lines); + + // Create a smaller array with sublevels only to be used later. This increase dramatically performances. + if ($parent == 0) // Always and only if at first level + { + for ($i = 0 ; $i < $numlines ; $i++) + { + if ($lines[$i]->fk_task_parent) $lineswithoutlevel0[]=$lines[$i]; + } + } + + if (empty($oldprojectforbreak)) + { + $oldprojectforbreak = (empty($conf->global->PROJECT_TIMESHEET_DISABLEBREAK_ON_PROJECT)?0:-1); // 0 to start break , -1 no break + } + + //dol_syslog('projectLinesPerDay inc='.$inc.' preselectedday='.$preselectedday.' task parent id='.$parent.' level='.$level." count(lines)=".$numlines." count(lineswithoutlevel0)=".count($lineswithoutlevel0)); + for ($i = 0 ; $i < $numlines ; $i++) + { + if ($parent == 0) $level = 0; + + //if ($lines[$i]->fk_task_parent == $parent) + //{ + // If we want all or we have a role on task, we show it + if (empty($mine) || ! empty($tasksrole[$lines[$i]->id])) + { + //dol_syslog("projectLinesPerWeek Found line ".$i.", a qualified task (i have role or want to show all tasks) with id=".$lines[$i]->id." project id=".$lines[$i]->fk_project); + + // Break on a new project + if ($parent == 0 && $lines[$i]->fk_project != $lastprojectid) + { + $lastprojectid=$lines[$i]->fk_project; + if ($preselectedday) + { + $projectstatic->id = $lines[$i]->fk_project; + } + } + + if (empty($workloadforid[$projectstatic->id])) + { + if ($preselectedday) + { + $projectstatic->loadTimeSpent($preselectedday, 0, $fuser->id); // Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week + $workloadforid[$projectstatic->id]=1; + } + } + + $projectstatic->id=$lines[$i]->fk_project; + $projectstatic->ref=$lines[$i]->project_ref; + $projectstatic->title=$lines[$i]->project_label; + $projectstatic->public=$lines[$i]->public; + + $taskstatic->id=$lines[$i]->task_id; + $taskstatic->ref=($lines[$i]->task_ref?$lines[$i]->task_ref:$lines[$i]->task_id); + $taskstatic->label=$lines[$i]->task_label; + $taskstatic->date_start=$lines[$i]->date_start; + $taskstatic->date_end=$lines[$i]->date_end; + + $thirdpartystatic->id=$lines[$i]->socid; + $thirdpartystatic->name=$lines[$i]->thirdparty_name; + $thirdpartystatic->email=$lines[$i]->thirdparty_email; + + if (empty($oldprojectforbreak) || ($oldprojectforbreak != -1 && $oldprojectforbreak != $projectstatic->id)) + { + print ''."\n"; + print ''; + print ''; + } + + if ($oldprojectforbreak != -1) $oldprojectforbreak = $projectstatic->id; + + print ''."\n"; + + // User + /* + print ''; + */ + + // Project + print ""; + + // Thirdparty + print ''; + + // Ref + print '\n"; + + // Date + print ''; + + $disabledproject=1;$disabledtask=1; + //print "x".$lines[$i]->fk_project; + //var_dump($lines[$i]); + //var_dump($projectsrole[$lines[$i]->fk_project]); + // If at least one role for project + if ($lines[$i]->public || ! empty($projectsrole[$lines[$i]->fk_project]) || $user->rights->projet->all->creer) + { + $disabledproject=0; + $disabledtask=0; + } + // If $restricteditformytask is on and I have no role on task, i disable edit + if ($restricteditformytask && empty($tasksrole[$lines[$i]->id])) + { + $disabledtask=1; + } + + // Hour + print ''; + + $cssonholiday=''; + if (! $isavailable[$preselectedday]['morning'] && ! $isavailable[$preselectedday]['afternoon']) $cssonholiday.='onholidayallday '; + elseif (! $isavailable[$preselectedday]['morning']) $cssonholiday.='onholidaymorning '; + elseif (! $isavailable[$preselectedday]['afternoon']) $cssonholiday.='onholidayafternoon '; + + // Duration + print ''; + + // Note + print ''; + + // Warning + print ''; + + print "\n"; + } + //} + //else + //{ + //$level--; + //} + } + + return $totalforeachline; +} + + +/** + * Output a task line into a pertime intput mode + * + * @param string $inc Line number (start to 0, then increased by recursive call) + * @param string $parent Id of parent task to show (0 to show all) + * @param User|null $fuser Restrict list to user if defined + * @param Task[] $lines Array of lines + * @param int $level Level (start to 0, then increased/decrease by recursive call) + * @param string $projectsrole Array of roles user has on project + * @param string $tasksrole Array of roles user has on task + * @param string $mine Show only task lines I am assigned to + * @param int $restricteditformytask 0=No restriction, 1=Enable add time only if task is a task i am affected to + * @param int $preselectedday Preselected day + * @param array $isavailable Array with data that say if user is available for several days for morning and afternoon + * @param int $oldprojectforbreak Old project id of last project break + * @return array Array with time spent for $fuser for each day of week on tasks in $lines and substasks */ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsrole, &$tasksrole, $mine, $restricteditformytask, $preselectedday, &$isavailable, $oldprojectforbreak=0) { @@ -598,6 +824,7 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr global $form, $formother, $projectstatic, $taskstatic, $thirdpartystatic; $lastprojectid=0; + $totalforeachday=array(); $workloadforid=array(); $lineswithoutlevel0=array(); @@ -655,7 +882,6 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr $taskstatic->id=$lines[$i]->id; $taskstatic->ref=($lines[$i]->ref?$lines[$i]->ref:$lines[$i]->id); - $taskstatic->id=$lines[$i]->id; $taskstatic->label=$lines[$i]->label; $taskstatic->date_start=$lines[$i]->date_start; $taskstatic->date_end=$lines[$i]->date_end; @@ -774,6 +1000,8 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr print ''; @@ -336,7 +336,7 @@ function show_list_sending_receive($origin,$origin_id,$filter='') } print ''; } - + // Batch number managment /*TODO Add link to expeditiondet_batch if (! empty($conf->productbatch->enabled)) @@ -351,7 +351,11 @@ function show_list_sending_receive($origin,$origin_id,$filter='') $detail = ''; foreach ($lines[$i]->detail_batch as $dbatch) { - $detail.= $langs->trans("DetailBatchFormat",$dbatch->batch,dol_print_date($dbatch->eatby,"day"),dol_print_date($dbatch->sellby,"day"),$dbatch->dluo_qty).'
    '; + $detail.= $langs->trans("Batch").': '.$dbatch->batch; + $detail.= ' - '.$langs->trans("SellByDate").': '.dol_print_date($dbatch->sellby,"day"); + $detail.= ' - '.$langs->trans("EatByDate").': '.dol_print_date($dbatch->eatby,"day"); + $detail.= ' - '.$langs->trans("Qty").': '.$dbatch->dluo_qty; + $detail.= '
    '; } print $form->textwithtooltip(img_picto('', 'object_barcode').' '.$langs->trans("DetailBatchNumber"),$detail); } @@ -363,8 +367,8 @@ function show_list_sending_receive($origin,$origin_id,$filter='') } else { print '
    '; } - }*/ - + }*/ + // Informations on receipt if (! empty($conf->livraison_bon->enabled)) { diff --git a/htdocs/core/lib/usergroups.lib.php b/htdocs/core/lib/usergroups.lib.php index afce2644124..6fe236d6b41 100644 --- a/htdocs/core/lib/usergroups.lib.php +++ b/htdocs/core/lib/usergroups.lib.php @@ -578,7 +578,7 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) } else { - $default='ffffff'; + $default='f0f0f0'; if ($conf->theme == 'md') $default='ffffff'; print ''; @@ -599,6 +599,33 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) print ''; } + // TextTitleColor + if ($foruserprofile) + { + + + } + else + { + print ''; + print ''; + print ''; + + print ''; + } + // BackgroundTableTitleColor if ($foruserprofile) { @@ -681,33 +708,6 @@ function show_theme($fuser,$edit=0,$foruserprofile=false) print ''; } - // TextTitleColor - if ($foruserprofile) - { - - - } - else - { - print ''; - print ''; - print ''; - - print ''; - } - // Text LinkColor if ($foruserprofile) { diff --git a/htdocs/core/lib/website.lib.php b/htdocs/core/lib/website.lib.php index 9a344ef0355..08fcdd82a58 100644 --- a/htdocs/core/lib/website.lib.php +++ b/htdocs/core/lib/website.lib.php @@ -29,14 +29,19 @@ * * @param Website $website Web site object * @param string $content Content to replace + * @param int $removephppart 0=Replace PHP sections with a PHP badge. 1=Remove completely PHP sections. * @return boolean True if OK */ -function dolWebsiteReplacementOfLinks($website, $content) +function dolWebsiteReplacementOfLinks($website, $content, $removephppart=0) { // Replace php code. Note $content may come from database and does not contains body tags. + $replacewith='...php...'; + if ($removephppart) $replacewith=''; + $content = preg_replace('/value="<\?php((?!\?>).)*\?>\n*/ims', 'value="'.$replacewith.'"', $content); - $content = preg_replace('/value="<\?php((?!\?>).)*\?>\n*/ims', 'value="...php..."', $content); - $content = preg_replace('/<\?php((?!\?>).)*\?>\n*/ims', '...php...', $content); + $replacewith='...php...'; + if ($removephppart) $replacewith=''; + $content = preg_replace('/<\?php((?!\?>).)*\?>\n*/ims', $replacewith, $content); // Replace relative link / with dolibarr URL $content = preg_replace('/(href=")\/\"/', '\1'.DOL_URL_ROOT.'/website/index.php?website='.$website->ref.'&pageid='.$website->fk_default_home.'"', $content, -1, $nbrep); @@ -155,17 +160,20 @@ function dolWebsiteSaveContent($content) * Clean an HTML page to report only content, so we can include it into another page. * It outputs content of file sanitized from html and body part. * - * @param string $contentfile Path to file to include (must include website root. Example: 'mywebsite/mypage.php') + * @param string $containeralias Path to file to include (must be a page from website root. Example: 'mypage.php' means 'mywebsite/mypage.php') * @return void */ -function dolIncludeHtmlContent($contentfile) +function includeContainer($containeralias) { global $conf, $db, $langs, $mysoc, $user, $website; global $includehtmlcontentopened; + global $websitekey; $MAXLEVEL=20; - $fullpathfile=DOL_DATA_ROOT.'/website/'.$contentfile; + if (! preg_match('/\.php$/i', $containeralias)) $containeralias.='.php'; + + $fullpathfile=DOL_DATA_ROOT.'/website/'.$websitekey.'/'.$containeralias; if (empty($includehtmlcontentopened)) $includehtmlcontentopened=0; $includehtmlcontentopened++; @@ -188,7 +196,7 @@ function dolIncludeHtmlContent($contentfile) if (! $res) { - print 'ERROR: FAILED TO INCLUDE PAGE '.$contentfile.".\n"; + print 'ERROR: FAILED TO INCLUDE PAGE '.$containeralias.".\n"; } $includehtmlcontentopened--; @@ -225,7 +233,16 @@ function getAllImages($object, $objectpage, $urltograb, &$tmp, &$action, $modify { if (preg_match('/^data:image/i', $regs[2][$key])) continue; // We do nothing for such images - $urltograbbis = $urltograb.(preg_match('/^\//', $regs[2][$key])?'':'/').$regs[2][$key]; + if (preg_match('/^\//', $regs[2][$key])) + { + $urltograbdirrootwithoutslash = getRootURLFromURL($urltograb); + $urltograbbis = $urltograbdirrootwithoutslash.$regs[2][$key]; // We use dirroot + } + else + { + $urltograbbis = $urltograb.'/'.$regs[2][$key]; // We use dir of grabbed file + } + $linkwithoutdomain = $regs[2][$key]; $filetosave = $conf->medias->multidir_output[$conf->entity].'/image/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $regs[2][$key])?'':'/').$regs[2][$key]; if (preg_match('/^http/', $regs[2][$key])) @@ -251,7 +268,13 @@ function getAllImages($object, $objectpage, $urltograb, &$tmp, &$action, $modify if ($tmpgeturl['curl_error_no']) { $error++; - setEventMessages($tmpgeturl['curl_error_msg'], null, 'errors'); + setEventMessages('Error getting '.$urltograbbis.': '.$tmpgeturl['curl_error_msg'], null, 'errors'); + $action='create'; + } + elseif ($tmpgeturl['http_code'] != '200') + { + $error++; + setEventMessages('Error getting '.$urltograbbis.': '.$tmpgeturl['http_code'], null, 'errors'); $action='create'; } else @@ -281,7 +304,15 @@ function getAllImages($object, $objectpage, $urltograb, &$tmp, &$action, $modify { if (preg_match('/^data:image/i', $regs[2][$key])) continue; // We do nothing for such images - $urltograbbis = $urltograb.(preg_match('/^\//', $regs[2][$key])?'':'/').$regs[2][$key]; + if (preg_match('/^\//', $regs[2][$key])) + { + $urltograbdirrootwithoutslash = getRootURLFromURL($urltograb); + $urltograbbis = $urltograbdirrootwithoutslash.$regs[2][$key]; // We use dirroot + } + else + { + $urltograbbis = $urltograb.'/'.$regs[2][$key]; // We use dir of grabbed file + } $linkwithoutdomain = $regs[2][$key]; $filetosave = $conf->medias->multidir_output[$conf->entity].'/image/'.$object->ref.'/'.$objectpage->pageurl.(preg_match('/^\//', $regs[2][$key])?'':'/').$regs[2][$key]; @@ -309,7 +340,13 @@ function getAllImages($object, $objectpage, $urltograb, &$tmp, &$action, $modify if ($tmpgeturl['curl_error_no']) { $error++; - setEventMessages($tmpgeturl['curl_error_msg'], null, 'errors'); + setEventMessages('Error getting '.$urltograbbis.': '.$tmpgeturl['curl_error_msg'], null, 'errors'); + $action='create'; + } + elseif ($tmpgeturl['http_code'] != '200') + { + $error++; + setEventMessages('Error getting '.$urltograbbis.': '.$tmpgeturl['http_code'], null, 'errors'); $action='create'; } else diff --git a/htdocs/core/login/functions_forceuser.php b/htdocs/core/login/functions_forceuser.php index 94201c74ad0..c337a0840b3 100644 --- a/htdocs/core/login/functions_forceuser.php +++ b/htdocs/core/login/functions_forceuser.php @@ -44,5 +44,6 @@ function check_user_password_forceuser($usertotest,$passwordtotest,$entitytotest if ($_SESSION["dol_loginmesg"]) $login=''; + dol_syslog("functions_forceuser::check_user_password_forceuser ok. forced user = ".$login); return $login; } diff --git a/htdocs/core/menus/standard/auguria.lib.php b/htdocs/core/menus/standard/auguria.lib.php index 90089488389..4dae9628c30 100644 --- a/htdocs/core/menus/standard/auguria.lib.php +++ b/htdocs/core/menus/standard/auguria.lib.php @@ -73,12 +73,9 @@ function print_auguria_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$m $showmode=dol_auguria_showmenu($type_user,$newTabMenu[$i],$listofmodulesforexternal); if ($showmode == 1) { - // $menu_array[$i]['url'] can be a relative url, a full external url or a dynamic value like '$conf->global->APARAM) - if (preg_match('/^\$conf->global->([^\?]+)/', $newTabMenu[$i]['url'], $reg)) - { - $keyforsconst=$reg[1]; - $newTabMenu[$i]['url'] = $conf->global->$keyforsconst; - } + $substitarray = array('__LOGIN__' => $user->login, '__USER_ID__' => $user->id, '__USER_SUPERVISOR_ID__' => $user->fk_user); + $substitarray['__USERID__'] = $user->id; // For backward compatibility + $newTabMenu[$i]['url'] = make_substitutions($newTabMenu[$i]['url'], $substitarray); $url = $shorturl = $newTabMenu[$i]['url']; @@ -105,11 +102,6 @@ function print_auguria_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$m if (DOL_URL_ROOT) $shorturl = preg_replace('/^'.preg_quote(DOL_URL_ROOT,'/').'/','',$shorturl); } - $url=preg_replace('/__LOGIN__/',$user->login,$url); - $shorturl=preg_replace('/__LOGIN__/',$user->login,$shorturl); - $url=preg_replace('/__USERID__/',$user->id,$url); - $shorturl=preg_replace('/__USERID__/',$user->id,$shorturl); - // TODO Find a generic solution if (preg_match('/search_project_user=__search_project_user__/', $shorturl)) { @@ -511,10 +503,13 @@ function print_left_auguria_menu($db,$menu_array_before,$menu_array_after,&$tabM } } + // $menu_array[$i]['url'] can be a relative url, a full external url. We try substitution + $substitarray = array('__LOGIN__' => $user->login, '__USER_ID__' => $user->id, '__USER_SUPERVISOR_ID__' => $user->fk_user); + $substitarray['__USERID__'] = $user->id; // For backward compatibility + $menu_array[$i]['url'] = make_substitutions($menu_array[$i]['url'], $substitarray); + // Add mainmenu in GET url. This make to go back on correct menu even when using Back on browser. $url=dol_buildpath($menu_array[$i]['url'],1); - $url=preg_replace('/__LOGIN__/',$user->login,$url); - $url=preg_replace('/__USERID__/',$user->id,$url); if (! preg_match('/mainmenu=/i',$menu_array[$i]['url'])) { diff --git a/htdocs/core/menus/standard/auguria_menu.php b/htdocs/core/menus/standard/auguria_menu.php index 55941fe7c10..080e9ef81dc 100644 --- a/htdocs/core/menus/standard/auguria_menu.php +++ b/htdocs/core/menus/standard/auguria_menu.php @@ -157,9 +157,11 @@ class MenuManager print '
  • '; if ($val['enabled'] == 1) { + $substitarray = array('__LOGIN__' => $user->login, '__USER_ID__' => $user->id, '__USER_SUPERVISOR_ID__' => $user->fk_user); + $substitarray['__USERID__'] = $user->id; // For backward compatibility + $val['url'] = make_substitutions($val['url'], $substitarray); + $relurl=dol_buildpath($val['url'],1); - $relurl=preg_replace('/__LOGIN__/',$user->login,$relurl); - $relurl=preg_replace('/__USERID__/',$user->id,$relurl); $canonurl=preg_replace('/\?.*$/','',$val['url']); print ''; @@ -190,7 +192,7 @@ class MenuManager print ''; if ($langs->trans(ucfirst($val['mainmenu'])."Dashboard") == ucfirst($val['mainmenu'])."Dashboard") // No translation { - if (in_array($val['mainmenu'], array('cashdesk', 'websites'))) print $langs->trans("Access"); + if (in_array($val['mainmenu'], array('cashdesk', 'externalsite', 'website', 'collab'))) print $langs->trans("Access"); else print $langs->trans("Dashboard"); } else print $langs->trans(ucfirst($val['mainmenu'])."Dashboard"); @@ -233,9 +235,11 @@ class MenuManager if ($showmenu) // Visible (option to hide when not allowed is off or allowed) { + $substitarray = array('__LOGIN__' => $user->login, '__USER_ID__' => $user->id, '__USER_SUPERVISOR_ID__' => $user->fk_user); + $substitarray['__USERID__'] = $user->id; // For backward compatibility + $val2['url'] = make_substitutions($val2['url'], $substitarray); + $relurl2=dol_buildpath($val2['url'],1); - $relurl2=preg_replace('/__LOGIN__/',$user->login,$relurl2); - $relurl2=preg_replace('/__USERID__/',$user->id,$relurl2); $canonurl2=preg_replace('/\?.*$/','',$val2['url']); //var_dump($val2['url'].' - '.$canonurl2.' - '.$val2['level']); if (in_array($canonurl2,array('/admin/index.php','/admin/tools/index.php','/core/tools.php'))) $relurl2=''; diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 287e91947d4..a6dd8031ffb 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -74,7 +74,7 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$mode // Third parties $tmpentry=array('enabled'=>(( ! empty($conf->societe->enabled) && (empty($conf->global->SOCIETE_DISABLE_PROSPECTS) || empty($conf->global->SOCIETE_DISABLE_CUSTOMERS))) || ! empty($conf->fournisseur->enabled)), 'perms'=>(! empty($user->rights->societe->lire) || ! empty($user->rights->fournisseur->lire)), 'module'=>'societe|fournisseur'); - $showmode=dol_eldy_showmenu($type_user, $tmpentry, $listofmodulesforexternal); + $showmode=isVisibleToUserType($type_user, $tmpentry, $listofmodulesforexternal); if ($showmode) { $langs->load("companies"); @@ -90,7 +90,7 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$mode // Products-Services $tmpentry=array('enabled'=>(! empty($conf->product->enabled) || ! empty($conf->service->enabled)), 'perms'=>(! empty($user->rights->produit->lire) || ! empty($user->rights->service->lire)), 'module'=>'product|service'); - $showmode=dol_eldy_showmenu($type_user, $tmpentry, $listofmodulesforexternal); + $showmode=isVisibleToUserType($type_user, $tmpentry, $listofmodulesforexternal); if ($showmode) { $langs->load("products"); @@ -125,7 +125,7 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$mode 'enabled'=>$menuqualified, 'perms'=>(! empty($user->rights->societe->lire) || ! empty($user->rights->societe->contact->lire)), 'module'=>'propal|commande|supplier_order|contrat|ficheinter'); - $showmode=dol_eldy_showmenu($type_user, $tmpentry, $listofmodulesforexternal); + $showmode=isVisibleToUserType($type_user, $tmpentry, $listofmodulesforexternal); if ($showmode) { $langs->load("commercial"); @@ -151,7 +151,7 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$mode 'enabled'=>$menuqualified, 'perms'=>(! empty($user->rights->facture->lire) || ! empty($user->rights->don->lire) || ! empty($user->rights->tax->charges->lire) || ! empty($user->rights->salaries->read) || ! empty($user->rights->fournisseur->facture->lire) || ! empty($user->rights->loan->read) || ! empty($user->rights->banque->lire)), 'module'=>'facture|supplier_invoice|don|tax|salaries|loan|banque'); - $showmode=dol_eldy_showmenu($type_user, $tmpentry, $listofmodulesforexternal); + $showmode=isVisibleToUserType($type_user, $tmpentry, $listofmodulesforexternal); if ($showmode) { $langs->load("compta"); @@ -172,7 +172,7 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$mode 'enabled'=>$menuqualified, 'perms'=>(! empty($user->rights->compta->resultat->lire) || ! empty($user->rights->accounting->mouvements->lire)), 'module'=>'comptabilite|accounting'); - $showmode=dol_eldy_showmenu($type_user, $tmpentry, $listofmodulesforexternal); + $showmode=isVisibleToUserType($type_user, $tmpentry, $listofmodulesforexternal); if ($showmode) { $langs->load("compta"); @@ -190,7 +190,7 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$mode $tmpentry=array('enabled'=>(! empty($conf->banque->enabled) || ! empty($conf->prelevement->enabled)), 'perms'=>(! empty($user->rights->banque->lire) || ! empty($user->rights->prelevement->lire)), 'module'=>'banque|prelevement'); - $showmode=dol_eldy_showmenu($type_user, $tmpentry, $listofmodulesforexternal); + $showmode=isVisibleToUserType($type_user, $tmpentry, $listofmodulesforexternal); if ($showmode) { $langs->load("compta"); @@ -208,7 +208,7 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$mode $tmpentry=array('enabled'=>(! empty($conf->projet->enabled)), 'perms'=>(! empty($user->rights->projet->lire)), 'module'=>'projet'); - $showmode=dol_eldy_showmenu($type_user, $tmpentry, $listofmodulesforexternal); + $showmode=isVisibleToUserType($type_user, $tmpentry, $listofmodulesforexternal); if ($showmode) { $langs->load("projects"); @@ -225,7 +225,7 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$mode $tmpentry=array('enabled'=>(! empty($conf->hrm->enabled) || ! empty($conf->holiday->enabled) || ! empty($conf->deplacement->enabled) || ! empty($conf->expensereport->enabled)), 'perms'=>(! empty($user->rights->hrm->employee->read) || ! empty($user->rights->holiday->write) || ! empty($user->rights->deplacement->lire) || ! empty($user->rights->expensereport->lire)), 'module'=>'hrm|holiday|deplacement|expensereport'); - $showmode=dol_eldy_showmenu($type_user, $tmpentry, $listofmodulesforexternal); + $showmode=isVisibleToUserType($type_user, $tmpentry, $listofmodulesforexternal); if ($showmode) { $langs->load("holiday"); @@ -245,7 +245,7 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$mode 'enabled'=>1, 'perms'=>1, 'module'=>''); - $showmode=dol_eldy_showmenu($type_user, $tmpentry, $listofmodulesforexternal); + $showmode=isVisibleToUserType($type_user, $tmpentry, $listofmodulesforexternal); if ($showmode) { $langs->load("other"); @@ -262,7 +262,7 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$mode $tmpentry=array('enabled'=>(! empty($conf->adherent->enabled)), 'perms'=>(! empty($user->rights->adherent->lire)), 'module'=>'adherent'); - $showmode=dol_eldy_showmenu($type_user, $tmpentry, $listofmodulesforexternal); + $showmode=isVisibleToUserType($type_user, $tmpentry, $listofmodulesforexternal); if ($showmode) { $classname=""; @@ -273,7 +273,6 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$mode $menu->add('/adherents/index.php?mainmenu=members&leftmenu=', $langs->trans("MenuMembers"), 0, $showmode, $atarget, "members", '', 100, $id, $idsel, $classname); } - // Show personalized menus $menuArbo = new Menubase($db,'eldy'); $newTabMenu = $menuArbo->menuTopCharger('','',$type_user,'eldy',$tabMenu); // Return tabMenu with only top entries @@ -283,9 +282,13 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$mode { $idsel=(empty($newTabMenu[$i]['mainmenu'])?'none':$newTabMenu[$i]['mainmenu']); - $showmode=dol_eldy_showmenu($type_user,$newTabMenu[$i],$listofmodulesforexternal); + $showmode=isVisibleToUserType($type_user,$newTabMenu[$i],$listofmodulesforexternal); if ($showmode == 1) { + $substitarray = array('__LOGIN__' => $user->login, '__USER_ID__' => $user->id, '__USER_SUPERVISOR_ID__' => $user->fk_user); + $substitarray['__USERID__'] = $user->id; // For backward compatibility + $newTabMenu[$i]['url'] = make_substitutions($newTabMenu[$i]['url'], $substitarray); + // url = url from host, shorturl = relative path into dolibarr sources $url = $shorturl = $newTabMenu[$i]['url']; if (! preg_match("/^(http:\/\/|https:\/\/)/i",$newTabMenu[$i]['url'])) // Do not change url content for external links @@ -301,10 +304,6 @@ function print_eldy_menu($db,$atarget,$type_user,&$tabMenu,&$menu,$noout=0,$mode $shorturl = $url; if (DOL_URL_ROOT) $shorturl = preg_replace('/^'.preg_quote(DOL_URL_ROOT,'/').'/','',$shorturl); } - $url=preg_replace('/__LOGIN__/',$user->login,$url); - $shorturl=preg_replace('/__LOGIN__/',$user->login,$shorturl); - $url=preg_replace('/__USERID__/',$user->id,$url); - $shorturl=preg_replace('/__USERID__/',$user->id,$shorturl); // Define the class (top menu selected or not) if (! empty($_SESSION['idmenu']) && $newTabMenu[$i]['rowid'] == $_SESSION['idmenu']) $classname='class="tmenusel"'; @@ -518,10 +517,10 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $langs->load("users"); // Home - dashboard - $newmenu->add("/index.php?mainmenu=home&leftmenu=home", $langs->trans("MyDashboard"), 0, 1, '', $mainmenu, 'home'); + $newmenu->add("/index.php?mainmenu=home&leftmenu=home", $langs->trans("MyDashboard"), 0, 1, '', $mainmenu, 'home', 0, '', '', '', ''); // Setup - $newmenu->add("/admin/index.php?mainmenu=home&leftmenu=setup", $langs->trans("Setup"), 0, $user->admin, '', $mainmenu, 'setup'); + $newmenu->add("/admin/index.php?mainmenu=home&leftmenu=setup", $langs->trans("Setup"), 0, $user->admin, '', $mainmenu, 'setup', 0, '', '', '', ''); if ($usemenuhider || empty($leftmenu) || $leftmenu=="setup") { $langs->load("admin"); @@ -558,7 +557,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu } // System tools - $newmenu->add("/admin/tools/index.php?mainmenu=home&leftmenu=admintools", $langs->trans("AdminTools"), 0, $user->admin, '', $mainmenu, 'admintools'); + $newmenu->add("/admin/tools/index.php?mainmenu=home&leftmenu=admintools", $langs->trans("AdminTools"), 0, $user->admin, '', $mainmenu, 'admintools', 0, '', '', '', ''); if ($usemenuhider || empty($leftmenu) || preg_match('/^admintools/',$leftmenu)) { $langs->load("admin"); @@ -591,7 +590,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu } } - $newmenu->add("/user/home.php?leftmenu=users", $langs->trans("MenuUsersAndGroups"), 0, $user->rights->user->user->lire, '', $mainmenu, 'users'); + $newmenu->add("/user/home.php?leftmenu=users", $langs->trans("MenuUsersAndGroups"), 0, $user->rights->user->user->lire, '', $mainmenu, 'users', 0, '', '', '', ''); if ($user->rights->user->user->lire) { if ($usemenuhider || empty($leftmenu) || $leftmenu=="users") @@ -1357,7 +1356,11 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $newmenu->add("/holiday/list.php?leftmenu=hrm", $langs->trans("CPTitreMenu"), 0, $user->rights->holiday->read, '', $mainmenu, 'hrm'); $newmenu->add("/holiday/card.php?action=request", $langs->trans("New"), 1,$user->rights->holiday->write); $newmenu->add("/holiday/list.php?leftmenu=hrm", $langs->trans("List"), 1,$user->rights->holiday->read); - $newmenu->add("/holiday/list.php?select_statut=2&leftmenu=hrm", $langs->trans("ListToApprove"), 2, $user->rights->holiday->read); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="hrm") $newmenu->add("/holiday/list.php?select_statut=1&leftmenu=hrm", $langs->trans("DraftCP"), 2, $user->rights->holiday->read); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="hrm") $newmenu->add("/holiday/list.php?select_statut=2&leftmenu=hrm", $langs->trans("ToReviewCP"), 2, $user->rights->holiday->read); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="hrm") $newmenu->add("/holiday/list.php?select_statut=3&leftmenu=hrm", $langs->trans("ApprovedCP"), 2, $user->rights->holiday->read); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="hrm") $newmenu->add("/holiday/list.php?select_statut=4&leftmenu=hrm", $langs->trans("CancelCP"), 2, $user->rights->holiday->read); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="hrm") $newmenu->add("/holiday/list.php?select_statut=5&leftmenu=hrm", $langs->trans("RefuseCP"), 2, $user->rights->holiday->read); $newmenu->add("/holiday/define_holiday.php?action=request", $langs->trans("MenuConfCP"), 1, $user->rights->holiday->read); $newmenu->add("/holiday/view_log.php?action=request", $langs->trans("MenuLogCP"), 1, $user->rights->holiday->define_holiday); } @@ -1379,7 +1382,12 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $newmenu->add("/expensereport/index.php?leftmenu=expensereport&mainmenu=hrm", $langs->trans("TripsAndExpenses"), 0, $user->rights->expensereport->lire, '', $mainmenu, 'expensereport'); $newmenu->add("/expensereport/card.php?action=create&leftmenu=expensereport&mainmenu=hrm", $langs->trans("New"), 1, $user->rights->expensereport->creer); $newmenu->add("/expensereport/list.php?leftmenu=expensereport&mainmenu=hrm", $langs->trans("List"), 1, $user->rights->expensereport->lire); - $newmenu->add("/expensereport/list.php?search_status=2&leftmenu=expensereport&mainmenu=hrm", $langs->trans("ListToApprove"), 2, $user->rights->expensereport->approve); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="expensereport") $newmenu->add("/expensereport/list.php?search_status=0&leftmenu=expensereport&mainmenu=hrm", $langs->trans("Draft"), 2, $user->rights->expensereport->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="expensereport") $newmenu->add("/expensereport/list.php?search_status=2&leftmenu=expensereport&mainmenu=hrm", $langs->trans("Validated"), 2, $user->rights->expensereport->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="expensereport") $newmenu->add("/expensereport/list.php?search_status=5&leftmenu=expensereport&mainmenu=hrm", $langs->trans("Approved"), 2, $user->rights->expensereport->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="expensereport") $newmenu->add("/expensereport/list.php?search_status=6&leftmenu=expensereport&mainmenu=hrm", $langs->trans("Paid"), 2, $user->rights->expensereport->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="expensereport") $newmenu->add("/expensereport/list.php?search_status=4&leftmenu=expensereport&mainmenu=hrm", $langs->trans("Canceled"), 2, $user->rights->expensereport->lire); + if ($usemenuhider || empty($leftmenu) || $leftmenu=="expensereport") $newmenu->add("/expensereport/list.php?search_status=99&leftmenu=expensereport&mainmenu=hrm", $langs->trans("Refused"), 2, $user->rights->expensereport->lire); $newmenu->add("/expensereport/stats/index.php?leftmenu=expensereport&mainmenu=hrm", $langs->trans("Statistics"), 1, $user->rights->expensereport->lire); } @@ -1598,12 +1606,10 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu } } - // $menu_array[$i]['url'] can be a relative url, a full external url or a dynamic value like '$conf->global->APARAM) - if (preg_match('/^\$conf->global->([^\?]+)/', $menu_array[$i]['url'], $reg)) - { - $keyforsconst=$reg[1]; - $menu_array[$i]['url'] = $conf->global->$keyforsconst; - } + // $menu_array[$i]['url'] can be a relative url, a full external url. We try substitution + $substitarray = array('__LOGIN__' => $user->login, '__USER_ID__' => $user->id, '__USER_SUPERVISOR_ID__' => $user->fk_user); + $substitarray['__USERID__'] = $user->id; // For backward compatibility + $menu_array[$i]['url'] = make_substitutions($menu_array[$i]['url'], $substitarray); $url = $shorturl = $menu_array[$i]['url']; @@ -1626,11 +1632,8 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $url = dol_buildpath($url,1).($param?'?'.$param:''); $shorturl = $shorturl.($param?'?'.$param:''); } + //var_dump($url); - $url=preg_replace('/__LOGIN__/',$user->login,$url); - $shorturl=preg_replace('/__LOGIN__/',$user->login,$shorturl); - $url=preg_replace('/__USERID__/',$user->id,$url); - $shorturl=preg_replace('/__USERID__/',$user->id,$shorturl); print ''."\n"; @@ -1639,7 +1642,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu { if ($menu_array[$i]['enabled']) // Enabled so visible { - print ''."\n"; + print ''."\n"; $lastlevel0='enabled'; } else if ($showmenu) // Not enabled but visible (so greyed) @@ -1656,6 +1659,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu print ''."\n"; } } + // Menu level > 0 if ($menu_array[$i]['level'] > 0) { @@ -1696,36 +1700,3 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu } -/** - * Function to test if an entry is enabled or not - * - * @param string $type_user 0=We need backoffice menu, 1=We need frontoffice menu - * @param array $menuentry Array for menu entry - * @param array $listofmodulesforexternal Array with list of modules allowed to external users - * @return int 0=Hide, 1=Show, 2=Show gray - */ -function dol_eldy_showmenu($type_user, &$menuentry, &$listofmodulesforexternal) -{ - global $conf; - - //print 'type_user='.$type_user.' module='.$menuentry['module'].' enabled='.$menuentry['enabled'].' perms='.$menuentry['perms']; - //print 'ok='.in_array($menuentry['module'], $listofmodulesforexternal); - if (empty($menuentry['enabled'])) return 0; // Entry disabled by condition - if ($type_user && $menuentry['module']) - { - $tmploops=explode('|',$menuentry['module']); - $found=0; - foreach($tmploops as $tmploop) - { - if (in_array($tmploop, $listofmodulesforexternal)) { - $found++; break; - } - } - if (! $found) return 0; // Entry is for menus all excluded to external users - } - if (! $menuentry['perms'] && $type_user) return 0; // No permissions and user is external - if (! $menuentry['perms'] && ! empty($conf->global->MAIN_MENU_HIDE_UNAUTHORIZED)) return 0; // No permissions and option to hide when not allowed, even for internal user, is on - if (! $menuentry['perms']) return 2; // No permissions and user is external - return 1; -} - diff --git a/htdocs/core/menus/standard/eldy_menu.php b/htdocs/core/menus/standard/eldy_menu.php index 51442d54e51..9ef1421daf2 100644 --- a/htdocs/core/menus/standard/eldy_menu.php +++ b/htdocs/core/menus/standard/eldy_menu.php @@ -165,9 +165,11 @@ class MenuManager if ($val['enabled'] == 1) { + $substitarray = array('__LOGIN__' => $user->login, '__USER_ID__' => $user->id, '__USER_SUPERVISOR_ID__' => $user->fk_user); + $substitarray['__USERID__'] = $user->id; // For backward compatibility + $val['url'] = make_substitutions($val['url'], $substitarray); + $relurl=dol_buildpath($val['url'],1); - $relurl=preg_replace('/__LOGIN__/',$user->login,$relurl); - $relurl=preg_replace('/__USERID__/',$user->id,$relurl); $canonurl=preg_replace('/\?.*$/','',$val['url']); print ''; @@ -200,7 +202,7 @@ class MenuManager print ''; if ($langs->trans(ucfirst($val['mainmenu'])."Dashboard") == ucfirst($val['mainmenu'])."Dashboard") // No translation { - if (in_array($val['mainmenu'], array('cashdesk', 'websites'))) print $langs->trans("Access"); + if (in_array($val['mainmenu'], array('cashdesk', 'externalsite', 'website', 'collab'))) print $langs->trans("Access"); else print $langs->trans("Dashboard"); } else print $langs->trans(ucfirst($val['mainmenu'])."Dashboard"); @@ -243,9 +245,11 @@ class MenuManager if ($showmenu) // Visible (option to hide when not allowed is off or allowed) { + $substitarray = array('__LOGIN__' => $user->login, '__USER_ID__' => $user->id, '__USER_SUPERVISOR_ID__' => $user->fk_user); + $substitarray['__USERID__'] = $user->id; // For backward compatibility + $val2['url'] = make_substitutions($val2['url'], $substitarray); + $relurl2=dol_buildpath($val2['url'],1); - $relurl2=preg_replace('/__LOGIN__/',$user->login,$relurl2); - $relurl2=preg_replace('/__USERID__/',$user->id,$relurl2); $canonurl2=preg_replace('/\?.*$/','',$val2['url']); //var_dump($val2['url'].' - '.$canonurl2.' - '.$val2['level']); if (in_array($canonurl2,array('/admin/index.php','/admin/tools/index.php','/core/tools.php'))) $relurl2=''; diff --git a/htdocs/core/menus/standard/empty.php b/htdocs/core/menus/standard/empty.php index 9de1ee345c2..ce85e583432 100644 --- a/htdocs/core/menus/standard/empty.php +++ b/htdocs/core/menus/standard/empty.php @@ -150,11 +150,13 @@ class MenuManager print '
      '; print '
    • '; + $substitarray = array('__LOGIN__' => $user->login, '__USER_ID__' => $user->id, '__USER_SUPERVISOR_ID__' => $user->fk_user); + $substitarray['__USERID__'] = $user->id; // For backward compatibility + $val['url'] = make_substitutions($val['url'], $substitarray); + if ($val['enabled'] == 1) { $relurl=dol_buildpath($val['url'],1); - $relurl=preg_replace('/__LOGIN__/',$user->login,$relurl); - $relurl=preg_replace('/__USERID__/',$user->id,$relurl); $canonurl=preg_replace('/\?.*$/','',$val['url']); print ''; @@ -249,9 +251,11 @@ class MenuManager if ($showmenu) // Visible (option to hide when not allowed is off or allowed) { + $substitarray = array('__LOGIN__' => $user->login, '__USER_ID__' => $user->id, '__USER_SUPERVISOR_ID__' => $user->fk_user); + $substitarray['__USERID__'] = $user->id; // For backward compatibility + $val2['url'] = make_substitutions($val2['url'], $substitarray); + $relurl2=dol_buildpath($val2['url'],1); - $relurl2=preg_replace('/__LOGIN__/',$user->login,$relurl2); - $relurl2=preg_replace('/__USERID__/',$user->id,$relurl2); $canonurl2=preg_replace('/\?.*$/','',$val2['url']); //var_dump($val2['url'].' - '.$canonurl2.' - '.$val2['level']); if (in_array($canonurl2,array('/admin/index.php','/admin/tools/index.php','/core/tools.php'))) $relurl2=''; @@ -447,11 +451,14 @@ class MenuManager { print '
        '; print '
      • '; + + $substitarray = array('__LOGIN__' => $user->login, '__USER_ID__' => $user->id, '__USER_SUPERVISOR_ID__' => $user->fk_user); + $substitarray['__USERID__'] = $user->id; // For backward compatibility + $val['url'] = make_substitutions($val['url'], $substitarray); + if ($val['enabled'] == 1) { $relurl=dol_buildpath($val['url'],1); - $relurl=preg_replace('/__LOGIN__/',$user->login,$relurl); - $relurl=preg_replace('/__USERID__/',$user->id,$relurl); print ''.$val['titre'].''."\n"; // Search submenu fot this entry @@ -474,9 +481,11 @@ class MenuManager } foreach($submenu->liste as $key2 => $val2) // $val['url','titre','level','enabled'=0|1|2,'target','mainmenu','leftmenu' { + $substitarray = array('__LOGIN__' => $user->login, '__USER_ID__' => $user->id, '__USER_SUPERVISOR_ID__' => $user->fk_user); + $substitarray['__USERID__'] = $user->id; // For backward compatibility + $val2['url'] = make_substitutions($val2['url'], $substitarray); + $relurl2=dol_buildpath($val2['url'],1); - $relurl2=preg_replace('/__LOGIN__/',$user->login,$relurl2); - $relurl2=preg_replace('/__USERID__/',$user->id,$relurl2); //var_dump($val2); print '
      • '.$val2['titre'].'
      • '."\n"; } diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index 32240f778d2..0155634ed25 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -1815,7 +1815,10 @@ class DolibarrModules // Can not be abstract, because we need to insta { $menu = new Menubase($this->db); $menu->menu_handler='all'; + + //$menu->module=strtolower($this->name); TODO When right_class will be same than module name $menu->module=$this->rights_class; + if (! $this->menu[$key]['fk_menu']) { $menu->fk_menu=0; @@ -1909,8 +1912,11 @@ class DolibarrModules // Can not be abstract, because we need to insta $err=0; + //$module=strtolower($this->name); TODO When right_class will be same than module name + $module=$this->rights_class; + $sql = "DELETE FROM ".MAIN_DB_PREFIX."menu"; - $sql.= " WHERE module = '".$this->db->escape($this->rights_class)."'"; + $sql.= " WHERE module = '".$this->db->escape($module)."'"; $sql.= " AND entity = ".$conf->entity; dol_syslog(get_class($this)."::delete_menus", LOG_DEBUG); diff --git a/htdocs/core/modules/barcode/mod_barcode_product_standard.php b/htdocs/core/modules/barcode/mod_barcode_product_standard.php index 1aadf650487..3e233eb1843 100644 --- a/htdocs/core/modules/barcode/mod_barcode_product_standard.php +++ b/htdocs/core/modules/barcode/mod_barcode_product_standard.php @@ -267,14 +267,14 @@ class mod_barcode_product_standard extends ModeleNumRefBarCode { global $conf; - $res = 0; + $result = 0; // Get Mask value $mask = empty($conf->global->BARCODE_STANDARD_PRODUCT_MASK)?'':$conf->global->BARCODE_STANDARD_PRODUCT_MASK; if (! $mask) { $this->error='NotConfigured'; - return ''; + return -1; } dol_syslog(get_class($this).'::verif_syntax codefortest='.$codefortest." typefortest=".$typefortest); @@ -292,6 +292,11 @@ class mod_barcode_product_standard extends ModeleNumRefBarCode } $result=check_value($mask,$newcodefortest); + if (is_string($result)) + { + $this->error = $result; + return -1; + } return $result; } diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php index d1285085014..9a839a826be 100644 --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php @@ -823,7 +823,7 @@ class pdf_crabe extends ModelePDFFactures $sql = "SELECT p.datep as date, p.fk_paiement, p.num_paiement as num, pf.amount as amount, pf.multicurrency_amount,"; $sql.= " cp.code"; $sql.= " FROM ".MAIN_DB_PREFIX."paiement_facture as pf, ".MAIN_DB_PREFIX."paiement as p"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as cp ON p.fk_paiement = cp.id AND cp.entity = " . getEntity('c_paiement'); + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as cp ON p.fk_paiement = cp.id AND cp.entity IN (".getEntity('c_paiement').")"; $sql.= " WHERE pf.fk_paiement = p.rowid AND pf.fk_facture = ".$object->id; //$sql.= " WHERE pf.fk_paiement = p.rowid AND pf.fk_facture = 1"; $sql.= " ORDER BY p.datep"; diff --git a/htdocs/core/modules/mailings/fraise.modules.php b/htdocs/core/modules/mailings/fraise.modules.php index e0226017ede..a1674d6ab08 100644 --- a/htdocs/core/modules/mailings/fraise.modules.php +++ b/htdocs/core/modules/mailings/fraise.modules.php @@ -43,7 +43,6 @@ class mailing_fraise extends MailingTargets var $db; - /** * Constructor * @@ -73,7 +72,7 @@ class mailing_fraise extends MailingTargets $statssql=array(); $statssql[0] ="SELECT '".$this->db->escape($langs->trans("FundationMembers"))."' as label, count(*) as nb"; - $statssql[0].=" FROM ".MAIN_DB_PREFIX."adherent where statut = 1"; + $statssql[0].=" FROM ".MAIN_DB_PREFIX."adherent where statut = 1 and entity IN (".getEntity('member').")"; return $statssql; } @@ -91,7 +90,7 @@ class mailing_fraise extends MailingTargets { $sql = "SELECT count(distinct(a.email)) as nb"; $sql .= " FROM ".MAIN_DB_PREFIX."adherent as a"; - $sql .= " WHERE (a.email IS NOT NULL AND a.email != '')"; + $sql .= " WHERE (a.email IS NOT NULL AND a.email != '') AND a.entity IN (".getEntity('member').")"; // La requete doit retourner un champ "nb" pour etre comprise // par parent::getNbOfRecipients @@ -252,8 +251,8 @@ class mailing_fraise extends MailingTargets $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."categorie as c ON c.rowid = cm.fk_categorie"; } $sql.= " , ".MAIN_DB_PREFIX."adherent_type as ta"; - $sql.= " WHERE a.email <> ''"; // Note that null != '' is false - $sql.= " AND a.email NOT IN (SELECT email FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE fk_mailing=".$mailing_id.")"; + $sql.= " WHERE a.entity IN (".getEntity('member').") AND a.email <> ''"; // Note that null != '' is false + $sql.= " AND a.email NOT IN (SELECT email FROM ".MAIN_DB_PREFIX."mailing_cibles WHERE fk_mailing=".$this->db->escape($mailing_id).")"; // Filter on status if (isset($_POST["filter"]) && $_POST["filter"] == '-1') $sql.= " AND a.statut=-1"; if (isset($_POST["filter"]) && $_POST["filter"] == '1a') $sql.= " AND a.statut=1 AND a.datefin >= '".$this->db->idate($now)."'"; diff --git a/htdocs/core/modules/modAgenda.class.php b/htdocs/core/modules/modAgenda.class.php index a42c3001b44..89085ea4d6c 100644 --- a/htdocs/core/modules/modAgenda.class.php +++ b/htdocs/core/modules/modAgenda.class.php @@ -79,8 +79,13 @@ class modAgenda extends DolibarrModules $this->module_parts = array(); // Constants - //----------- + //----------- + // List of particular constants to add when module is enabled (key, 'chaine', value, desc, visible, 'current' or 'allentities', deleteonunactive) + // Example: $this->const=array(0=>array('MYMODULE_MYNEWCONST1','chaine','myvalue','This is a constant to add',1), + // 1=>array('MYMODULE_MYNEWCONST2','chaine','myvalue','This is another constant to add',0, 'current', 1) + // ); $this->const = array(); + //$this->const[] = array('AGENDA_DEFAULT_FILTER_TYPE', 'chaine', 'AC_NON_AUTO', 'Default filter for type of event on agenda', 0, 'current'); $sqlreadactions="SELECT code, label, description FROM ".MAIN_DB_PREFIX."c_action_trigger ORDER by rang"; $resql = $this->db->query($sqlreadactions); if ($resql) @@ -90,7 +95,7 @@ class modAgenda extends DolibarrModules //if (preg_match('/_CREATE$/',$obj->code) && (! in_array($obj->code, array('COMPANY_CREATE','PRODUCT_CREATE','TASK_CREATE')))) continue; // We don't track such events (*_CREATE) by default, we prefer validation (except thirdparty/product/task creation because there is no validation). if (preg_match('/^TASK_/',$obj->code)) continue; // We don't track such events by default. //if (preg_match('/^_MODIFY/',$obj->code)) continue; // We don't track such events by default. - $this->const[] = array('MAIN_AGENDA_ACTIONAUTO_'.$obj->code, "chaine", "1"); + $this->const[] = array('MAIN_AGENDA_ACTIONAUTO_'.$obj->code, "chaine", "1", '', 0, 'current'); } } else @@ -302,7 +307,7 @@ class modAgenda extends DolibarrModules 'type'=>'left', 'titre'=>'List', 'mainmenu'=>'agenda', - 'url'=>'/comm/action/listactions.php?mainmenu=agenda&leftmenu=agenda', + 'url'=>'/comm/action/list.php?mainmenu=agenda&leftmenu=agenda', 'langs'=>'agenda', 'position'=>110, 'perms'=>'$user->rights->agenda->myactions->read', @@ -314,7 +319,7 @@ class modAgenda extends DolibarrModules 'type'=>'left', 'titre'=>'MenuToDoMyActions', 'mainmenu'=>'agenda', - 'url'=>'/comm/action/listactions.php?mainmenu=agenda&leftmenu=agenda&status=todo&filter=mine', + 'url'=>'/comm/action/list.php?mainmenu=agenda&leftmenu=agenda&status=todo&filter=mine', 'langs'=>'agenda', 'position'=>111, 'perms'=>'$user->rights->agenda->myactions->read', @@ -326,7 +331,7 @@ class modAgenda extends DolibarrModules 'type'=>'left', 'titre'=>'MenuDoneMyActions', 'mainmenu'=>'agenda', - 'url'=>'/comm/action/listactions.php?mainmenu=agenda&leftmenu=agenda&status=done&filter=mine', + 'url'=>'/comm/action/list.php?mainmenu=agenda&leftmenu=agenda&status=done&filter=mine', 'langs'=>'agenda', 'position'=>112, 'perms'=>'$user->rights->agenda->myactions->read', @@ -338,7 +343,7 @@ class modAgenda extends DolibarrModules 'type'=>'left', 'titre'=>'MenuToDoActions', 'mainmenu'=>'agenda', - 'url'=>'/comm/action/listactions.php?mainmenu=agenda&leftmenu=agenda&status=todo&filtert=-1', + 'url'=>'/comm/action/list.php?mainmenu=agenda&leftmenu=agenda&status=todo&filtert=-1', 'langs'=>'agenda', 'position'=>113, 'perms'=>'$user->rights->agenda->allactions->read', @@ -350,7 +355,7 @@ class modAgenda extends DolibarrModules 'type'=>'left', 'titre'=>'MenuDoneActions', 'mainmenu'=>'agenda', - 'url'=>'/comm/action/listactions.php?mainmenu=agenda&leftmenu=agenda&status=done&filtert=-1', + 'url'=>'/comm/action/list.php?mainmenu=agenda&leftmenu=agenda&status=done&filtert=-1', 'langs'=>'agenda', 'position'=>114, 'perms'=>'$user->rights->agenda->allactions->read', diff --git a/htdocs/core/modules/modBarcode.class.php b/htdocs/core/modules/modBarcode.class.php index 69df9843630..da8b51c8e8e 100644 --- a/htdocs/core/modules/modBarcode.class.php +++ b/htdocs/core/modules/modBarcode.class.php @@ -114,7 +114,7 @@ class modBarcode extends DolibarrModules 'url'=>'/barcode/codeinit.php?mainmenu=home&leftmenu=admintools', 'langs'=>'products', // Lang file to use (without .lang) by module. File must be in langs/code_CODE/ directory. 'position'=>300, - 'enabled'=>'$conf->barcode->enabled && ($leftmenu=="admintools" || $leftmenu=="admintools_info")', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. + 'enabled'=>'$conf->barcode->enabled && preg_match(\'/^admintools/\',$leftmenu)', // Define condition to show or hide menu entry. Use '$conf->mymodule->enabled' if entry must be visible if module is enabled. Use '$leftmenu==\'system\'' to show if leftmenu system is selected. 'perms'=>'($conf->global->MAIN_USE_ADVANCED_PERMS && $user->rights->barcode->creer_advance) || (! $conf->global->MAIN_USE_ADVANCED_PERMS)', // Use 'perms'=>'$user->rights->mymodule->level1->level2' if you want your menu with a permission rules 'target'=>'', 'user'=>0); // 0=Menu for internal users, 1=external users, 2=both diff --git a/htdocs/core/modules/modBlockedLog.class.php b/htdocs/core/modules/modBlockedLog.class.php index f26c5fe525f..95d1933cc89 100644 --- a/htdocs/core/modules/modBlockedLog.class.php +++ b/htdocs/core/modules/modBlockedLog.class.php @@ -36,7 +36,7 @@ class modBlockedLog extends DolibarrModules */ function __construct($db) { - global $langs,$conf; + global $langs,$conf,$mysoc; $this->db = $db; $this->numero = 3200; @@ -48,7 +48,7 @@ class modBlockedLog extends DolibarrModules $this->name = preg_replace('/^mod/i','',get_class($this)); $this->description = "Enable a log on some business events into a non reversible log. This module may be mandatory for some countries."; // Possible values for version are: 'development', 'experimental', 'dolibarr' or version - $this->version = 'development'; + $this->version = 'dolibarr'; // Key used in llx_const table to save module status enabled/disabled (where MYMODULE is value of property name of module in uppercase) $this->const_name = 'MAIN_MODULE_'.strtoupper($this->name); // Where to store the module in setup page (0=common,1=interface,2=others,3=very specific) @@ -69,11 +69,25 @@ class modBlockedLog extends DolibarrModules $this->depends = array('always'=>'modFacture'); // List of modules id that must be enabled if this module is enabled $this->requiredby = array(); // List of modules id to disable if this one is disabled $this->conflictwith = array(); // List of modules id this module is in conflict with - $this->langfiles = array(); + $this->langfiles = array('blockedlog'); + + $this->warnings_activation = array(); // Warning to show when we activate module. array('always'='text') or array('FR'='textfr','ES'='textes'...) + $this->warnings_activation_ext = array(); // Warning to show when we activate an external module. array('always'='text') or array('FR'='textfr','ES'='textes'...) + $this->warnings_unactivation = array('FR'=>'BlockedLogAreRequiredByYourCountryLegislation'); + + // Currently, activation is not automatic because only companies (in France) making invoices to non business customers must + // enable this module. + // It is automatic only if $conf->global->BLOCKEDLOG_DISABLE_NOT_ALLOWED_FOR_COUNTRY is on. + if (! empty($conf->global->BLOCKEDLOG_DISABLE_NOT_ALLOWED_FOR_COUNTRY)) + { + $this->automatic_activation = array('FR'=>'BlockedLogActivatedBecauseRequiredByYourCountryLegislation'); + } + + $this->always_enabled = !empty($conf->blockedlog->enabled) && !empty($conf->global->BLOCKEDLOG_DISABLE_NOT_ALLOWED_FOR_COUNTRY) && in_array($mysoc->country_code, explode(',', $conf->global->BLOCKEDLOG_DISABLE_NOT_ALLOWED_FOR_COUNTRY)); // Constants //----------- - + $this->const = array(); // New pages on tabs // ----------------- @@ -87,4 +101,51 @@ class modBlockedLog extends DolibarrModules //------------------ $this->menu = array(); } + + /** + * Check if module was already used before unactivation linked to warnings_unactivation property + */ + function alreadyUsed() { + + $res = $this->db->query("SELECT count(*) as nb FROM ".MAIN_DB_PREFIX."blockedlog"); + if($res!==false) { + $obj = $this->db->fetch_object($res); + return ($obj->nb > 0); + } + + return false; + } + + /** + * Function called when module is disabled. + * The remove function removes tabs, constants, boxes, permissions and menus from Dolibarr database. + * Data directories are not deleted + * + * @param string $options Options when enabling module ('', 'noboxes') + * @return int 1 if OK, 0 if KO + */ + function remove($options = '') { + + global $user; + + require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php'; + + $object=new stdClass; + $object->id = 1; + $object->element = 'module'; + $object->ref = 'module'; + $object->date = dol_now(); + + $b=new BlockedLog($this->db); + $b->setObjectData($object, 'MODULE_RESET', -1); + + $res = $b->create($user); + if($res<=0) { + $this->error = $b->error; + return $res; + } + + return $this->_remove(array(), $options); + + } } diff --git a/htdocs/core/modules/modExternalSite.class.php b/htdocs/core/modules/modExternalSite.class.php index 620fc53b53f..388bc340776 100644 --- a/htdocs/core/modules/modExternalSite.class.php +++ b/htdocs/core/modules/modExternalSite.class.php @@ -104,7 +104,7 @@ class modExternalSite extends DolibarrModules $this->menu[$r]=array( 'fk_menu'=>0, 'type'=>'top', - 'titre'=>'$conf->global->EXTERNALSITE_LABEL', + 'titre'=>'__[EXTERNALSITE_LABEL]__', 'mainmenu'=>'externalsite', 'url'=>'/externalsite/frames.php', 'langs'=>'other', diff --git a/htdocs/core/modules/modFacture.class.php b/htdocs/core/modules/modFacture.class.php index 53f23265d6b..04628560d74 100644 --- a/htdocs/core/modules/modFacture.class.php +++ b/htdocs/core/modules/modFacture.class.php @@ -128,14 +128,14 @@ class modFacture extends DolibarrModules $r++; $this->rights[$r][0] = 11; - $this->rights[$r][1] = 'Lire les factures'; + $this->rights[$r][1] = 'Read invoices'; $this->rights[$r][2] = 'a'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'lire'; $r++; $this->rights[$r][0] = 12; - $this->rights[$r][1] = 'Creer/modifier les factures'; + $this->rights[$r][1] = 'Create and update invoices'; $this->rights[$r][2] = 'a'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'creer'; @@ -143,7 +143,7 @@ class modFacture extends DolibarrModules // There is a particular permission for unvalidate because this may be not forbidden by some laws $r++; $this->rights[$r][0] = 13; - $this->rights[$r][1] = 'Dévalider les factures'; + $this->rights[$r][1] = 'Devalidate invoices'; $this->rights[$r][2] = 'a'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'invoice_advance'; @@ -151,7 +151,7 @@ class modFacture extends DolibarrModules $r++; $this->rights[$r][0] = 14; - $this->rights[$r][1] = 'Valider les factures'; + $this->rights[$r][1] = 'Validate invoices'; $this->rights[$r][2] = 'a'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'invoice_advance'; @@ -159,7 +159,7 @@ class modFacture extends DolibarrModules $r++; $this->rights[$r][0] = 15; - $this->rights[$r][1] = 'Envoyer les factures par mail'; + $this->rights[$r][1] = 'Send invoices by email'; $this->rights[$r][2] = 'a'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'invoice_advance'; @@ -167,21 +167,21 @@ class modFacture extends DolibarrModules $r++; $this->rights[$r][0] = 16; - $this->rights[$r][1] = 'Emettre des paiements sur les factures'; + $this->rights[$r][1] = 'Issue payments on invoices'; $this->rights[$r][2] = 'a'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'paiement'; $r++; $this->rights[$r][0] = 19; - $this->rights[$r][1] = 'Supprimer les factures'; + $this->rights[$r][1] = 'Delete invoices'; $this->rights[$r][2] = 'a'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'supprimer'; $r++; $this->rights[$r][0] = 1321; - $this->rights[$r][1] = 'Exporter les factures clients, attributs et reglements'; + $this->rights[$r][1] = 'Export customer invoices, attributes and payments'; $this->rights[$r][2] = 'r'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'facture'; @@ -189,7 +189,7 @@ class modFacture extends DolibarrModules $r++; $this->rights[$r][0] = 1322; - $this->rights[$r][1] = 'Rouvrir une facture totalement réglée'; + $this->rights[$r][1] = 'Re-open a fully paid invoice'; $this->rights[$r][2] = 'r'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'invoice_advance'; @@ -260,7 +260,7 @@ class modFacture extends DolibarrModules $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'facture_extrafields as extra ON f.rowid = extra.fk_object'; $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'paiement_facture as pf ON pf.fk_facture = f.rowid'; $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'paiement as p ON pf.fk_paiement = p.rowid'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as pt ON pt.id = p.fk_paiement AND pt.entity IN (' . getEntity('c_paiement').')'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as pt ON pt.id = p.fk_paiement AND pt.entity IN ('.getEntity('c_paiement').')'; $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON b.rowid = p.fk_bank'; $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON ba.rowid = b.fk_account'; $this->export_sql_end[$r] .=' WHERE f.fk_soc = s.rowid'; diff --git a/htdocs/core/modules/modModuleBuilder.class.php b/htdocs/core/modules/modModuleBuilder.class.php index 944664f2339..d14a37f3bdb 100644 --- a/htdocs/core/modules/modModuleBuilder.class.php +++ b/htdocs/core/modules/modModuleBuilder.class.php @@ -92,7 +92,7 @@ class modModuleBuilder extends DolibarrModules 'titre'=>'ModuleBuilder', 'mainmenu'=>'home', 'leftmenu'=>'admintools_modulebuilder', - 'url'=>'/modulebuilder/index.php?mainmenu=home&leftmenu=admintools_modulebuilder', + 'url'=>'/modulebuilder/index.php?mainmenu=home&leftmenu=admintools', 'langs'=>'modulebuilder', 'position'=>100, 'perms'=>'1', diff --git a/htdocs/core/modules/modOauth.class.php b/htdocs/core/modules/modOauth.class.php index 4d64c666c60..0dce715a9f4 100644 --- a/htdocs/core/modules/modOauth.class.php +++ b/htdocs/core/modules/modOauth.class.php @@ -139,6 +139,8 @@ class modOauth extends DolibarrModules // Clean before activation $this->remove($options); - return $this->_init($sql,$options); + $sql = array(); + + return $this->_init($sql, $options); } } diff --git a/htdocs/core/modules/modProjet.class.php b/htdocs/core/modules/modProjet.class.php index af71ccc4360..6c4ecf8098e 100644 --- a/htdocs/core/modules/modProjet.class.php +++ b/htdocs/core/modules/modProjet.class.php @@ -188,7 +188,7 @@ class modProjet extends DolibarrModules $r++; $this->rights[$r][0] = 142; // id de la permission - $this->rights[$r][1] = "Create/modify all projects and tasks (also private projects I am not contact for)"; // libelle de la permission + $this->rights[$r][1] = "Create/modify all projects and tasks (also private projects I am not contact for). Can also enter time consumed on assigned tasks (timesheet)"; // libelle de la permission $this->rights[$r][2] = 'w'; // type de la permission (deprecie a ce jour) $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut $this->rights[$r][4] = 'all'; diff --git a/htdocs/core/modules/modPropale.class.php b/htdocs/core/modules/modPropale.class.php index 43ba37aa26e..a6b38f7d5ff 100644 --- a/htdocs/core/modules/modPropale.class.php +++ b/htdocs/core/modules/modPropale.class.php @@ -77,14 +77,14 @@ class modPropale extends DolibarrModules $this->const[$r][0] = "PROPALE_ADDON_PDF"; $this->const[$r][1] = "chaine"; $this->const[$r][2] = "azur"; - $this->const[$r][3] = 'Nom du gestionnaire de generation des propales en PDF'; + $this->const[$r][3] = 'Name of the proposal generation manager in PDF format'; $this->const[$r][4] = 0; $r++; $this->const[$r][0] = "PROPALE_ADDON"; $this->const[$r][1] = "chaine"; $this->const[$r][2] = "mod_propale_marbre"; - $this->const[$r][3] = 'Nom du gestionnaire de numerotation des propales'; + $this->const[$r][3] = 'Name of proposal numbering manager'; $this->const[$r][4] = 0; $r++; @@ -121,21 +121,21 @@ class modPropale extends DolibarrModules $r++; $this->rights[$r][0] = 21; // id de la permission - $this->rights[$r][1] = 'Lire les propositions commerciales'; // libelle de la permission + $this->rights[$r][1] = 'Read commercial proposals'; // libelle de la permission $this->rights[$r][2] = 'r'; // type de la permission (deprecie a ce jour) $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut $this->rights[$r][4] = 'lire'; $r++; $this->rights[$r][0] = 22; // id de la permission - $this->rights[$r][1] = 'Creer/modifier les propositions commerciales'; // libelle de la permission + $this->rights[$r][1] = 'Create and update commercial proposals'; // libelle de la permission $this->rights[$r][2] = 'w'; // type de la permission (deprecie a ce jour) $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut $this->rights[$r][4] = 'creer'; $r++; $this->rights[$r][0] = 24; // id de la permission - $this->rights[$r][1] = 'Valider les propositions commerciales'; // libelle de la permission + $this->rights[$r][1] = 'Validate commercial proposals'; // libelle de la permission $this->rights[$r][2] = 'd'; // type de la permission (deprecie a ce jour) $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut $this->rights[$r][4] = 'propal_advance'; @@ -143,7 +143,7 @@ class modPropale extends DolibarrModules $r++; $this->rights[$r][0] = 25; // id de la permission - $this->rights[$r][1] = 'Envoyer les propositions commerciales aux clients'; // libelle de la permission + $this->rights[$r][1] = 'Send commercial proposals to customers'; // libelle de la permission $this->rights[$r][2] = 'd'; // type de la permission (deprecie a ce jour) $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut $this->rights[$r][4] = 'propal_advance'; @@ -151,21 +151,21 @@ class modPropale extends DolibarrModules $r++; $this->rights[$r][0] = 26; // id de la permission - $this->rights[$r][1] = 'Cloturer les propositions commerciales'; // libelle de la permission + $this->rights[$r][1] = 'Close commercial proposals'; // libelle de la permission $this->rights[$r][2] = 'd'; // type de la permission (deprecie a ce jour) $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut $this->rights[$r][4] = 'cloturer'; $r++; $this->rights[$r][0] = 27; // id de la permission - $this->rights[$r][1] = 'Supprimer les propositions commerciales'; // libelle de la permission + $this->rights[$r][1] = 'Delete commercial proposals'; // libelle de la permission $this->rights[$r][2] = 'd'; // type de la permission (deprecie a ce jour) $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut $this->rights[$r][4] = 'supprimer'; $r++; $this->rights[$r][0] = 28; // id de la permission - $this->rights[$r][1] = 'Exporter les propositions commerciales et attributs'; // libelle de la permission + $this->rights[$r][1] = 'Exporting commercial proposals and attributes'; // libelle de la permission $this->rights[$r][2] = 'r'; // type de la permission (deprecie a ce jour) $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut $this->rights[$r][4] = 'export'; diff --git a/htdocs/core/modules/modResource.class.php b/htdocs/core/modules/modResource.class.php index dd09b148453..148dbece597 100644 --- a/htdocs/core/modules/modResource.class.php +++ b/htdocs/core/modules/modResource.class.php @@ -227,7 +227,7 @@ class modResource extends DolibarrModules 'titre'=> 'MenuResourceAdd', 'mainmenu'=> 'tools', 'leftmenu'=> 'resource_add', - 'url'=> '/resource/add.php', + 'url'=> '/resource/card.php?action=create', 'langs'=> 'resource', 'position'=> 101, 'enabled'=> '1', diff --git a/htdocs/core/modules/modSalaries.class.php b/htdocs/core/modules/modSalaries.class.php index 27bad86856c..e037b35728e 100644 --- a/htdocs/core/modules/modSalaries.class.php +++ b/htdocs/core/modules/modSalaries.class.php @@ -165,7 +165,7 @@ class modSalaries extends DolibarrModules $this->export_sql_start[$r]='SELECT DISTINCT '; $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'user as u'; $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'payment_salary as p ON p.fk_user = u.rowid'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as cp ON p.fk_typepayment = cp.id AND cp.entity IN (' . getEntity('c_paiement').')'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as cp ON p.fk_typepayment = cp.id AND cp.entity IN ('.getEntity('c_paiement').')'; $this->export_sql_end[$r] .=' AND u.entity IN ('.getEntity('user').')'; } diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php index 15a4834c7d8..897a954a88f 100644 --- a/htdocs/core/modules/modSociete.class.php +++ b/htdocs/core/modules/modSociete.class.php @@ -52,7 +52,7 @@ class modSociete extends DolibarrModules $this->module_position = 10; // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) $this->name = preg_replace('/^mod/i','',get_class($this)); - $this->description = "Gestion des societes et contacts"; + $this->description = "Gestion des sociétés et contacts"; // Possible values for version are: 'development', 'experimental', 'dolibarr' or version $this->version = 'dolibarr'; @@ -92,7 +92,7 @@ class modSociete extends DolibarrModules $this->const[$r][0] = "SOCIETE_FISCAL_MONTH_START"; $this->const[$r][1] = "chaine"; $this->const[$r][2] = "0"; - $this->const[$r][3] = "Mettre le numero du mois du debut d\'annee fiscale, ex: 9 pour septembre"; + $this->const[$r][3] = "Enter the month number of the first month of the fiscal year, e. g. 9 for September"; $this->const[$r][4] = 0; $r++; @@ -141,7 +141,7 @@ class modSociete extends DolibarrModules $r++; $this->rights[$r][0] = 121; // id de la permission - $this->rights[$r][1] = 'Lire les societes'; // libelle de la permission + $this->rights[$r][1] = 'Read third parties'; // libelle de la permission $this->rights[$r][2] = 'r'; // type de la permission (deprecie a ce jour) $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut $this->rights[$r][4] = 'lire'; @@ -165,7 +165,7 @@ class modSociete extends DolibarrModules $r++; $this->rights[$r][0] = 122; // id de la permission - $this->rights[$r][1] = 'Creer modifier les societes'; // libelle de la permission + $this->rights[$r][1] = 'Create and update third parties'; // libelle de la permission $this->rights[$r][2] = 'w'; // type de la permission (deprecie a ce jour) $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut $this->rights[$r][4] = 'creer'; @@ -189,14 +189,14 @@ class modSociete extends DolibarrModules $r++; $this->rights[$r][0] = 125; // id de la permission - $this->rights[$r][1] = 'Supprimer les societes'; // libelle de la permission + $this->rights[$r][1] = 'Delete third parties'; // libelle de la permission $this->rights[$r][2] = 'd'; // type de la permission (deprecie a ce jour) $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut $this->rights[$r][4] = 'supprimer'; $r++; $this->rights[$r][0] = 126; // id de la permission - $this->rights[$r][1] = 'Exporter les societes'; // libelle de la permission + $this->rights[$r][1] = 'Export third parties'; // libelle de la permission $this->rights[$r][2] = 'r'; // type de la permission (deprecie a ce jour) $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut $this->rights[$r][4] = 'export'; @@ -204,7 +204,7 @@ class modSociete extends DolibarrModules // 262 : Resteindre l'acces des commerciaux $r++; $this->rights[$r][0] = 262; - $this->rights[$r][1] = 'Consulter tous les tiers par utilisateurs internes (sinon uniquement si contact commercial). Non effectif pour utilisateurs externes (tjs limités à eux-meme).'; + $this->rights[$r][1] = 'Read all third parties by internal users (otherwise only if commercial contact). Not effective for external users (limited to themselves).'; $this->rights[$r][2] = 'r'; $this->rights[$r][3] = 0; $this->rights[$r][4] = 'client'; @@ -212,7 +212,7 @@ class modSociete extends DolibarrModules $r++; $this->rights[$r][0] = 281; // id de la permission - $this->rights[$r][1] = 'Lire les contacts'; // libelle de la permission + $this->rights[$r][1] = 'Read contacts'; // libelle de la permission $this->rights[$r][2] = 'r'; // type de la permission (deprecie a ce jour) $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut $this->rights[$r][4] = 'contact'; @@ -220,7 +220,7 @@ class modSociete extends DolibarrModules $r++; $this->rights[$r][0] = 282; // id de la permission - $this->rights[$r][1] = 'Creer modifier les contacts'; // libelle de la permission + $this->rights[$r][1] = 'Create and update contact'; // libelle de la permission $this->rights[$r][2] = 'w'; // type de la permission (deprecie a ce jour) $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut $this->rights[$r][4] = 'contact'; @@ -228,7 +228,7 @@ class modSociete extends DolibarrModules $r++; $this->rights[$r][0] = 283; // id de la permission - $this->rights[$r][1] = 'Supprimer les contacts'; // libelle de la permission + $this->rights[$r][1] = 'Delete contacts'; // libelle de la permission $this->rights[$r][2] = 'd'; // type de la permission (deprecie a ce jour) $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut $this->rights[$r][4] = 'contact'; @@ -236,7 +236,7 @@ class modSociete extends DolibarrModules $r++; $this->rights[$r][0] = 286; // id de la permission - $this->rights[$r][1] = 'Exporter les contacts'; // libelle de la permission + $this->rights[$r][1] = 'Export contacts'; // libelle de la permission $this->rights[$r][2] = 'd'; // type de la permission (deprecie a ce jour) $this->rights[$r][3] = 0; // La permission est-elle une permission par defaut $this->rights[$r][4] = 'contact'; @@ -284,8 +284,8 @@ class modSociete extends DolibarrModules $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_departements as d ON s.fk_departement = d.rowid'; $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_stcomm as st ON s.fk_stcomm = st.id'; $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'societe_commerciaux as sc ON sc.fk_soc = s.rowid LEFT JOIN '.MAIN_DB_PREFIX.'user as u ON sc.fk_user = u.rowid'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as payterm ON s.cond_reglement = payterm.rowid AND payterm.entity IN (' . getEntity('c_payment_term').')'; - $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as paymode ON s.mode_reglement = paymode.id AND paymode.entity IN (' . getEntity('c_paiement').')'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_payment_term as payterm ON s.cond_reglement = payterm.rowid AND payterm.entity IN ('.getEntity('c_payment_term').')'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as paymode ON s.mode_reglement = paymode.id AND paymode.entity IN ('.getEntity('c_paiement').')'; $this->export_sql_end[$r] .=' WHERE s.entity IN ('.getEntity('societe').')'; if (is_object($user) && empty($user->rights->societe->client->voir)) { $this->export_sql_end[$r] .=' AND (sc.fk_user = '.$user->id.' '; diff --git a/htdocs/core/modules/modStock.class.php b/htdocs/core/modules/modStock.class.php index e31b15d81dd..c23a02eeac1 100644 --- a/htdocs/core/modules/modStock.class.php +++ b/htdocs/core/modules/modStock.class.php @@ -168,9 +168,9 @@ class modStock extends DolibarrModules $this->export_code[$r]=$this->rights_class; $this->export_label[$r]="WarehousesAndProducts"; // Translation key (used only if key ExportDataset_xxx_z not found) $this->export_permission[$r]=array(array("stock","lire")); - $this->export_fields_array[$r]=array('e.rowid'=>'IdWarehouse','e.label'=>'LocationSummary','e.description'=>'DescWareHouse','e.lieu'=>'LieuWareHouse','e.address'=>'Address','e.zip'=>'Zip','e.town'=>'Town','p.rowid'=>"ProductId",'p.ref'=>"Ref",'p.fk_product_type'=>"Type",'p.label'=>"Label",'p.description'=>"Description",'p.note'=>"Note",'p.price'=>"Price",'p.tva_tx'=>'VAT','p.tosell'=>"OnSell",'p.tobuy'=>'OnBuy','p.duration'=>"Duration",'p.datec'=>'DateCreation','p.tms'=>'DateModification','ps.reel'=>'Stock'); - $this->export_TypeFields_array[$r]=array('e.rowid'=>'List:entrepot:label','e.label'=>'Text','e.lieu'=>'Text','e.address'=>'Text','e.zip'=>'Text','e.town'=>'Text','p.rowid'=>"List:product:label",'p.ref'=>"Text",'p.fk_product_type'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.note'=>"Text",'p.price'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean",'p.duration'=>"Duree",'p.datec'=>'Date','p.tms'=>'Date','ps.reel'=>'Numeric'); - $this->export_entities_array[$r]=array('e.rowid'=>'warehouse','e.label'=>'warehouse','e.description'=>'warehouse','e.lieu'=>'warehouse','e.address'=>'warehouse','e.zip'=>'warehouse','e.town'=>'warehouse','p.rowid'=>"product",'p.ref'=>"product",'p.fk_product_type'=>"product",'p.label'=>"product",'p.description'=>"product",'p.note'=>"product",'p.price'=>"product",'p.tva_tx'=>'product','p.tosell'=>"product",'p.tobuy'=>"product",'p.duration'=>"product",'p.datec'=>'product','p.tms'=>'product','ps.reel'=>'stock'); + $this->export_fields_array[$r]=array('e.rowid'=>'IdWarehouse','e.ref'=>'LocationSummary','e.description'=>'DescWareHouse','e.lieu'=>'LieuWareHouse','e.address'=>'Address','e.zip'=>'Zip','e.town'=>'Town','p.rowid'=>"ProductId",'p.ref'=>"Ref",'p.fk_product_type'=>"Type",'p.label'=>"Label",'p.description'=>"Description",'p.note'=>"Note",'p.price'=>"Price",'p.tva_tx'=>'VAT','p.tosell'=>"OnSell",'p.tobuy'=>'OnBuy','p.duration'=>"Duration",'p.datec'=>'DateCreation','p.tms'=>'DateModification','p.pmp'=>'PMPValue','p.cost_price'=>'CostPrice','ps.reel'=>'Stock'); + $this->export_TypeFields_array[$r]=array('e.rowid'=>'List:entrepot:ref','e.ref'=>'Text','e.lieu'=>'Text','e.address'=>'Text','e.zip'=>'Text','e.town'=>'Text','p.rowid'=>"List:product:label",'p.ref'=>"Text",'p.fk_product_type'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.note'=>"Text",'p.price'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean",'p.duration'=>"Duree",'p.datec'=>'Date','p.tms'=>'Date','p.pmp'=>'Numeric','p.cost_price'=>'Numeric','ps.reel'=>'Numeric'); + $this->export_entities_array[$r]=array('e.rowid'=>'warehouse','e.ref'=>'warehouse','e.description'=>'warehouse','e.lieu'=>'warehouse','e.address'=>'warehouse','e.zip'=>'warehouse','e.town'=>'warehouse','p.rowid'=>"product",'p.ref'=>"product",'p.fk_product_type'=>"product",'p.label'=>"product",'p.description'=>"product",'p.note'=>"product",'p.price'=>"product",'p.tva_tx'=>'product','p.tosell'=>"product",'p.tobuy'=>"product",'p.duration'=>"product",'p.datec'=>'product','p.tms'=>'product','p.pmp'=>'product','p.cost_price'=>'product','ps.reel'=>'stock'); $this->export_aggregate_array[$r]=array('ps.reel'=>'SUM'); // TODO Not used yet $this->export_dependencies_array[$r]=array('stock'=>array('p.rowid','e.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 '; @@ -188,13 +188,18 @@ class modStock extends DolibarrModules $this->export_code[$r]=$this->rights_class.'_lot'; $this->export_label[$r]="WarehousesAndProductsBatchDetail"; // Translation key (used only if key ExportDataset_xxx_z not found) $this->export_permission[$r]=array(array("stock","lire")); - $this->export_fields_array[$r]=array('e.rowid'=>'IdWarehouse','e.label'=>'LocationSummary','e.description'=>'DescWareHouse','e.lieu'=>'LieuWareHouse','e.address'=>'Address','e.zip'=>'Zip','e.town'=>'Town','p.rowid'=>"ProductId",'p.ref'=>"Ref",'p.fk_product_type'=>"Type",'p.label'=>"Label",'p.description'=>"Description",'p.note'=>"Note",'p.price'=>"Price",'p.tva_tx'=>'VAT','p.tosell'=>"OnSell",'p.tobuy'=>'OnBuy','p.duration'=>"Duration",'p.datec'=>'DateCreation','p.tms'=>'DateModification','pb.rowid'=>'Id','pb.batch'=>'Batch','pb.eatby'=>'EatByDate','pb.sellby'=>'SellByDate','pb.qty'=>'Qty'); - $this->export_TypeFields_array[$r]=array('e.rowid'=>'List:entrepot:label','e.label'=>'Text','e.lieu'=>'Text','e.address'=>'Text','e.zip'=>'Text','e.town'=>'Text','p.rowid'=>"List:product:label",'p.ref'=>"Text",'p.fk_product_type'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.note'=>"Text",'p.price'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean",'p.duration'=>"Duree",'p.datec'=>'Date','p.tms'=>'Date','pb.batch'=>'Text','pb.eatby'=>'Date','pb.sellby'=>'Date','pb.qty'=>'Numeric'); - $this->export_entities_array[$r]=array('e.rowid'=>'warehouse','e.label'=>'warehouse','e.description'=>'warehouse','e.lieu'=>'warehouse','e.address'=>'warehouse','e.zip'=>'warehouse','e.town'=>'warehouse','p.rowid'=>"product",'p.ref'=>"product",'p.fk_product_type'=>"product",'p.label'=>"product",'p.description'=>"product",'p.note'=>"product",'p.price'=>"product",'p.tva_tx'=>'product','p.tosell'=>"product",'p.tobuy'=>"product",'p.duration'=>"product",'p.datec'=>'product','p.tms'=>'product','pb.rowid'=>'batch','pb.batch'=>'batch','pb.eatby'=>'batch','pb.sellby'=>'batch','pb.qty'=>'batch'); + $this->export_fields_array[$r]=array('e.rowid'=>'IdWarehouse','e.ref'=>'LocationSummary','e.description'=>'DescWareHouse','e.lieu'=>'LieuWareHouse','e.address'=>'Address','e.zip'=>'Zip','e.town'=>'Town','p.rowid'=>"ProductId",'p.ref'=>"Ref",'p.fk_product_type'=>"Type",'p.label'=>"Label",'p.description'=>"Description",'p.note'=>"Note",'p.price'=>"Price",'p.tva_tx'=>'VAT','p.tosell'=>"OnSell",'p.tobuy'=>'OnBuy','p.duration'=>"Duration",'p.datec'=>'DateCreation','p.tms'=>'DateModification','pb.rowid'=>'Id','pb.batch'=>'Batch','pb.qty'=>'Qty','pl.eatby'=>'EatByDate','pl.sellby'=>'SellByDate'); + $this->export_TypeFields_array[$r]=array('e.rowid'=>'List:entrepot:ref','e.ref'=>'Text','e.lieu'=>'Text','e.description'=>'Text','e.address'=>'Text','e.zip'=>'Text','e.town'=>'Text','p.rowid'=>"List:product:label",'p.ref'=>"Text",'p.fk_product_type'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.note'=>"Text",'p.price'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean",'p.duration'=>"Duree",'p.datec'=>'Date','p.tms'=>'Date','pb.batch'=>'Text','pb.qty'=>'Numeric','pl.eatby'=>'Date','pl.sellby'=>'Date'); + $this->export_entities_array[$r]=array('e.rowid'=>'warehouse','e.ref'=>'warehouse','e.description'=>'warehouse','e.lieu'=>'warehouse','e.address'=>'warehouse','e.zip'=>'warehouse','e.town'=>'warehouse','p.rowid'=>"product",'p.ref'=>"product",'p.fk_product_type'=>"product",'p.label'=>"product",'p.description'=>"product",'p.note'=>"product",'p.price'=>"product",'p.tva_tx'=>'product','p.tosell'=>"product",'p.tobuy'=>"product",'p.duration'=>"product",'p.datec'=>'product','p.tms'=>'product','pb.rowid'=>'stockbatch','pb.batch'=>'stockbatch','pb.qty'=>'stockbatch','pl.eatby'=>'batch','pl.sellby'=>'batch'); $this->export_aggregate_array[$r]=array('ps.reel'=>'SUM'); // TODO Not used yet - $this->export_dependencies_array[$r]=array('batch'=>array('pb.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_dependencies_array[$r]=array('stockbatch'=>array('pb.rowid'),'batch'=>array('pb.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. + $keyforselect='product_lot'; $keyforelement='batch'; $keyforaliasextra='extra'; + include DOL_DOCUMENT_ROOT.'/core/extrafieldsinexport.inc.php'; $this->export_sql_start[$r]='SELECT DISTINCT '; - $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'product as p, '.MAIN_DB_PREFIX.'product_stock as ps, '.MAIN_DB_PREFIX.'entrepot as e, '.MAIN_DB_PREFIX.'product_batch as pb'; + $this->export_sql_end[$r] =' FROM ('.MAIN_DB_PREFIX.'product as p, '.MAIN_DB_PREFIX.'product_stock as ps, '.MAIN_DB_PREFIX.'product_batch as pb)'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_lot as pl ON pl.fk_product = p.rowid AND pl.batch = pb.batch'; + $this->export_sql_end[$r] .=' LEFT JOIN '.MAIN_DB_PREFIX.'product_lot_extrafields as extra ON extra.fk_object = pl.rowid,'; + $this->export_sql_end[$r] .=' '.MAIN_DB_PREFIX.'entrepot as e'; $this->export_sql_end[$r] .=' WHERE p.rowid = ps.fk_product AND ps.fk_entrepot = e.rowid AND ps.rowid = pb.fk_product_stock'; $this->export_sql_end[$r] .=' AND e.entity IN ('.getEntity('stock').')'; } @@ -203,9 +208,9 @@ class modStock extends DolibarrModules $this->export_code[$r]=$this->rights_class.'_movement'; $this->export_label[$r]="StockMovements"; // Translation key (used only if key ExportDataset_xxx_z not found) $this->export_permission[$r]=array(array("stock","lire")); - $this->export_fields_array[$r]=array('e.rowid'=>'IdWarehouse','e.label'=>'LocationSummary','e.description'=>'DescWareHouse','e.lieu'=>'LieuWareHouse','e.address'=>'Address','e.zip'=>'Zip','e.town'=>'Town','p.rowid'=>"ProductId",'p.ref'=>"Ref",'p.fk_product_type'=>"Type",'p.label'=>"Label",'p.description'=>"Description",'p.note'=>"Note",'p.price'=>"Price",'p.tva_tx'=>'VAT','p.tosell'=>"OnSell",'p.tobuy'=>'OnBuy','p.duration'=>"Duration",'p.datec'=>'DateCreation','p.tms'=>'DateModification','sm.rowid'=>'MovementId','sm.value'=>'Qty','sm.datem'=>'DateMovement','sm.label'=>'LabelMovement','sm.inventorycode'=>'InventoryCode'); - $this->export_TypeFields_array[$r]=array('e.rowid'=>'List:entrepot:label','e.label'=>'Text','e.lieu'=>'Text','e.address'=>'Text','e.zip'=>'Text','e.town'=>'Text','p.rowid'=>"List:product:label",'p.ref'=>"Text",'p.fk_product_type'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.note'=>"Text",'p.price'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean",'p.duration'=>"Duree",'p.datec'=>'Date','p.tms'=>'Date','sm.rowid'=>'Numeric','sm.value'=>'Numeric','sm.datem'=>'Date','sm.batch'=>'Text','sm.label'=>'Text','sm.inventorycode'=>'Text'); - $this->export_entities_array[$r]=array('e.rowid'=>'warehouse','e.label'=>'warehouse','e.description'=>'warehouse','e.lieu'=>'warehouse','e.address'=>'warehouse','e.zip'=>'warehouse','e.town'=>'warehouse','p.rowid'=>"product",'p.ref'=>"product",'p.fk_product_type'=>"product",'p.label'=>"product",'p.description'=>"product",'p.note'=>"product",'p.price'=>"product",'p.tva_tx'=>'product','p.tosell'=>"product",'p.tobuy'=>"product",'p.duration'=>"product",'p.datec'=>'product','p.tms'=>'product','sm.rowid'=>'movement','sm.value'=>'movement','sm.datem'=>'movement','sm.label'=>'movement','sm.inventorycode'=>'movement'); + $this->export_fields_array[$r]=array('e.rowid'=>'IdWarehouse','e.ref'=>'LocationSummary','e.description'=>'DescWareHouse','e.lieu'=>'LieuWareHouse','e.address'=>'Address','e.zip'=>'Zip','e.town'=>'Town','p.rowid'=>"ProductId",'p.ref'=>"Ref",'p.fk_product_type'=>"Type",'p.label'=>"Label",'p.description'=>"Description",'p.note'=>"Note",'p.price'=>"Price",'p.tva_tx'=>'VAT','p.tosell'=>"OnSell",'p.tobuy'=>'OnBuy','p.duration'=>"Duration",'p.datec'=>'DateCreation','p.tms'=>'DateModification','sm.rowid'=>'MovementId','sm.value'=>'Qty','sm.datem'=>'DateMovement','sm.label'=>'LabelMovement','sm.inventorycode'=>'InventoryCode'); + $this->export_TypeFields_array[$r]=array('e.rowid'=>'List:entrepot:ref','e.ref'=>'Text','e.description'=>'Text','e.lieu'=>'Text','e.address'=>'Text','e.zip'=>'Text','e.town'=>'Text','p.rowid'=>"List:product:label",'p.ref'=>"Text",'p.fk_product_type'=>"Text",'p.label'=>"Text",'p.description'=>"Text",'p.note'=>"Text",'p.price'=>"Numeric",'p.tva_tx'=>'Numeric','p.tosell'=>"Boolean",'p.tobuy'=>"Boolean",'p.duration'=>"Duree",'p.datec'=>'Date','p.tms'=>'Date','sm.rowid'=>'Numeric','sm.value'=>'Numeric','sm.datem'=>'Date','sm.batch'=>'Text','sm.label'=>'Text','sm.inventorycode'=>'Text'); + $this->export_entities_array[$r]=array('e.rowid'=>'warehouse','e.ref'=>'warehouse','e.description'=>'warehouse','e.lieu'=>'warehouse','e.address'=>'warehouse','e.zip'=>'warehouse','e.town'=>'warehouse','p.rowid'=>"product",'p.ref'=>"product",'p.fk_product_type'=>"product",'p.label'=>"product",'p.description'=>"product",'p.note'=>"product",'p.price'=>"product",'p.tva_tx'=>'product','p.tosell'=>"product",'p.tobuy'=>"product",'p.duration'=>"product",'p.datec'=>'product','p.tms'=>'product','sm.rowid'=>'movement','sm.value'=>'movement','sm.datem'=>'movement','sm.label'=>'movement','sm.inventorycode'=>'movement'); if ($conf->productbatch->enabled) { $this->export_fields_array[$r]['sm.batch']='Batch'; @@ -232,7 +237,7 @@ class modStock extends DolibarrModules $this->import_entities_array[$r]=array(); // We define here only fields that use another icon that the one defined into import_icon $this->import_tables_array[$r]=array('e'=>MAIN_DB_PREFIX.'entrepot'); $this->import_tables_creator_array[$r]=array('e'=>'fk_user_author'); - $this->import_fields_array[$r]=array('e.label'=>"LocationSummary*", + $this->import_fields_array[$r]=array('e.ref'=>"LocationSummary*", 'e.description'=>"DescWareHouse",'e.lieu'=>"LieuWareHouse", 'e.address'=>"Address",'e.zip'=>'Zip','e.fk_pays'=>'CountryCode', 'e.statut'=>'Status' @@ -242,7 +247,7 @@ class modStock extends DolibarrModules 'e.fk_pays'=>array('rule'=>'fetchidfromcodeid','classfile'=>'/core/class/ccountry.class.php','class'=>'Ccountry','method'=>'fetch','dict'=>'DictionaryCountry') ); $this->import_regex_array[$r]=array('e.statut'=>'^[0|1]'); - $this->import_examplevalues_array[$r]=array('e.label'=>"ALM001", + $this->import_examplevalues_array[$r]=array('e.ref'=>"ALM001", 'e.description'=>"Central Warehouse",'e.lieu'=>"Central", 'e.address'=>"Route 66",'e.zip'=>'28080','e.fk_pays'=>'US', 'e.statut'=>'1'); @@ -258,7 +263,7 @@ class modStock extends DolibarrModules $this->import_convertvalue_array[$r]=array( 'ps.fk_product'=>array('rule'=>'fetchidfromref','classfile'=>'/product/class/product.class.php','class'=>'Product','method'=>'fetch','element'=>'product'), - 'ps.fk_entrepot'=>array('rule'=>'fetchidfromref','classfile'=>'/product/stock/class/entrepot.class.php','class'=>'Entrepot','method'=>'fetch','element'=>'label') + 'ps.fk_entrepot'=>array('rule'=>'fetchidfromref','classfile'=>'/product/stock/class/entrepot.class.php','class'=>'Entrepot','method'=>'fetch','element'=>'ref') ); $this->import_examplevalues_array[$r]=array( 'ps.fk_product'=>"PREF123456",'ps.fk_entrepot'=>"ALM001",'ps.reel'=>"10" diff --git a/htdocs/core/modules/modUser.class.php b/htdocs/core/modules/modUser.class.php index 1bd4281b507..95474ac8921 100644 --- a/htdocs/core/modules/modUser.class.php +++ b/htdocs/core/modules/modUser.class.php @@ -50,7 +50,6 @@ class modUser extends DolibarrModules // Module label (no space allowed), used if translation string 'ModuleXXXName' not found (where XXX is value of numeric property 'numero' of module) $this->name = preg_replace('/^mod/i','',get_class($this)); $this->description = "Gestion des utilisateurs (requis)"; - $this->always_enabled = true; // Can't be disabled // Possible values for version are: 'development', 'experimental', 'dolibarr' or version $this->version = 'dolibarr'; @@ -69,6 +68,7 @@ class modUser extends DolibarrModules $this->depends = array(); $this->requiredby = array(); $this->langfiles = array("main","users","companies","members",'salaries'); + $this->always_enabled = true; // Can't be disabled // Constants $this->const = array(); @@ -204,13 +204,13 @@ class modUser extends DolibarrModules $this->rights[$r][4] = 'user'; $this->rights[$r][5] = 'export'; - + // Menus //------- - + $this->menu = 1; // This module add menu entries. They are coded into menu manager. - - + + // Exports //-------- $r=0; @@ -230,7 +230,7 @@ class modUser extends DolibarrModules $this->export_sql_start[$r]='SELECT DISTINCT '; $this->export_sql_end[$r] =' FROM '.MAIN_DB_PREFIX.'user as u'; $this->export_sql_end[$r] .=' WHERE u.entity IN ('.getEntity('user').')'; - + // Imports //-------- $r=0; @@ -266,7 +266,7 @@ class modUser extends DolibarrModules $this->import_regex_array[$r]=array('u.employee'=>'^[0|1]','u.datec'=>'^[0-9][0-9][0-9][0-9]-[0-9][0-9]-[0-9][0-9]( [0-9][0-9]:[0-9][0-9]:[0-9][0-9])?$'); $this->import_examplevalues_array[$r]=array('u.lastname'=>"Doe",'u.firstname'=>'John','u.login'=>'jdoe','u.employee'=>'0 or 1','u.status'=>"0 (closed) or 1 (active)",'u.fk_soc'=>'0 (internal user) or company name (external user)','u.datec'=>dol_print_date(dol_now(),'%Y-%m-%d'),'u.address'=>"61 jump street",'u.zip'=>"123456",'u.town'=>"Big town",'u.fk_country'=>'US, FR, DE...','u.office_phone'=>"0101010101",'u.office_fax'=>"0101010102",'u.email'=>"test@mycompany.com",'u.salary'=>"10000",'u.note'=>"This is an example of note for record",'u.datec'=>"2015-01-01 or 2015-01-01 12:30:00"); $this->import_updatekeys_array[$r]=array('u.lastname'=>'Lastname','u.firstname'=>'Firstname','u.login'=>'Login'); - + } diff --git a/htdocs/core/modules/modWebServices.class.php b/htdocs/core/modules/modWebServices.class.php index f4383bc6dc5..ae979eb026e 100644 --- a/htdocs/core/modules/modWebServices.class.php +++ b/htdocs/core/modules/modWebServices.class.php @@ -64,6 +64,7 @@ class modWebServices extends DolibarrModules //------------- $this->depends = array(); $this->requiredby = array(); + //$this->phpmax = array(7,1); // Maximum version of PHP required by module $this->langfiles = array("other"); // Constants diff --git a/htdocs/core/modules/oauth/github_oauthcallback.php b/htdocs/core/modules/oauth/github_oauthcallback.php index 83c3da66a47..23bb1942c66 100644 --- a/htdocs/core/modules/oauth/github_oauthcallback.php +++ b/htdocs/core/modules/oauth/github_oauthcallback.php @@ -94,18 +94,22 @@ $langs->load("oauth"); */ -if ($action == 'delete') +if ($action == 'delete') { $storage->clearToken('GitHub'); - + setEventMessages($langs->trans('TokenDeleted'), null, 'mesgs'); - + header('Location: ' . $backtourl); exit(); -} +} if (! empty($_GET['code'])) // We are coming from oauth provider page { + // We should have + //$_GET=array('code' => string 'aaaaaaaaaaaaaa' (length=20), 'state' => string 'user,public_repo' (length=16)) + + dol_syslog("We are coming fr mthe oauth provider page"); //llxHeader('',$langs->trans("OAuthSetup")); //$linkback=''.$langs->trans("BackToModuleList").''; @@ -121,29 +125,29 @@ if (! empty($_GET['code'])) // We are coming from oauth provider page //var_dump($_GET['code']); //var_dump($state); //var_dump($apiService); // OAuth\OAuth2\Service\GitHub - + //$token = $apiService->requestAccessToken($_GET['code'], $state); - $token = $apiService->requestAccessToken($_GET['code']); - // Github is a service that does not need state yo be stored. + $token = $apiService->requestAccessToken($_GET['code']); + // Github is a service that does not need state to be stored. // Into constructor of GitHub, the call // parent::__construct($credentials, $httpClient, $storage, $scopes, $baseApiUri) // has not the ending parameter to true like the Google class constructor. - + setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token + + $backtourl = $_SESSION["backtourlsavedbeforeoauthjump"]; + unset($_SESSION["backtourlsavedbeforeoauthjump"]); + + header('Location: ' . $backtourl); + exit(); } catch (Exception $e) { print $e->getMessage(); } - - $backtourl = $_SESSION["backtourlsavedbeforeoauthjump"]; - unset($_SESSION["backtourlsavedbeforeoauthjump"]); - - header('Location: ' . $backtourl); - exit(); } else // If entry on page with no parameter, we arrive here { $_SESSION["backtourlsavedbeforeoauthjump"]=$backtourl; - + // This may create record into oauth_state before the header redirect. // Creation of record with state in this tables depend on the Provider used (see its constructor). if (GETPOST('state')) @@ -154,7 +158,7 @@ else // If entry on page with no parameter, we arrive here { $url = $apiService->getAuthorizationUri(); // Parameter state will be randomly generated } - + // we go on oauth provider authorization page header('Location: ' . $url); exit(); diff --git a/htdocs/core/modules/oauth/google_oauthcallback.php b/htdocs/core/modules/oauth/google_oauthcallback.php index 001db7320a0..7760898bc6e 100644 --- a/htdocs/core/modules/oauth/google_oauthcallback.php +++ b/htdocs/core/modules/oauth/google_oauthcallback.php @@ -97,19 +97,20 @@ $langs->load("oauth"); */ -if ($action == 'delete') +if ($action == 'delete') { $storage->clearToken('Google'); - + setEventMessages($langs->trans('TokenDeleted'), null, 'mesgs'); - + header('Location: ' . $backtourl); exit(); -} +} if (! empty($_GET['code'])) // We are coming from oauth provider page { - //llxHeader('',$langs->trans("OAuthSetup")); + dol_syslog("We are coming fr mthe oauth provider page"); + //llxHeader('',$langs->trans("OAuthSetup")); //$linkback=''.$langs->trans("BackToModuleList").''; //print load_fiche_titre($langs->trans("OAuthSetup"),$linkback,'title_setup'); @@ -124,24 +125,24 @@ if (! empty($_GET['code'])) // We are coming from oauth provider page //var_dump($_GET['code']); //var_dump($state); //var_dump($apiService); // OAuth\OAuth2\Service\Google - + $token = $apiService->requestAccessToken($_GET['code'], $state); - + setEventMessages($langs->trans('NewTokenStored'), null, 'mesgs'); // Stored into object managed by class DoliStorage so into table oauth_token + + $backtourl = $_SESSION["backtourlsavedbeforeoauthjump"]; + unset($_SESSION["backtourlsavedbeforeoauthjump"]); + + header('Location: ' . $backtourl); + exit(); } catch (Exception $e) { print $e->getMessage(); } - - $backtourl = $_SESSION["backtourlsavedbeforeoauthjump"]; - unset($_SESSION["backtourlsavedbeforeoauthjump"]); - - header('Location: ' . $backtourl); - exit(); } else // If entry on page with no parameter, we arrive here { $_SESSION["backtourlsavedbeforeoauthjump"]=$backtourl; - + // This may create record into oauth_state before the header redirect. // Creation of record with state in this tables depend on the Provider used (see its constructor). if (GETPOST('state')) @@ -152,7 +153,7 @@ else // If entry on page with no parameter, we arrive here { $url = $apiService->getAuthorizationUri(); // Parameter state will be randomly generated } - + // we go on oauth provider authorization page header('Location: ' . $url); exit(); diff --git a/htdocs/core/modules/printing/printgcp.modules.php b/htdocs/core/modules/printing/printgcp.modules.php index 539db0ddee5..6e007b22b55 100644 --- a/htdocs/core/modules/printing/printgcp.modules.php +++ b/htdocs/core/modules/printing/printgcp.modules.php @@ -318,7 +318,7 @@ class printing_printgcp extends PrintingDriver else dol_print_error($this->db); $ret = $this->sendPrintToPrinter($printer_id, $file, $fileprint, $mimetype); - $this->errors = 'PRINTGCP: '.mb_convert_encoding($ret['errormessage'], "UTF-8"); + $this->error = 'PRINTGCP: '.$ret['errormessage']; if ($ret['status']!=1) $error++; return $error; } diff --git a/htdocs/core/modules/product/mod_codeproduct_elephant.php b/htdocs/core/modules/product/mod_codeproduct_elephant.php index bb7eb09abf4..32941ca1ec9 100644 --- a/htdocs/core/modules/product/mod_codeproduct_elephant.php +++ b/htdocs/core/modules/product/mod_codeproduct_elephant.php @@ -229,6 +229,7 @@ class mod_codeproduct_elephant extends ModeleProductCode * -2 ErrorCustomerCodeRequired * -3 ErrorCustomerCodeAlreadyUsed * -4 ErrorPrefixRequired + * -5 Other (see this->error) */ function verif($db, &$code, $product, $type) { @@ -256,10 +257,15 @@ class mod_codeproduct_elephant extends ModeleProductCode if (! $mask) { $this->error='NotConfigured'; - return ''; + return -5; } $result=check_value($mask,$code); + if (is_string($result)) + { + $this->error = $result; + return -5; + } } dol_syslog("mod_codeclient_elephant::verif type=".$type." result=".$result); diff --git a/htdocs/core/modules/rapport/pdf_paiement.class.php b/htdocs/core/modules/rapport/pdf_paiement.class.php index 336928ce408..b294d8645eb 100644 --- a/htdocs/core/modules/rapport/pdf_paiement.class.php +++ b/htdocs/core/modules/rapport/pdf_paiement.class.php @@ -187,8 +187,9 @@ class pdf_paiement if (! empty($conf->banque->enabled)) $sql.= ", ba.ref as bankaccount"; $sql.= ", p.rowid as prowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."paiement as p, ".MAIN_DB_PREFIX."facture as f,"; - $sql.= " ".MAIN_DB_PREFIX."c_paiement as c, ".MAIN_DB_PREFIX."paiement_facture as pf,"; + $sql.= " FROM ".MAIN_DB_PREFIX."paiement as p LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as c ON p.fk_paiement = c.id AND c.entity IN (" . getEntity('c_paiement').")"; + $sql.= ", ".MAIN_DB_PREFIX."facture as f,"; + $sql.= " ".MAIN_DB_PREFIX."paiement_facture as pf,"; if (! empty($conf->banque->enabled)) $sql.= " ".MAIN_DB_PREFIX."bank as b, ".MAIN_DB_PREFIX."bank_account as ba,"; $sql.= " ".MAIN_DB_PREFIX."societe as s"; @@ -200,8 +201,6 @@ class pdf_paiement if (! empty($conf->banque->enabled)) $sql.= " AND p.fk_bank = b.rowid AND b.fk_account = ba.rowid "; $sql.= " AND f.entity = ".$conf->entity; - $sql.= " AND p.fk_paiement = c.id "; - $sql.= " AND c.entity = " . getEntity('c_paiement'); $sql.= " AND p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year,$month))."' AND '".$this->db->idate(dol_get_last_day($year,$month))."'"; if (! $user->rights->societe->client->voir && ! $socid) { @@ -219,8 +218,9 @@ class pdf_paiement if (! empty($conf->banque->enabled)) $sql.= ", ba.ref as bankaccount"; $sql.= ", p.rowid as prowid"; - $sql.= " FROM ".MAIN_DB_PREFIX."paiementfourn as p, ".MAIN_DB_PREFIX."facture_fourn as f,"; - $sql.= " ".MAIN_DB_PREFIX."c_paiement as c, ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf,"; + $sql.= " FROM ".MAIN_DB_PREFIX."paiementfourn as p LEFT JOIN ON ".MAIN_DB_PREFIX."c_paiement as c ON p.fk_paiement = c.id AND c.entity IN (".getEntity('c_paiement').")"; + $sql.= ", ".MAIN_DB_PREFIX."facture_fourn as f,"; + $sql.= " ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf,"; if (! empty($conf->banque->enabled)) $sql.= " ".MAIN_DB_PREFIX."bank as b, ".MAIN_DB_PREFIX."bank_account as ba,"; $sql.= " ".MAIN_DB_PREFIX."societe as s"; @@ -232,8 +232,6 @@ class pdf_paiement if (! empty($conf->banque->enabled)) $sql.= " AND p.fk_bank = b.rowid AND b.fk_account = ba.rowid "; $sql.= " AND f.entity = ".$conf->entity; - $sql.= " AND p.fk_paiement = c.id "; - $sql.= " AND c.entity = " . getEntity('c_paiement'); $sql.= " AND p.datep BETWEEN '".$this->db->idate(dol_get_first_day($year,$month))."' AND '".$this->db->idate(dol_get_last_day($year,$month))."'"; if (! $user->rights->societe->client->voir && ! $socid) { diff --git a/htdocs/core/modules/societe/mod_codeclient_elephant.php b/htdocs/core/modules/societe/mod_codeclient_elephant.php index 589bf1547c1..d6a6da23a94 100644 --- a/htdocs/core/modules/societe/mod_codeclient_elephant.php +++ b/htdocs/core/modules/societe/mod_codeclient_elephant.php @@ -247,6 +247,7 @@ class mod_codeclient_elephant extends ModeleThirdPartyCode * -2 ErrorCustomerCodeRequired * -3 ErrorCustomerCodeAlreadyUsed * -4 ErrorPrefixRequired + * -5 Other (see this->error) */ function verif($db, &$code, $soc, $type) { @@ -274,10 +275,15 @@ class mod_codeclient_elephant extends ModeleThirdPartyCode if (! $mask) { $this->error='NotConfigured'; - return ''; + return -5; } $result=check_value($mask,$code); + if (is_string($result)) + { + $this->error = $result; + return -5; + } } dol_syslog("mod_codeclient_elephant::verif type=".$type." result=".$result); diff --git a/htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php b/htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php index 6f36c643ccd..c14c92db2bf 100644 --- a/htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php +++ b/htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php @@ -933,7 +933,7 @@ class pdf_canelle extends ModelePDFSuppliersInvoices $sql = "SELECT p.datep as date, p.fk_paiement as type, p.num_paiement as num, pf.amount as amount, pf.multicurrency_amount,"; $sql.= " cp.code"; $sql.= " FROM ".MAIN_DB_PREFIX."paiementfourn_facturefourn as pf, ".MAIN_DB_PREFIX."paiementfourn as p"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as cp ON p.fk_paiement = cp.id AND cp.entity = " . getEntity('c_paiement'); + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as cp ON p.fk_paiement = cp.id AND cp.entity IN (".getEntity('c_paiement').")"; $sql.= " WHERE pf.fk_paiementfourn = p.rowid and pf.fk_facturefourn = ".$object->id; $sql.= " ORDER BY p.datep"; $resql=$this->db->query($sql); diff --git a/htdocs/core/search_page.php b/htdocs/core/search_page.php index 83ef016d3a9..acf2f788802 100644 --- a/htdocs/core/search_page.php +++ b/htdocs/core/search_page.php @@ -86,9 +86,8 @@ else { $tmp=explode('?', $val['url']); $urlaction=$tmp[0]; - $keysearch=$tmp[1]; - $keysearch=preg_replace('/mainmenu=(.*)&/','',$keysearch); - $keysearch=preg_replace('/=/','',$keysearch); + $keysearch='search_all'; + $accesskey=''; if (! $accesskeyalreadyassigned[$val['label'][0]]) { diff --git a/htdocs/core/tpl/ajaxrow.tpl.php b/htdocs/core/tpl/ajaxrow.tpl.php index a5d8ab039b8..49d69d6afcb 100644 --- a/htdocs/core/tpl/ajaxrow.tpl.php +++ b/htdocs/core/tpl/ajaxrow.tpl.php @@ -46,8 +46,8 @@ $(document).ready(function(){ onDrop: function(table, row) { var reloadpage = ""; console.log("tableDND onDrop"); - console.log($("#").tableDnDSerialize()); - var roworder = cleanSerialize($("#").tableDnDSerialize()); + console.log(decodeURI($("#").tableDnDSerialize())); + var roworder = cleanSerialize(decodeURI($("#").tableDnDSerialize())); var table_element_line = ""; var fk_element = ""; var element_id = ""; @@ -75,7 +75,7 @@ $(document).ready(function(){ }); }, onDragClass: "dragClass", - dragHandle: "tdlineupdown" + dragHandle: "td.tdlineupdown" }); $(".tdlineupdown").hover( function() { $(this).addClass('showDragHandle'); }, function() { $(this).removeClass('showDragHandle'); } diff --git a/htdocs/core/tpl/card_presend.tpl.php b/htdocs/core/tpl/card_presend.tpl.php index c5e8e68901b..9fd8e6b5cfa 100644 --- a/htdocs/core/tpl/card_presend.tpl.php +++ b/htdocs/core/tpl/card_presend.tpl.php @@ -66,7 +66,7 @@ if ($action == 'presend') { $outputlangs = new Translate('', $conf); $outputlangs->setDefaultLang($newlang); - $outputlangs->load('commercial'); + $outputlangs->loadLangs(array('commercial','bills','orders','contracts','members','propal','supplier_proposal','interventions')); } $topicmail=''; @@ -98,7 +98,7 @@ if ($action == 'presend') dol_fiche_head(''); - // Cree l'objet formulaire mail + // Create form for email include_once DOL_DOCUMENT_ROOT . '/core/class/html.formmail.class.php'; $formmail = new FormMail($db); $formmail->param['langsmodels']=(empty($newlang)?$langs->defaultlang:$newlang); diff --git a/htdocs/core/tpl/commonfields_add.tpl.php b/htdocs/core/tpl/commonfields_add.tpl.php index f6aebd6357c..7179719e7db 100644 --- a/htdocs/core/tpl/commonfields_add.tpl.php +++ b/htdocs/core/tpl/commonfields_add.tpl.php @@ -35,14 +35,14 @@ foreach($object->fields as $key => $val) print ''; print $langs->trans($val['label']); print ''; print '
  • '; diff --git a/htdocs/core/tpl/commonfields_edit.tpl.php b/htdocs/core/tpl/commonfields_edit.tpl.php index 248cd4b4086..9605a218544 100644 --- a/htdocs/core/tpl/commonfields_edit.tpl.php +++ b/htdocs/core/tpl/commonfields_edit.tpl.php @@ -34,13 +34,14 @@ foreach($object->fields as $key => $val) print ''.$langs->trans($val['label']).''; print ''; print ''; diff --git a/htdocs/core/tpl/commonfields_view.tpl.php b/htdocs/core/tpl/commonfields_view.tpl.php index ded3247f1dd..cd8c567c418 100644 --- a/htdocs/core/tpl/commonfields_view.tpl.php +++ b/htdocs/core/tpl/commonfields_view.tpl.php @@ -19,6 +19,8 @@ * $action * $conf * $langs + * + * $keyforbreak may be defined to key to switch on second column */ ?> @@ -37,6 +39,7 @@ foreach($object->fields as $key => $val) print ''.$langs->trans($val['label']).''; print ''; print ''; - //if ($key == 'targetsrcfile3') break; // key used for break on second column + if (! empty($keyforbreak) && $key == $keyforbreak) break; // key used for break on second column } print '
    '; - print ''; - print ''; + print ''; + print ''; - print ''; + print ''; - print $form->selectarray('search_status', array('-1'=>'','0'=>$contactstatic->LibStatut(0,1),'1'=>$contactstatic->LibStatut(1,1)),$search_status); - print ''; + print $form->selectarray('search_status', array('-1'=>'','0'=>$contactstatic->LibStatut(0,1),'1'=>$contactstatic->LibStatut(1,1)),$search_status); + print ''; - $searchpicto=$form->showFilterButtons(); - print $searchpicto; - print ''; + $searchpicto=$form->showFilterButtons(); + print $searchpicto; + print '
    '.$contactstatic->getLibStatut(5).''.$contactstatic->getLibStatut(5).''.$center.''.$morehtmlcenter.'
    '; + print $projectstatic->getNomUrl(1,'',0,$langs->transnoentitiesnoconv("YourRole").': '.$projectsrole[$lines[$i]->fk_project]); + if ($projectstatic->title) + { + print ' - '; + print $projectstatic->title; + } + print '
    '; + print $fuser->getNomUrl(1, 'withproject', 'time'); + print '"; + if ($oldprojectforbreak == -1) + { + print $projectstatic->getNomUrl(1,'',0,$langs->transnoentitiesnoconv("YourRole").': '.$projectsrole[$lines[$i]->fk_project]); + print '
    '.$projectstatic->title; + } + print "
    '; + if ($thirdpartystatic->id > 0) print $thirdpartystatic->getNomUrl(1, 'project', 10); + print ''; + print ''; + for ($k = 0 ; $k < $level ; $k++) print "   "; + print $taskstatic->getNomUrl(1, 'withproject', 'time'); + // Label task + print '
    '; + for ($k = 0 ; $k < $level ; $k++) print "   "; + print $taskstatic->label; + //print "
    "; + //for ($k = 0 ; $k < $level ; $k++) print "   "; + //print get_date_range($lines[$i]->date_start,$lines[$i]->date_end,'',$langs,0); + print "
    '; + print dol_print_date($lines[$i]->timespent_datehour,'day'); + print ''; + print dol_print_date($lines[$i]->timespent_datehour,'hour'); + print ''; + + $dayWorkLoad = $lines[$i]->timespent_duration; + $totalforeachline[$preselectedday]+=$lines[$i]->timespent_duration; + + $alreadyspent=''; + if ($dayWorkLoad > 0) $alreadyspent=convertSecondToTime($lines[$i]->timespent_duration,'allhourmin'); + + print convertSecondToTime($lines[$i]->timespent_duration,'allhourmin'); + + $modeinput='hours'; + + print ''; + + print ''; + print ''; + print ''; + /*if ((! $lines[$i]->public) && $disabledproject) print $form->textwithpicto('',$langs->trans("UserIsNotContactOfProject")); + else if ($disabledtask) + { + $titleassigntask = $langs->trans("AssignTaskToMe"); + if ($fuser->id != $user->id) $titleassigntask = $langs->trans("AssignTaskToUser", '...'); + + print $form->textwithpicto('',$langs->trans("TaskIsNotAssignedToUser", $titleassigntask)); + }*/ + print '
    '; $dayWorkLoad = $projectstatic->weekWorkLoadPerTask[$preselectedday][$lines[$i]->id]; + $totalforeachday[$preselectedday]+=$dayWorkLoad; + $alreadyspent=''; if ($dayWorkLoad > 0) $alreadyspent=convertSecondToTime($dayWorkLoad,'allhourmin'); @@ -822,8 +1050,17 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr $level++; if ($lines[$i]->id > 0) { - if ($parent == 0) projectLinesPerDay($inc, $lines[$i]->id, $fuser, $lineswithoutlevel0, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $preselectedday, $isavailable, $oldprojectforbreak); - else projectLinesPerDay($inc, $lines[$i]->id, $fuser, $lines, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $preselectedday, $isavailable, $oldprojectforbreak); + //var_dump('totalforeachday after taskid='.$lines[$i]->id.' and previous one on level '.$level); + //var_dump($totalforeachday); + $ret = projectLinesPerDay($inc, $lines[$i]->id, $fuser, ($parent == 0 ? $lineswithoutlevel0 : $lines), $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $preselectedday, $isavailable, $oldprojectforbreak); + //var_dump('ret with parent='.$lines[$i]->id.' level='.$level); + //var_dump($ret); + foreach($ret as $key => $val) + { + $totalforeachday[$key]+=$val; + } + //var_dump('totalforeachday after taskid='.$lines[$i]->id.' and previous one on level '.$level.' + subtasks'); + //var_dump($totalforeachday); } $level--; } @@ -833,7 +1070,7 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr } } - return $inc; + return $totalforeachday; } @@ -852,7 +1089,7 @@ function projectLinesPerDay(&$inc, $parent, $fuser, $lines, &$level, &$projectsr * @param int $restricteditformytask 0=No restriction, 1=Enable add time only if task is a task i am affected to * @param array $isavailable Array with data that say if user is available for several days for morning and afternoon * @param int $oldprojectforbreak Old project id of last project break - * @return $inc + * @return array Array with time spent for $fuser for each day of week on tasks in $lines and substasks */ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$level, &$projectsrole, &$tasksrole, $mine, $restricteditformytask, &$isavailable, $oldprojectforbreak=0) { @@ -863,6 +1100,7 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ $lastprojectid=0; $workloadforid=array(); + $totalforeachday=array(); $lineswithoutlevel0=array(); // Create a smaller array with sublevels only to be used later. This increase dramatically performances. @@ -899,11 +1137,15 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ $projectstatic->id = $lines[$i]->fk_project; } + //var_dump('--- '.$level.' '.$firstdaytoshow.' '.$fuser->id.' '.$projectstatic->id.' '.$workloadforid[$projectstatic->id]); + //var_dump($projectstatic->weekWorkLoadPerTask); if (empty($workloadforid[$projectstatic->id])) { $projectstatic->loadTimeSpent($firstdaytoshow, 0, $fuser->id); // Load time spent from table projet_task_time for the project into this->weekWorkLoad and this->weekWorkLoadPerTask for all days of a week $workloadforid[$projectstatic->id]=1; } + //var_dump($projectstatic->weekWorkLoadPerTask); + //var_dump('--- '.$projectstatic->id.' '.$workloadforid[$projectstatic->id]); $projectstatic->id=$lines[$i]->fk_project; $projectstatic->ref=$lines[$i]->projectref; @@ -913,7 +1155,6 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ $taskstatic->id=$lines[$i]->id; $taskstatic->ref=($lines[$i]->ref?$lines[$i]->ref:$lines[$i]->id); - $taskstatic->id=$lines[$i]->id; $taskstatic->label=$lines[$i]->label; $taskstatic->date_start=$lines[$i]->date_start; $taskstatic->date_end=$lines[$i]->date_end; @@ -1033,6 +1274,8 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ $tmparray=dol_getdate($tmpday); $dayWorkLoad = $projectstatic->weekWorkLoadPerTask[$tmpday][$lines[$i]->id]; + $totalforeachday[$tmpday]+=$dayWorkLoad; + $alreadyspent=''; if ($dayWorkLoad > 0) $alreadyspent=convertSecondToTime($dayWorkLoad,'allhourmin'); $alttitle=$langs->trans("AddHereTimeSpentForDay",$tmparray['day'],$tmparray['mon']); @@ -1073,8 +1316,17 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ $level++; if ($lines[$i]->id > 0) { - if ($parent == 0) projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, $lineswithoutlevel0, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $isavailable, $oldprojectforbreak); - else projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, $lines, $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $isavailable, $oldprojectforbreak); + //var_dump('totalforeachday after taskid='.$lines[$i]->id.' and previous one on level '.$level); + //var_dump($totalforeachday); + $ret = projectLinesPerWeek($inc, $firstdaytoshow, $fuser, $lines[$i]->id, ($parent == 0 ? $lineswithoutlevel0 : $lines), $level, $projectsrole, $tasksrole, $mine, $restricteditformytask, $isavailable, $oldprojectforbreak); + //var_dump('ret with parent='.$lines[$i]->id.' level='.$level); + //var_dump($ret); + foreach($ret as $key => $val) + { + $totalforeachday[$key]+=$val; + } + //var_dump('totalforeachday after taskid='.$lines[$i]->id.' and previous one on level '.$level.' + subtasks'); + //var_dump($totalforeachday); } $level--; } @@ -1084,7 +1336,7 @@ function projectLinesPerWeek(&$inc, $firstdaytoshow, $fuser, $parent, $lines, &$ } } - return $inc; + return $totalforeachday; } diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index fed22dafdfb..cf37b749b5b 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -74,7 +74,7 @@ function dol_decode($chain) * If constant MAIN_SECURITY_SALT is defined, we use it as a salt. * * @param string $chain String to hash - * @param string $type Type of hash ('0':auto, '1':sha1, '2':sha1+md5, '3':md5, '4':md5 for OpenLdap). Use '3' here, if hash is not needed for security purpose, for security need, prefer '0'. + * @param string $type Type of hash ('0':auto, '1':sha1, '2':sha1+md5, '3':md5, '4':md5 for OpenLdap, '5':sha256). Use '3' here, if hash is not needed for security purpose, for security need, prefer '0'. * @return string Hash of string */ function dol_hash($chain, $type='0') @@ -88,6 +88,7 @@ function dol_hash($chain, $type='0') else if ($type == '2' || $type == 'sha1md5') return sha1(md5($chain)); else if ($type == '3' || $type == 'md5') return md5($chain); else if ($type == '4' || $type == 'md5openldap') return '{md5}'.base64_encode(mhash(MHASH_MD5,$chain)); // For OpenLdap with md5 (based on an unencrypted password in base) + else if ($type == '5') return hash('sha256',$chain); else if (! empty($conf->global->MAIN_SECURITY_HASH_ALGO) && $conf->global->MAIN_SECURITY_HASH_ALGO == 'sha1') return sha1($chain); else if (! empty($conf->global->MAIN_SECURITY_HASH_ALGO) && $conf->global->MAIN_SECURITY_HASH_ALGO == 'sha1md5') return sha1(md5($chain)); @@ -242,9 +243,9 @@ function restrictedArea($user, $features, $objectid=0, $tableandshare='', $featu { foreach($feature2 as $subfeature) { - if (empty($user->rights->$feature->$subfeature->creer) - && empty($user->rights->$feature->$subfeature->write) - && empty($user->rights->$feature->$subfeature->create)) { $createok=0; $nbko++; } + if (empty($user->rights->$feature->$subfeature->creer) + && empty($user->rights->$feature->$subfeature->write) + && empty($user->rights->$feature->$subfeature->create)) { $createok=0; $nbko++; } else { $createok=1; break; } // Break to bypass second test if the first is ok } } @@ -307,6 +308,9 @@ function restrictedArea($user, $features, $objectid=0, $tableandshare='', $featu else if ($feature == 'ftp') { if (! $user->rights->ftp->write) $deleteok=0; + }else if ($feature == 'salaries') + { + if (! $user->rights->salaries->delete) $deleteok=0; } else if ($feature == 'salaries') { diff --git a/htdocs/core/lib/sendings.lib.php b/htdocs/core/lib/sendings.lib.php index 78de61a729f..3f5c8b8077c 100644 --- a/htdocs/core/lib/sendings.lib.php +++ b/htdocs/core/lib/sendings.lib.php @@ -53,9 +53,9 @@ function shipping_prepare_head($object) $object->fetchObjectLinked($object->id,$object->element); if (count($object->linkedObjectsIds['delivery']) > 0) // If there is a delivery { - // Take first one element of array + // Take first one element of array $tmp = reset($object->linkedObjectsIds['delivery']); - + $head[$h][0] = DOL_URL_ROOT."/livraison/card.php?id=".$tmp; $head[$h][1] = $langs->trans("DeliveryCard"); $head[$h][2] = 'delivery'; @@ -78,7 +78,7 @@ function shipping_prepare_head($object) $head[$h][2] = 'contact'; $h++; } - + $nbNote = 0; if (!empty($object->note_private)) $nbNote++; if (!empty($object->note_public)) $nbNote++; @@ -171,7 +171,7 @@ function show_list_sending_receive($origin,$origin_id,$filter='') $product_static=new Product($db); $expedition=new Expedition($db); $warehousestatic=new Entrepot($db); - + $sql = "SELECT obj.rowid, obj.fk_product, obj.label, obj.description, obj.product_type as fk_product_type, obj.qty as qty_asked, obj.date_start, obj.date_end,"; $sql.= " ed.rowid as edrowid, ed.qty as qty_shipped, ed.fk_expedition as expedition_id, ed.fk_origin_line, ed.fk_entrepot as warehouse_id,"; $sql.= " e.rowid as sendingid, e.ref as exp_ref, e.date_creation, e.date_delivery, e.date_expedition,"; @@ -233,7 +233,7 @@ function show_list_sending_receive($origin,$origin_id,$filter='') $var=True; while ($i < $num) { - + $objp = $db->fetch_object($resql); print '
    '.$langs->trans("TextTitleColor").''; + if ($edit) + { + print $formother->selectColor(colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_TEXTTITLENOTAB,array()),''),'THEME_ELDY_TEXTTITLENOTAB','formcolor',1).' '; + } + else + { + print $formother->showColor($conf->global->THEME_ELDY_TEXTTITLENOTAB, $langs->trans("Default")); + } + print '   ('.$langs->trans("Default").': 643c14) '; + print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); + + print '
    '.$langs->trans("TextTitleColor").''; - if ($edit) - { - print $formother->selectColor(colorArrayToHex(colorStringToArray($conf->global->THEME_ELDY_TEXTTITLENOTAB,array()),''),'THEME_ELDY_TEXTTITLENOTAB','formcolor',1).' '; - } - else - { - print $formother->showColor($conf->global->THEME_ELDY_TEXTTITLENOTAB, $langs->trans("Default")); - } - print '   ('.$langs->trans("Default").': 3c3c14) '; - print $form->textwithpicto('', $langs->trans("NotSupportedByAllThemes").', '.$langs->trans("PressF5AfterChangingThis")); - - print '
    '; if (in_array($val['type'], array('int', 'integer'))) $value = GETPOST($key, 'int'); - elseif ($val['type'] == 'text') $value = GETPOST($key, 'none'); + elseif ($val['type'] == 'text' || $val['type'] == 'html') $value = GETPOST($key, 'none'); else $value = GETPOST($key, 'alpha'); print $object->showInputField($val, $key, $value, '', '', '', 0); print '
    '; if (in_array($val['type'], array('int', 'integer'))) $value = GETPOSTISSET($key)?GETPOST($key, 'int'):$object->$key; - elseif ($val['type'] == 'text') $value = GETPOSTISSET($key)?GETPOST($key,'none'):$object->$key; + elseif ($val['type'] == 'text' || $val['type'] == 'html') $value = GETPOSTISSET($key)?GETPOST($key,'none'):$object->$key; else $value = GETPOSTISSET($key)?GETPOST($key, 'alpha'):$object->$key; + //var_dump($val.' '.$key.' '.$value); print $object->showInputField($val, $key, $value, '', '', '', 0); print '
    '; @@ -45,7 +48,7 @@ foreach($object->fields as $key => $val) print '
    '; @@ -60,7 +63,7 @@ foreach($object->fields as $key => $val) { if ($alreadyoutput) { - //if ($key == 'targetsrcfile3') $alreadyoutput = 0; // key used for break on second column + if (! empty($keyforbreak) && $key == $keyforbreak) $alreadyoutput = 0; // key used for break on second column continue; } @@ -73,6 +76,7 @@ foreach($object->fields as $key => $val) print '
    '; diff --git a/htdocs/core/tpl/extrafields_list_print_fields.tpl.php b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php new file mode 100644 index 00000000000..30318350bc3 --- /dev/null +++ b/htdocs/core/tpl/extrafields_list_print_fields.tpl.php @@ -0,0 +1,32 @@ +attribute_label) && count($extrafields->attribute_label)) +{ + foreach($extrafields->attribute_label as $key => $val) + { + if (! empty($arrayfields["ef.".$key]['checked'])) + { + $align=$extrafields->getAlignFlag($key); + print ''; + $tmpkey='options_'.$key; + if (in_array($extrafields->attribute_type[$key], array('date', 'datetime', 'timestamp'))) + { + $value = $db->jdate($obj->$tmpkey); + } + else + { + $value = $obj->$tmpkey; + } + print $extrafields->showOutputField($key, $value, ''); + print ''; + if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select')) && empty($extrafields->attribute_computed[$key])) + { + $crit=$val; + $tmpkey=preg_replace('/search_options_/','',$key); + $searchclass=''; + if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; + if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; + print ''; + } + else + { + // for the type as 'checkbox', 'chkbxlst', 'sellist' we should use code instead of id (example: I declare a 'chkbxlst' to have a link with dictionnairy, I have to extend it with the 'code' instead 'rowid') + echo $extrafields->showInputField($key, $search_array_options['search_options_'.$key], '', '', 'search_'); + } + print '
    '."\n"; @@ -211,4 +214,4 @@ if (! empty($conf->use_javascript_ajax) && empty($conf->global->MAIN_ECM_DISABLE } ?> - + diff --git a/htdocs/core/tpl/massactions_pre.tpl.php b/htdocs/core/tpl/massactions_pre.tpl.php index 2095399dace..48989b2daec 100644 --- a/htdocs/core/tpl/massactions_pre.tpl.php +++ b/htdocs/core/tpl/massactions_pre.tpl.php @@ -116,7 +116,7 @@ if ($massaction == 'presend') // $formmail->withfile = 2; Not yet supported in mass action $formmail->withmaindocfile = 1; // Add a checkbox "Attach also main document" if ($objecttmp->element != 'societe') { - $formmail->withfile = $langs->trans("OnlyPDFattachmentSupported"); + $formmail->withfile = ''.$langs->trans("OnlyPDFattachmentSupported").''; $formmail->withmaindocfile = - 1; // Add a checkbox "Attach also main document" but not checked by default } $formmail->withbody = 1; diff --git a/htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php b/htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php index 348aeb4dcc8..48ed23aba32 100644 --- a/htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php +++ b/htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php @@ -16,7 +16,7 @@ */ /** - * \file htdocs/core/triggers/interface_50_modAgenda_ActionsBlockedLog.class.php + * \file htdocs/core/triggers/interface_50_modBlockedlog_ActionsBlockedLog.class.php * \ingroup system * \brief Trigger file for blockedlog module */ @@ -24,6 +24,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/triggers/dolibarrtriggers.class.php'; require_once DOL_DOCUMENT_ROOT.'/blockedlog/class/blockedlog.class.php'; + /** * Class of triggered functions for agenda module */ @@ -55,13 +56,14 @@ class InterfaceActionsBlockedLog extends DolibarrTriggers dol_syslog("Trigger '".$this->name."' for action '$action' launched by ".__FILE__.". id=".$object->id); // Event/record is qualified - if ($action==='BILL_VALIDATE' || $action === 'BILL_PAYED' || $action==='BILL_UNPAYED' + if ($action==='BILL_VALIDATE' || $action === 'BILL_PAYED' || $action==='BILL_UNPAYED' || $action==='BILL_DELETE' || $action === 'BILL_SENTBYMAIL' || $action === 'DOC_DOWNLOAD' || $action === 'DOC_PREVIEW' || $action === 'BILL_SUPPLIER_PAYED') { $amounts= (double) $object->total_ttc; } - else if($action === 'PAYMENT_CUSTOMER_CREATE' || $action === 'PAYMENT_ADD_TO_BANK' || $action === 'PAYMENT_SUPPLIER_CREATE') + else if ($action === 'PAYMENT_CUSTOMER_CREATE' || $action === 'PAYMENT_SUPPLIER_CREATE' + || $action === 'PAYMENT_CUSTOMER_DELETE' || $action === 'PAYMENT_SUPPLIER_DELETE') // 'PAYMENT_ADD_TO_BANK' { $amounts = 0; if(!empty($object->amounts)) { @@ -70,7 +72,7 @@ class InterfaceActionsBlockedLog extends DolibarrTriggers } } } - else if(strpos($action,'PAYMENT')!==false) { + else if (strpos($action,'PAYMENT')!==false && ! in_array($action, array('PAYMENT_ADD_TO_BANK'))) { $amounts= (double) $object->amount; } else { @@ -79,9 +81,7 @@ class InterfaceActionsBlockedLog extends DolibarrTriggers $b=new BlockedLog($this->db); - $b->action = $action; - $b->amounts= $amounts; - $b->setObjectData($object); // Set field date_object, ref_object, fk_object, element, object_data + $b->setObjectData($object, $action, $amounts); // Set field date_object, ref_object, fk_object, element, object_data $res = $b->create($user); diff --git a/htdocs/cron/class/cronjob.class.php b/htdocs/cron/class/cronjob.class.php index 88494be7e04..a63982c5b12 100644 --- a/htdocs/cron/class/cronjob.class.php +++ b/htdocs/cron/class/cronjob.class.php @@ -1061,7 +1061,7 @@ class Cronjob extends CommonObject // Execute a CLI include_once DOL_DOCUMENT_ROOT.'/core/class/utils.class.php'; - $utils = new Utils($db); + $utils = new Utils($this->db); $arrayresult = $utils->executeCLI($this->command, $outputfile); $retval = $arrayresult['result']; diff --git a/htdocs/cron/list.php b/htdocs/cron/list.php index b08ec473028..a217370971b 100644 --- a/htdocs/cron/list.php +++ b/htdocs/cron/list.php @@ -205,19 +205,7 @@ if (count($sqlwhere)>0) { $sql.= " WHERE ".implode(' AND ',$sqlwhere); } // Add where from extra fields -foreach ($search_array_options as $key => $val) -{ - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $typ=$extrafields->attribute_type[$tmpkey]; - $mode_search=0; - if (in_array($typ, array('int','double','real'))) $mode_search=1; // Search on a numeric - if (in_array($typ, array('sellist','link')) && $crit != '0' && $crit != '-1') $mode_search=2; // Search on a foreign key int - if ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0') && (! in_array($typ, array('link')) || $crit != '-1')) - { - $sql .= natural_search('ef.'.$tmpkey, $crit, $mode_search); - } -} +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; // Add where from hooks $parameters=array(); $reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters); // Note that $action and $object may have been modified by hook @@ -246,12 +234,7 @@ if ($limit > 0 && $limit != $conf->liste_limit) $param.='&limit='.$limit; if ($search_label) $param.='&search_label='.$search_label; if ($optioncss != '') $param.='&optioncss='.$optioncss; // Add $param from extra fields -foreach ($search_array_options as $key => $val) -{ - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); -} +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; //$massactionbutton=$form->selectMassAction('', $massaction == 'presend' ? array() : array('presend'=>$langs->trans("SendByMail"), 'builddoc'=>$langs->trans("PDFMerge"))); diff --git a/htdocs/document.php b/htdocs/document.php index 42ad848a0d7..db9f4bdb41e 100644 --- a/htdocs/document.php +++ b/htdocs/document.php @@ -73,7 +73,7 @@ $urlsource=GETPOST('urlsource','alpha'); $entity=GETPOST('entity','int')?GETPOST('entity','int'):$conf->entity; // Security check -if (empty($modulepart)) accessforbidden('Bad link. Bad value for parameter modulepart',0,0,1); +if (empty($modulepart) && empty($hashp)) accessforbidden('Bad link. Bad value for parameter modulepart',0,0,1); if (empty($original_file) && empty($hashp)) accessforbidden('Bad link. Missing identification to find file (original_file or hashp)',0,0,1); if ($modulepart == 'fckeditor') $modulepart='medias'; // For backward compatibility @@ -119,15 +119,23 @@ if (! empty($hashp)) { $tmp = explode('/', $ecmfile->filepath, 2); // $ecmfile->filepath is relative to document directory $moduleparttocheck = $tmp[0]; - if ($moduleparttocheck == $modulepart) + if ($modulepart) // Not required for link using public hashp { - // We remove first level of directory - $original_file = (($tmp[1]?$tmp[1].'/':'').$ecmfile->filename); // this is relative to module dir - //var_dump($original_file); exit; + if ($moduleparttocheck == $modulepart) + { + // We remove first level of directory + $original_file = (($tmp[1]?$tmp[1].'/':'').$ecmfile->filename); // this is relative to module dir + //var_dump($original_file); exit; + } + else + { + accessforbidden('Bad link. File is from another module part.',0,0,1); + } } else { - accessforbidden('Bad link. File is from another module part.',0,0,1); + $modulepart = $moduleparttocheck; + $original_file = (($tmp[1]?$tmp[1].'/':'').$ecmfile->filename); // this is relative to module dir } } else @@ -154,7 +162,8 @@ $fullpath_original_file = $check_access['original_file']; // $ if (! empty($hashp)) { - $accessallowed = 1; // When using hashp, link is public so we force $accessallowed + $accessallowed = 1; // When using hashp, link is public so we force $accessallowed + $sqlprotectagainstexternals = ''; } else { @@ -220,7 +229,7 @@ if (! file_exists($fullpath_original_file_osencoded)) top_httphead($type); header('Content-Description: File Transfer'); if ($encoding) header('Content-Encoding: '.$encoding); -// Add MIME Content-Disposition from RFC 2183 (inline=automatically displayed, atachment=need user action to open) +// Add MIME Content-Disposition from RFC 2183 (inline=automatically displayed, attachment=need user action to open) if ($attachment) header('Content-Disposition: attachment; filename="'.$filename.'"'); else header('Content-Disposition: inline; filename="'.$filename.'"'); header('Content-Length: ' . dol_filesize($fullpath_original_file)); diff --git a/htdocs/don/admin/donation.php b/htdocs/don/admin/donation.php index 69e48248d57..fc659565c56 100644 --- a/htdocs/don/admin/donation.php +++ b/htdocs/don/admin/donation.php @@ -201,7 +201,7 @@ else if ($action == 'setart885') { $dir = "../../core/modules/dons/"; $form=new Form($db); -if (! empty($conf->accounting->enabled)) $formaccounting = New FormAccounting($db); +if (! empty($conf->accounting->enabled)) $formaccounting = new FormAccounting($db); llxHeader('',$langs->trans("DonationsSetup"),'DonConfiguration'); $linkback=''.$langs->trans("BackToModuleList").''; diff --git a/htdocs/don/card.php b/htdocs/don/card.php index 9628f8ce52d..539bae26e48 100644 --- a/htdocs/don/card.php +++ b/htdocs/don/card.php @@ -631,14 +631,12 @@ if (! empty($id) && $action != 'edit') */ $sql = "SELECT p.rowid, p.num_payment, p.datep as dp, p.amount,"; $sql.= "c.code as type_code,c.libelle as paiement_type"; - $sql.= " FROM ".MAIN_DB_PREFIX."payment_donation as p"; - $sql.= ", ".MAIN_DB_PREFIX."c_paiement as c "; + $sql.= " FROM ".MAIN_DB_PREFIX."payment_donation as p LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as c AND c.entity IN (".getEntity('c_paiement').")"; $sql.= ", ".MAIN_DB_PREFIX."don as d"; $sql.= " WHERE d.rowid = '".$id."'"; $sql.= " AND p.fk_donation = d.rowid"; - $sql.= " AND d.entity = ".$conf->entity; + $sql.= " AND d.entity IN (".getEntity('donation').")"; $sql.= " AND p.fk_typepayment = c.id"; - $sql.= " AND c.entity = " . getEntity('c_paiement'); $sql.= " ORDER BY dp"; //print $sql; diff --git a/htdocs/don/class/don.class.php b/htdocs/don/class/don.class.php index dd0243a632b..7224df1aa22 100644 --- a/htdocs/don/class/don.class.php +++ b/htdocs/don/class/don.class.php @@ -611,17 +611,17 @@ class Don extends CommonObject $sql.= " c.code as country_code, c.label as country"; $sql.= " FROM ".MAIN_DB_PREFIX."don as d"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."projet as p ON p.rowid = d.fk_projet"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as cp ON cp.id = d.fk_payment AND cp.entity = " . getEntity('c_paiement'); + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as cp ON cp.id = d.fk_payment AND cp.entity IN (".getEntity('c_paiement').")"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_country as c ON d.fk_country = c.rowid"; - if (! empty($id)) + $sql.= " WHERE d.entity IN (".getEntity('donation').")"; + if (! empty($id)) { - $sql.= " WHERE d.rowid=".$id; + $sql.= " AND d.rowid=".$id; } else if (! empty($ref)) { - $sql.= " WHERE ref='".$this->db->escape($ref)."'"; + $sql.= " AND ref='".$this->db->escape($ref)."'"; } - $sql.= " AND d.entity = ".$conf->entity; dol_syslog(get_class($this)."::fetch", LOG_DEBUG); $resql=$this->db->query($sql); @@ -842,9 +842,10 @@ class Don extends CommonObject * Return clicable name (with picto eventually) * * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto + * @param int $notooltip 1=Disable tooltip * @return string Chaine avec URL */ - function getNomUrl($withpicto=0) + function getNomUrl($withpicto=0, $notooltip=0) { global $langs; diff --git a/htdocs/don/class/donstats.class.php b/htdocs/don/class/donstats.class.php index 63105da07d2..dfe74b7f691 100644 --- a/htdocs/don/class/donstats.class.php +++ b/htdocs/don/class/donstats.class.php @@ -42,7 +42,7 @@ class DonationStats extends Stats var $from; var $field; var $where; - + /** * Constructor @@ -55,13 +55,13 @@ class DonationStats extends Stats function __construct($db, $socid, $mode, $userid=0) { global $user, $conf; - + $this->db = $db; - + $this->socid = ($socid > 0 ? $socid : 0); $this->userid = $userid; - $this->cachefilesuffix = $mode; - + $this->cachefilesuffix = $mode; + $object=new Don($this->db); $this->from = MAIN_DB_PREFIX.$object->table_element." as d"; //$this->from.= ", ".MAIN_DB_PREFIX."societe as s"; @@ -77,9 +77,10 @@ class DonationStats extends Stats * Return shipment number by month for a year * * @param int $year Year to scan + * @param int $format 0=Label of absiss is a translated text, 1=Label of absiss is month number, 2=Label of absiss is first letter of month * @return array Array with number by month */ - function getNbByMonth($year) + function getNbByMonth($year, $format=0) { global $user; @@ -90,7 +91,7 @@ class DonationStats extends Stats $sql.= " GROUP BY dm"; $sql.= $this->db->order('dm','DESC'); - $res=$this->_getNbByMonth($year, $sql); + $res=$this->_getNbByMonth($year, $sql, $format); return $res; } diff --git a/htdocs/don/class/paymentdonation.class.php b/htdocs/don/class/paymentdonation.class.php index 22fbcd6dab4..1785cf2e57d 100644 --- a/htdocs/don/class/paymentdonation.class.php +++ b/htdocs/don/class/paymentdonation.class.php @@ -172,10 +172,10 @@ class PaymentDonation extends CommonObject $sql.= " t.fk_user_modif,"; $sql.= " pt.code as type_code, pt.libelle as type_libelle,"; $sql.= ' b.fk_account'; - $sql.= " FROM (".MAIN_DB_PREFIX."c_paiement as pt, ".MAIN_DB_PREFIX."payment_donation as t)"; + $sql.= " FROM ".MAIN_DB_PREFIX."payment_donation as t"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as pt ON t.fk_typepayment = pt.id AND pt.entity IN (".getEntity('c_paiement').")"; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON t.fk_bank = b.rowid'; - $sql.= " WHERE t.rowid = ".$id." AND t.fk_typepayment = pt.id"; - $sql.= " AND pt.entity = " . getEntity('c_paiement'); + $sql.= " WHERE t.rowid = ".$id; dol_syslog(get_class($this)."::fetch", LOG_DEBUG); $resql=$this->db->query($sql); diff --git a/htdocs/don/index.php b/htdocs/don/index.php index 4912b6d8f1a..b72e63f7797 100644 --- a/htdocs/don/index.php +++ b/htdocs/don/index.php @@ -52,9 +52,10 @@ llxHeader('',$langs->trans("Donations"),$help_url); $nb=array(); $somme=array(); +$total = 0; $sql = "SELECT count(d.rowid) as nb, sum(d.amount) as somme , d.fk_statut"; -$sql.= " FROM ".MAIN_DB_PREFIX."don as d"; +$sql.= " FROM ".MAIN_DB_PREFIX."don as d WHERE d.entity IN (".getEntity('donation').")"; $sql.= " GROUP BY d.fk_statut"; $sql.= " ORDER BY d.fk_statut"; @@ -69,6 +70,8 @@ if ($result) $somme[$objp->fk_statut] = $objp->somme; $nb[$objp->fk_statut] = $objp->nb; + $total += $objp->somme; + $i++; } $db->free($result); @@ -87,7 +90,7 @@ if (! empty($conf->global->MAIN_SEARCH_FORM_ON_HOME_AREAS)) // This is usele { $listofsearchfields['search_donation']=array('text'=>'Donation'); } - + if (count($listofsearchfields)) { print ''; @@ -103,7 +106,7 @@ if (! empty($conf->global->MAIN_SEARCH_FORM_ON_HOME_AREAS)) // This is usele print ''; $i++; } - print '
    '; + print ''; print ''; print '
    '; } @@ -118,14 +121,23 @@ print "\n"; $listofstatus=array(0,1,-1,2); foreach ($listofstatus as $status) { - $dataseries[]=array('label'=>$donstatic->LibStatut($status,1),'data'=>(isset($nb[$status])?(int) $nb[$status]:0)); + $dataseries[]=array($donstatic->LibStatut($status,1), (isset($nb[$status])?(int) $nb[$status]:0)); } if ($conf->use_javascript_ajax) { - print ''; - $data=array('series'=>$dataseries); - dol_print_graph('stats',300,180,$data,1,'pie',1); + print ''; + + include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; + $dolgraph = new DolGraph(); + $dolgraph->SetData($dataseries); + $dolgraph->setShowLegend(1); + $dolgraph->setShowPercent(1); + $dolgraph->SetType(array('pie')); + $dolgraph->setWidth('100%'); + $dolgraph->draw('idgraphstatus'); + print $dolgraph->show($total?0:1); + print ''; } @@ -141,7 +153,7 @@ $totalnb=0; $var=true; foreach ($listofstatus as $status) { - + print ''; print ''.$donstatic->LibStatut($status,4).''; print ''.(! empty($nb[$status])?$nb[$status]:' ').''; @@ -191,7 +203,7 @@ if ($resql) $var = True; while ($i < $num) { - + $obj = $db->fetch_object($resql); print ''; diff --git a/htdocs/don/list.php b/htdocs/don/list.php index cb5ab766ae9..46692c9025b 100644 --- a/htdocs/don/list.php +++ b/htdocs/don/list.php @@ -43,7 +43,7 @@ if (! $sortorder) $sortorder="DESC"; if (! $sortfield) $sortfield="d.datedon"; $statut=(GETPOST("statut",'intcomma')!='')?GETPOST("statut",'intcomma'):"-1"; -$search_all=GETPOST('sall', 'alphanohtml'); +$search_all=trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alphanohtml'):GETPOST('sall', 'alphanohtml')); $search_ref=GETPOST('search_ref','alpha'); $search_company=GETPOST('search_company','alpha'); $search_name=GETPOST('search_name','alpha'); diff --git a/htdocs/ecm/class/ecmdirectory.class.php b/htdocs/ecm/class/ecmdirectory.class.php index bbb80f52cba..019a749b6ef 100644 --- a/htdocs/ecm/class/ecmdirectory.class.php +++ b/htdocs/ecm/class/ecmdirectory.class.php @@ -39,19 +39,20 @@ class EcmDirectory // extends CommonObject var $cachenbofdoc=-1; // By default cache initialized with value 'not calculated' var $date_c; var $date_m; - public $fk_user_m; - public $fk_user_c; - public $ref; + public $fk_user_m; + public $fk_user_c; + public $ref; var $cats=array(); var $motherof=array(); - var $forbiddenchars = array('<','>',':','/','\\','?','*','|','"'); + var $forbiddenchars = array('<','>',':','/','\\','?','*','|','"'); + var $forbiddencharsdir = array('<','>',':','?','*','|','"'); - public $full_arbo_loaded; + public $full_arbo_loaded; - public $error; - public $errors; + public $error; + public $errors; /** @@ -104,8 +105,8 @@ class EcmDirectory // extends CommonObject $pathfound=0; foreach ($cate_arbo as $key => $categ) { - $path=str_replace($this->forbiddenchars,'_',$categ['fulllabel']); - //print $path.'
    '; + $path=str_replace($this->forbiddencharsdir, '_', $categ['fullrelativename']); + //print $relativepath.' - '.$path.'
    '; if ($path == $relativepath) { $pathfound=1; @@ -424,7 +425,7 @@ class EcmDirectory // extends CommonObject $label=$langs->trans("ShowECMSection").': '.$newref; $linkclose='"'.($more?' '.$more:'').' title="'.dol_escape_htmltag($label, 1).'" class="classfortooltip">'; - $linkstart = ' +/* Copyright (C) 2008-2017 Laurent Destailleur * * 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 @@ -17,15 +17,13 @@ /** * \file htdocs/ecm/class/htmlecm.form.class.php - * \brief Fichier de la classe des fonctions predefinie de composants html + * \brief File of class to manage HTML component for ECM and generic filemanager */ require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php'; /** - * \class FormEcm - * \brief Classe permettant la generation de composants html - * \remarks Only common components must be here. + * Class to manage HTML component for ECM and generic filemanager */ class FormEcm { @@ -52,13 +50,14 @@ class FormEcm * @param string $module Module ('ecm', 'medias', ...) * @return string String with HTML select */ - function select_all_sections($selected=0, $select_name='', $module='ecm') + function selectAllSections($selected=0, $select_name='', $module='ecm') { global $conf, $langs; $langs->load("ecm"); if ($select_name=='') $select_name="catParent"; + $cate_arbo=null; if ($module == 'ecm') { $cat = new EcmDirectory($this->db); @@ -80,7 +79,8 @@ class FormEcm $output.= ''; foreach($cate_arbo as $key => $value) { - if ($cate_arbo[$key]['id'] == $selected) + $valueforoption = empty($cate_arbo[$key]['id']) ? $cate_arbo[$key]['relativename'] : $cate_arbo[$key]['id']; + if ($selected && $valueforoption == $selected) { $add = 'selected '; } @@ -88,7 +88,7 @@ class FormEcm { $add = ''; } - $output.= ''; + $output.= ''; } } } diff --git a/htdocs/ecm/docdir.php b/htdocs/ecm/dir_add_card.php similarity index 70% rename from htdocs/ecm/docdir.php rename to htdocs/ecm/dir_add_card.php index 145da2aa7bd..ba935676e1e 100644 --- a/htdocs/ecm/docdir.php +++ b/htdocs/ecm/dir_add_card.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2008-2017 Laurent Destailleur * Copyright (C) 2008-2012 Regis Houssin * Copyright (C) 2015-2016 Alexandre Spangaro * @@ -29,15 +29,7 @@ require_once DOL_DOCUMENT_ROOT.'/ecm/class/htmlecm.form.class.php'; require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php'; // Load traductions files -$langs->load("ecm"); -$langs->load("companies"); -$langs->load("other"); -$langs->load("users"); -$langs->load("orders"); -$langs->load("propal"); -$langs->load("bills"); -$langs->load("contracts"); -$langs->load("categories"); +$langs->loadLangs(array("ecm","companies","other","users","orders","propal","bills","contracts","categories")); if (! $user->rights->ecm->setup) accessforbidden(); @@ -46,11 +38,12 @@ $socid = GETPOST('socid','int'); $action = GETPOST('action','alpha'); $cancel = GETPOST('cancel', 'aZ09'); $backtopage = GETPOST('backtopage', 'alpha'); -$confirm=GETPOST('confirm','alpha'); +$confirm = GETPOST('confirm','alpha'); $module = GETPOST('module', 'alpha'); $website = GETPOST('website', 'alpha'); $pageid = GETPOST('pageid', 'int'); +if (empty($module)) $module='ecm'; // Security check if ($user->societe_id > 0) @@ -66,7 +59,7 @@ if ($module == 'ecm') { $upload_dir = $conf->ecm->dir_output.'/'.$urlsection; } -if ($module == 'medias') +else // For example $module == 'medias' { $upload_dir = $conf->medias->multidir_output[$conf->entity]; } @@ -109,39 +102,84 @@ if ($action == 'add' && $user->rights->ecm->setup) } else { - header("Location: ".DOL_URL_ROOT.'/ecm/index.php?action=file_manager'); + header("Location: ".DOL_URL_ROOT.'/ecm/index.php?action=file_manager'.($module?'&module='.$module:'')); exit; } } - $ecmdir->ref = trim($_POST["ref"]); - $ecmdir->label = trim($_POST["label"]); - $ecmdir->description = trim($_POST["desc"]); - $ecmdir->fk_parent = $_POST["catParent"]; + $ref = trim(GETPOST("ref", 'alpha')); + $label = trim(GETPOST("label", 'alpha')); + $desc = trim(GETPOST("desc", 'alpha')); + $catParent = GETPOST("catParent", 'alpha'); // Can be an int (with ECM) or a string (with generic filemanager) - $ok=true; + $error=0; - if (! $ecmdir->label) + if (empty($label)) { setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentities("Label")), null, 'errors'); $action = 'create'; - $ok=false; + $error++; } - if ($ok) + if (! $error) { - $id = $ecmdir->create($user); - - if ($id > 0) + if ($module == 'ecm') { - header("Location: ".DOL_URL_ROOT.'/ecm/index.php?action=file_manager'); + $ecmdir->ref = $ref; + $ecmdir->label = $label; + $ecmdir->description = $desc; + $ecmdir->fk_parent = (int) $catParent; + + $id = $ecmdir->create($user); + if ($id <= 0) + { + $error++; + $langs->load("errors"); + setEventMessages($ecmdir->error, $ecmdir->errors, 'errors'); + $action = 'create'; + } + } + else // For example $module == 'medias' + { + $dirfornewdir = ''; + if ($module == 'medias') + { + $dirfornewdir = $conf->medias->multidir_output[$conf->entity]; + } + if (empty($dirfornewdir)) + { + $error++; + dol_print_error('', 'Bad value for module. Not supported.'); + } + + if (! $error) + { + $fullpathofdir = $dirfornewdir.'/'.($catParent? $catParent.'/' : '').$label; + $result = dol_mkdir($fullpathofdir, DOL_DATA_ROOT); + if ($result < 0) + { + setEventMessages($langs->trans('ErrorFailToCreateDir', $label), null, 'errors'); + $error++; + } + else + { + setEventMessages($langs->trans("ECMSectionWasCreated", $label), null, 'mesgs'); + } + } + } + } + + if (! $error) + { + if (! empty($backtopage)) + { + header("Location: ".$backtopage); exit; } else { - $langs->load("errors"); - setEventMessages($langs->trans($ecmdir->error), $ecmdir->errors, 'errors'); - $action = 'create'; + header("Location: ".DOL_URL_ROOT.'/ecm/index.php?action=file_manager'); + exit; } } } @@ -160,7 +198,7 @@ else if ($action == 'confirm_deletesection' && $confirm == 'yes') * View */ -llxHeader(); +llxHeader('', $langs->trans("ECMNewSection")); $form=new Form($db); $formecm=new FormEcm($db); @@ -170,12 +208,13 @@ if ($action == 'create') //*********************** // Create //*********************** - print '
    '; + print ''; print ''; print ''; - print ''; - if ($website) print ''; - if ($pageid) print ''; + print ''; + print ''; + if ($website) print ''; + if ($pageid) print ''; $title=$langs->trans("ECMNewSection"); print load_fiche_titre($title); @@ -188,7 +227,7 @@ if ($action == 'create') print ''.$langs->trans("Label").''."\n"; print ''.$langs->trans("AddIn").''; - print $formecm->select_all_sections(! empty($_GET["catParent"]) ? $_GET["catParent"] : $ecmdir->fk_parent, 'catParent', $module); + print $formecm->selectAllSections((GETPOST("catParent",'alpha') ? GETPOST("catParent",'alpha') : $ecmdir->fk_parent), 'catParent', $module); print ''."\n"; // Description @@ -207,7 +246,7 @@ if ($action == 'create') print '
    '; print ''; - print '     '; + print '     '; print ''; print '
    '; print '
    '; @@ -226,7 +265,7 @@ if (empty($action) || $action == 'delete_section') $ecmdir->ref=$ecmdir->label; print $langs->trans("ECMSection").': '; print img_picto('','object_dir').' '; - print '
    '.$langs->trans("ECMRoot").''; + print ''.$langs->trans("ECMRoot").''; //print ' -> '.$ecmdir->getNomUrl(1).'
    '; print "

    "; */ diff --git a/htdocs/ecm/docmine.php b/htdocs/ecm/dir_card.php similarity index 69% rename from htdocs/ecm/docmine.php rename to htdocs/ecm/dir_card.php index c722ba9a208..ce403469107 100644 --- a/htdocs/ecm/docmine.php +++ b/htdocs/ecm/dir_card.php @@ -17,7 +17,7 @@ /** - * \file htdocs/ecm/docmine.php + * \file htdocs/ecm/dir_card.php * \ingroup ecm * \brief Card of a directory for ECM module * \author Laurent Destailleur @@ -34,8 +34,15 @@ $langs->load("ecm"); $langs->load("companies"); $langs->load("other"); -$action=GETPOST('action','alpha'); -$confirm=GETPOST('confirm','alpha'); +$action = GETPOST('action','alpha'); +$cancel = GETPOST('cancel', 'aZ09'); +$backtopage = GETPOST('backtopage', 'alpha'); +$confirm = GETPOST('confirm','alpha'); + +$module = GETPOST('module', 'alpha'); +$website = GETPOST('website', 'alpha'); +$pageid = GETPOST('pageid', 'int'); +if (empty($module)) $module='ecm'; // Get parameters $sortfield = GETPOST("sortfield",'alpha'); @@ -48,24 +55,33 @@ $pagenext = $page + 1; if (! $sortorder) $sortorder="ASC"; if (! $sortfield) $sortfield="name"; -$section=GETPOST("section"); +$section=GETPOST("section", 'alpha')?GETPOST("section", 'alpha'):GETPOST("relativedir", 'alpha'); if (! $section) { dol_print_error('',"ErrorSectionParamNotDefined"); exit; } - // Load ecm object $ecmdir = new EcmDirectory($db); -$result=$ecmdir->fetch(GETPOST("section")); -if (! $result > 0) + +if ($module == 'ecm') { - dol_print_error($db,$ecmdir->error); - exit; + $result=$ecmdir->fetch($section); + if (! $result > 0) + { + dol_print_error($db, $ecmdir->error); + exit; + } + $relativepath=$ecmdir->getRelativePath(); + + $upload_dir = $conf->ecm->dir_output.'/'.$relativepath; +} +else // For example $module == 'medias' +{ + $relativepath = $section; + $upload_dir = $conf->medias->multidir_output[$conf->entity].'/'.$relativepath; } -$relativepath=$ecmdir->getRelativePath(); -$upload_dir = $conf->ecm->dir_output.'/'.$relativepath; @@ -210,7 +226,7 @@ foreach($filearray as $key => $file) } -$head = ecm_prepare_head($ecmdir); +$head = ecm_prepare_head($ecmdir, $module, $section); dol_fiche_head($head, 'card', $langs->trans("ECMSectionManual"), -1, 'dir'); @@ -219,75 +235,106 @@ if ($action == 'edit') print '
    '; print ''; print ''; + print ''; print ''; } -$s=''; -$result = 1; -$i=0; -$tmpecmdir=new EcmDirectory($db); // Need to create a new one -$tmpecmdir->fetch($ecmdir->id); -while ($tmpecmdir && $result > 0) -{ - $tmpecmdir->ref=$tmpecmdir->label; - if ($i == 0 && $action == 'edit') - { - $s=''; - } - else $s=$tmpecmdir->getNomUrl(1).$s; - if ($tmpecmdir->fk_parent) - { - $s=' -> '.$s; - $result=$tmpecmdir->fetch($tmpecmdir->fk_parent); - } - else - { - $tmpecmdir=0; - } - $i++; -} $morehtml=''; -$morehtmlref = ''.$langs->trans("ECMRoot").' -> '.$s; +$morehtmlref = '/'.$module.'/'.$relativepath; + +if ($module == 'ecm') +{ + $s=''; + $result = 1; + $i=0; + $tmpecmdir=new EcmDirectory($db); // Need to create a new one + $tmpecmdir->fetch($ecmdir->id); + while ($tmpecmdir && $result > 0) + { + $tmpecmdir->ref=$tmpecmdir->label; + if ($i == 0 && $action == 'edit') + { + $s=''; + } + else $s=$tmpecmdir->getNomUrl(1).$s; + if ($tmpecmdir->fk_parent) + { + $s=' -> '.$s; + $result=$tmpecmdir->fetch($tmpecmdir->fk_parent); + } + else + { + $tmpecmdir=0; + } + $i++; + } + + $morehtmlref = ''.$langs->trans("ECMRoot").' -> '.$s; +} + + dol_banner_tab($object, '', $morehtml, 0, '', '', $morehtmlref); print '
    '; print '
    '; -print ''; +print '
    '; /*print '';*/ -print ''; + + print ''; +} +print ''; -print ''; -print ''; print ''; print ''; print ''; + print ''; print ''; print ''; print '
    '.$langs->trans("Ref").''; print img_picto('','object_dir').' '.$langs->trans("ECMRoot").' -> '; print $s; print '
    '.$langs->trans("Description").''; -if ($action == 'edit') +if ($module == 'ecm') { - print ''; + print '
    '.$langs->trans("Description").''; + if ($action == 'edit') + { + print ''; + } + else print dol_nl2br($ecmdir->description); + print '
    '.$langs->trans("ECMCreationUser").''; + $userecm=new User($db); + $userecm->fetch($ecmdir->fk_user_c); + print $userecm->getNomUrl(1); + print '
    '.$langs->trans("ECMCreationDate").''; +if ($module == 'ecm') +{ + print dol_print_date($ecmdir->date_c,'dayhour'); +} +else +{ + //var_dump($upload_dir); + print dol_print_date(dol_filemtime($upload_dir), 'dayhour'); } -else print dol_nl2br($ecmdir->description); -print '
    '.$langs->trans("ECMCreationUser").''; -$userecm=new User($db); -$userecm->fetch($ecmdir->fk_user_c); -print $userecm->getNomUrl(1); -print '
    '.$langs->trans("ECMCreationDate").''; -print dol_print_date($ecmdir->date_c,'dayhour'); print '
    '.$langs->trans("ECMDirectoryForFiles").''; -print '/ecm/'.$relativepath; +if ($module == 'ecm') +{ + print '/ecm/'.$relativepath; +} +else +{ + print '/'.$module.'/'.$relativepath; +} print '
    '.$langs->trans("ECMNbOfDocs").''; $nbofiles=count($filearray); print $nbofiles; -// Test if nb is same than in cache -if ($nbofiles != $ecmdir->cachenbofdoc) +if ($ecmdir->id > 0) { - $ecmdir->changeNbOfFiles((string) $nbofiles); + // Test if nb is same than in cache + if ($nbofiles != $ecmdir->cachenbofdoc) + { + $ecmdir->changeNbOfFiles((string) $nbofiles); + } } print '
    '.$langs->trans("TotalSizeOfAttachedFiles").''; @@ -321,12 +368,12 @@ if ($action != 'edit' && $action != 'delete') if ($user->rights->ecm->setup) { - print ''.$langs->trans('Edit').''; + print ''.$langs->trans('Edit').''; } if ($user->rights->ecm->setup) { - print ''.$langs->trans('ECMAddSection').''; + print ''.$langs->trans('ECMAddSection').''; } else { @@ -337,7 +384,7 @@ if ($action != 'edit' && $action != 'delete') { if ($user->rights->ecm->setup) { - print ''.$langs->trans('Delete').''; + print ''.$langs->trans('Delete').''; } else { @@ -354,25 +401,24 @@ if ($action != 'edit' && $action != 'delete') // Confirm remove file if ($action == 'delete') { - print $form->formconfirm($_SERVER["PHP_SELF"].'?section='.$_REQUEST["section"].'&urlfile='.urlencode($_GET["urlfile"]), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile'); - + print $form->formconfirm($_SERVER["PHP_SELF"].'?section='.GETPOST("section",'alpha').'&urlfile='.urlencode($_GET["urlfile"]), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile'); } // Confirm remove file if ($action == 'delete_dir') { $relativepathwithoutslash=preg_replace('/[\/]$/','',$relativepath); - print $form->formconfirm($_SERVER["PHP_SELF"].'?section='.$_REQUEST["section"], $langs->trans('DeleteSection'), $langs->trans('ConfirmDeleteSection',$relativepathwithoutslash), 'confirm_deletedir', '', 1, 1); - + print $form->formconfirm($_SERVER["PHP_SELF"].'?section='.GETPOST('section','alpha').($module?'&module='.$module:''), $langs->trans('DeleteSection'), $langs->trans('ConfirmDeleteSection',$relativepathwithoutslash), 'confirm_deletedir', '', 1, 1); } -$formfile=new FormFile($db); /* +$formfile=new FormFile($db); + // Display upload form if ($user->rights->ecm->upload) { - $formfile->form_attach_new_file(DOL_URL_ROOT.'/ecm/docmine.php','',0,$section); + $formfile->form_attach_new_file(DOL_URL_ROOT.'/ecm/dir_card.php','',0,$section); } // List of document diff --git a/htdocs/ecm/docother.php b/htdocs/ecm/docother.php deleted file mode 100644 index addf559e01c..00000000000 --- a/htdocs/ecm/docother.php +++ /dev/null @@ -1,171 +0,0 @@ - - */ - -/** - * \file htdocs/ecm/docother.php - * \ingroup ecm - * \brief Main ecm page - * \author Laurent Destailleur - */ - -require '../main.inc.php'; -require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; - -// Load traductions files -$langs->load("ecm"); -$langs->load("companies"); -$langs->load("other"); - -// Get parameters -$socid = GETPOST("socid","int"); - -// Security check -if ($user->societe_id > 0) -{ - $action = ''; - $socid = $user->societe_id; -} - -$section=$_GET["section"]; -if (! $section) $section='misc'; -$upload_dir = $conf->ecm->dir_output.'/'.$section; - - - -/******************************************************************* - * ACTIONS - * - * Put here all code to do according to value of "action" parameter - ********************************************************************/ - -// Envoie fichier -if ( $_POST["sendit"] && ! empty($conf->global->MAIN_UPLOAD_DOC)) -{ - if (dol_mkdir($upload_dir) >= 0) - { - $resupload = dol_move_uploaded_file($_FILES['userfile']['tmp_name'], $upload_dir . "/" . dol_unescapefile($_FILES['userfile']['name']),0,0,$_FILES['userfile']['error']); - if (is_numeric($resupload) && $resupload > 0) - { - $result=$ecmdir->changeNbOfFiles('+'); - } - else - { - $langs->load("errors"); - if ($resupload < 0) // Unknown error - { - setEventMessages($langs->trans("ErrorFileNotUploaded"), null, 'errors'); - } - else if (preg_match('/ErrorFileIsInfectedWithAVirus/',$resupload)) // Files infected by a virus - { - setEventMessages($langs->trans("ErrorFileIsInfectedWithAVirus"), null, 'errors'); - } - else // Known error - { - setEventMessages($langs->trans($resupload), null, 'errors'); - } - } - } - else - { - // Echec transfert (fichier depassant la limite ?) - $langs->load("errors"); - $mesg = '
    '.$langs->trans("ErrorFailToCreateDir",$upload_dir).'
    '; - } -} - -// Suppression fichier -if ($_POST['action'] == 'confirm_deletefile' && $_POST['confirm'] == 'yes') -{ - $langs->load("other"); - $file = $upload_dir . "/" . GETPOST('urlfile'); // Do not use urldecode here ($_GET and $_REQUEST are already decoded by PHP). - $ret=dol_delete_file($file); - if ($ret) setEventMessages($langs->trans("FileWasRemoved", GETPOST('urlfile')), null, 'mesgs'); - else setEventMessages($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), null, 'errors'); -} - - - - - -/******************************************************************* - * PAGE - * - * Put here all code to do according to value of "action" parameter - ********************************************************************/ - -llxHeader(); - -$form=new Form($db); - -print load_fiche_titre($langs->trans("ECMAutoOrg")); - -//$head = societe_prepare_head($societe); - - - -/* - * Confirmation of deleting a product line - */ -if ($_GET['action'] == 'delete_file') -{ - print $form->formconfirm($_SERVER["PHP_SELF"].'?socid='.$socid.'&urlfile='.urldecode($_GET["urlfile"]), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile'); - -} - -// Construct files list -clearstatcache(); -$totalsize=0; -$filearray=array(); -$errorlevel=error_reporting(); -error_reporting(0); -$handle=opendir($upload_dir); -error_reporting($errorlevel); -if (is_resource($handle)) -{ - $i=0; - while (($file = readdir($handle))!==false) - { - if (!is_dir($dir.$file) && substr($file, 0, 1) <> '.' && substr($file, 0, 3) <> 'CVS') - { - $filearray[$i]->name=$file; - $filearray[$i]->size=dol_filesize($upload_dir."/".$file); - $filearray[$i]->date=dol_filemtime($upload_dir."/".$file); - $totalsize+=$filearray[$i]->size; - $i++; - } - } - closedir($handle); -} -else -{ - // print '
    '.$langs->trans("ErrorCanNotReadDir",$upload_dir).'
    '; -} - - -/* - -print ''; - -// Nbre fichiers -print ''; - -//Total taille -print ''; - -print '
    '.$langs->trans("NbOfAttachedFiles").''.count($filearray).'
    '.$langs->trans("TotalSizeOfAttachedFiles").''.$totalsize.' '.$langs->trans("bytes").'
    '; - -print ''; - -*/ - - -if ($mesg) { print $mesg."
    "; } - - -print $langs->trans("FeatureNotYetAvailable"); - -// End of page -llxFooter(); -$db->close(); diff --git a/htdocs/ecm/docfile.php b/htdocs/ecm/file_card.php similarity index 90% rename from htdocs/ecm/docfile.php rename to htdocs/ecm/file_card.php index 5a14b95291f..8c62cbe18f2 100644 --- a/htdocs/ecm/docfile.php +++ b/htdocs/ecm/file_card.php @@ -16,7 +16,7 @@ */ /** - * \file htdocs/ecm/docfile.php + * \file htdocs/ecm/file_card.php * \ingroup ecm * \brief Card of a file for ECM module */ @@ -123,7 +123,7 @@ if ($cancel) } else { - header("Location: ".DOL_URL_ROOT.'/ecm/docfile.php?urlfile='.urlencode($urlfile).'§ion='.urlencode($section)); + header('Location: '.$_SERVER["PHP_SELF"].'?urlfile='.urlencode($urlfile).'§ion='.urlencode($section).($module?'&module='.urlencode($module):'')); exit; } } @@ -216,7 +216,7 @@ if ($action == 'update') $db->commit(); $urlfile=$newlabel; - header("Location: ".DOL_URL_ROOT.'/ecm/docfile.php?urlfile='.urlencode($urlfile).'§ion='.urlencode($section)); + header('Location: '.$_SERVER["PHP_SELF"].'?urlfile='.urlencode($urlfile).'§ion='.urlencode($section)); exit; } else @@ -242,7 +242,8 @@ if ($action == 'edit') print ''; print ''; print ''; - print ''; + print ''; + print ''; print ''; print ''; } @@ -341,15 +342,19 @@ if (! empty($object->share)) if ($action != 'edit') { $modulepart='ecm'; - $forcedownload=1; - $rellink='/document.php?modulepart='.$modulepart; - if ($forcedownload) $rellink.='&attachment=1'; - if (! empty($object->entity)) $rellink.='&entity='.$object->entity; - //$rellink.='&file='.urlencode($filepath); // No need of name of file for public link, we will use the hash - $fulllink=$urlwithroot.$rellink; - //if (! empty($object->ref)) $fulllink.='&hashn='.$object->ref; // Hash of file path + $forcedownload=0; + + $paramlink=''; + //if (! empty($modulepart)) $paramlink.=($paramlink?'&':'').'modulepart='.$modulepart; // For sharing with hash (so public files), modulepart is not required. + //if (! empty($object->entity)) $paramlink.='&entity='.$object->entity; // For sharing with hash (so public files), entity is not required. + //$paramlink.=($paramlink?'&':'').'file='.urlencode($filepath); // No need of name of file for public link, we will use the hash + if (! empty($object->share)) $paramlink.=($paramlink?'&':'').'hashp='.$object->share; // Hash for public share + if ($forcedownload) $paramlink.=($paramlink?'&':'').'attachment=1'; + + $fulllink=$urlwithroot.'/document.php'.($paramlink?'?'.$paramlink:''); + //if (! empty($object->ref)) $fulllink.='&hashn='.$object->ref; // Hash of file path //elseif (! empty($object->label)) $fulllink.='&hashc='.$object->label; // Hash of file content - if (! empty($object->share)) $fulllink.='&hashp='.$object->share; // Hash for public share + print img_picto('','object_globe.png').' '; if ($action != 'edit') print ''; else print $fulllink; diff --git a/htdocs/ecm/index.php b/htdocs/ecm/index.php index 8841778ce26..5895cc9b793 100644 --- a/htdocs/ecm/index.php +++ b/htdocs/ecm/index.php @@ -77,8 +77,8 @@ $error=0; * Actions */ -// Upload file -if (GETPOST("sendit") && ! empty($conf->global->MAIN_UPLOAD_DOC)) +// Upload file (code similar but different than actions_linkedfiles.inc.php) +if (GETPOST("sendit",'none') && ! empty($conf->global->MAIN_UPLOAD_DOC)) { // Define relativepath and upload_dir $relativepath=''; @@ -86,14 +86,20 @@ if (GETPOST("sendit") && ! empty($conf->global->MAIN_UPLOAD_DOC)) else $relativepath=$section_dir; $upload_dir = $conf->ecm->dir_output.'/'.$relativepath; - if (empty($_FILES['userfile']['tmp_name'])) + if (is_array($_FILES['userfile']['tmp_name'])) $userfiles=$_FILES['userfile']['tmp_name']; + else $userfiles=array($_FILES['userfile']['tmp_name']); + + foreach($userfiles as $key => $userfile) { - $error++; - if($_FILES['userfile']['error'] == 1 || $_FILES['userfile']['error'] == 2){ - setEventMessages($langs->trans('ErrorFileSizeTooLarge'),null, 'errors'); - } - else { - setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("File")), null, 'errors'); + if (empty($_FILES['userfile']['tmp_name'][$key])) + { + $error++; + if ($_FILES['userfile']['error'][$key] == 1 || $_FILES['userfile']['error'][$key] == 2){ + setEventMessages($langs->trans('ErrorFileSizeTooLarge'), null, 'errors'); + } + else { + setEventMessages($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("File")), null, 'errors'); + } } } @@ -107,8 +113,6 @@ if (GETPOST("sendit") && ! empty($conf->global->MAIN_UPLOAD_DOC)) } } - - // Add directory if ($action == 'add' && $user->rights->ecm->setup) { @@ -131,7 +135,7 @@ if ($action == 'add' && $user->rights->ecm->setup) clearstatcache(); } -// Remove file +// Remove file (code similar but different than actions_linkedfiles.inc.php) if ($action == 'confirm_deletefile') { if (GETPOST('confirm') == 'yes') @@ -141,7 +145,6 @@ if ($action == 'confirm_deletefile') $upload_dir = $conf->ecm->dir_output.($relativepath?'/'.$relativepath:''); $file = $upload_dir . "/" . GETPOST('urlfile','alpha'); // Do not use urldecode here ($_GET and $_POST are already decoded by PHP). - //var_dump($file);exit; $ret=dol_delete_file($file); // This include also the delete from file index in database. if ($ret) @@ -335,7 +338,7 @@ dol_fiche_head($head, 'index', $langs->trans("ECMArea").' - '.$langs->trans("ECM // Add filemanager component $module='ecm'; -include DOL_DOCUMENT_ROOT.'/ecm/tpl/filemanager.tpl.php'; +include DOL_DOCUMENT_ROOT.'/core/tpl/filemanager.tpl.php'; // End of page dol_fiche_end(); diff --git a/htdocs/ecm/search.php b/htdocs/ecm/search.php index c52476aef02..4dbebac97c3 100644 --- a/htdocs/ecm/search.php +++ b/htdocs/ecm/search.php @@ -30,14 +30,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/lib/treeview.lib.php'; require_once DOL_DOCUMENT_ROOT.'/ecm/class/ecmdirectory.class.php'; // Load traductions files -$langs->load("ecm"); -$langs->load("companies"); -$langs->load("other"); -$langs->load("users"); -$langs->load("orders"); -$langs->load("propal"); -$langs->load("bills"); -$langs->load("contracts"); +$langs->loadLangs(array("ecm","companies","other","users","orders","propal","bills","contracts")); // Security check if ($user->societe_id) $socid=$user->societe_id; @@ -52,6 +45,11 @@ $action = GETPOST('action','alpha'); $section=GETPOST('section'); if (! $section) $section=0; +$module = GETPOST('module', 'alpha'); +$website = GETPOST('website', 'alpha'); +$pageid = GETPOST('pageid', 'int'); +if (empty($module)) $module='ecm'; + $upload_dir = $conf->ecm->dir_output.'/'.$section; $sortfield = GETPOST("sortfield",'alpha'); @@ -123,7 +121,7 @@ print load_fiche_titre($langs->trans("ECMArea").' - '.$langs->trans("Search")); print $langs->trans("FeatureNotYetAvailable").'.

    '; // Tool bar -$head = ecm_prepare_head_fm($ecmdir); +$head = ecm_prepare_head_fm($ecmdir, $module, $section); //dol_fiche_head($head, 'search_form', '', 1); diff --git a/htdocs/ecm/tpl/enablefiletreeajax.tpl.php b/htdocs/ecm/tpl/enablefiletreeajax.tpl.php index 3e77c0acd92..cb21c7c2799 100644 --- a/htdocs/ecm/tpl/enablefiletreeajax.tpl.php +++ b/htdocs/ecm/tpl/enablefiletreeajax.tpl.php @@ -25,6 +25,7 @@ @@ -34,21 +35,30 @@ $(document).ready(function() { $('#filetree').fileTree({ root: '', // Ajax called if we click to expand a dir (not a file). Parameter 'dir' is provided as a POST parameter by fileTree code to this following URL. - script: '', + script: '', folderEvent: 'click', // 'dblclick' multiFolder: false }, // Called if we click on a file (not a dir) function(file) { + console.log("We click on a file"); $("#mesg").hide(); loadandshowpreview(file,0); }, // Called if we click on a dir (not a file) function(elem) { id=elem.attr('id').substr(12); // We get id that is 'fmdirlia_id_xxx' (id we want is xxx) - jQuery("#_section_dir").val(elem.attr('rel')); + rel=elem.attr('rel') + console.log("We click on a dir, we call the ajaxdirtree.php with modulepart=, param="); + console.log("We also save dir name or id into _section_... with name section_... id="+id+" rel="+rel); + jQuery("#_section_dir").val(rel); jQuery("#_section_id").val(id); + jQuery("#section_dir").val(rel); + jQuery("#section_id").val(id); + jQuery("#section").val(id); jQuery('#').show(); + console.log("We also execute the loadandshowpreview() that is on the onclick of each li defined by ajaxdirtree"); } + // The loadanshowpreview is also call by the 'onclick' set on each li return by ajaxdirtree ); $('#refreshbutton').click( function() { @@ -73,7 +83,7 @@ function loadandshowpreview(filedirname,section) $('#ecmfileview').empty(); - var url = '?action=preview&module=§ion='+section+'&file='+urlencode(filedirname); + var url = '?action=preview&module=§ion='+section+'&file='+urlencode(filedirname); $.get(url, function(data) { //alert('Load of url '+url+' was performed : '+data); pos=data.indexOf("TYPE=directory",0); diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index e85cb70a74d..1318e3f2857 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -52,14 +52,8 @@ if (! empty($conf->projet->enabled)) { require_once DOL_DOCUMENT_ROOT.'/core/class/html.formprojet.class.php'; } -$langs->load("sendings"); -$langs->load("companies"); -$langs->load("bills"); -$langs->load('deliveries'); -$langs->load('orders'); -$langs->load('stocks'); -$langs->load('other'); -$langs->load('propal'); +$langs->loadLangs(array("sendings","companies","bills",'deliveries','orders','stocks','other','propal')); + if (!empty($conf->incoterm->enabled)) $langs->load('incoterm'); if (! empty($conf->productbatch->enabled)) $langs->load('productbatch'); @@ -108,6 +102,7 @@ include DOL_DOCUMENT_ROOT.'/core/actions_fetchobject.inc.php'; // Must be inclu $hookmanager->initHooks(array('expeditioncard','globalcard')); $permissiondellink=$user->rights->expedition->livraison->creer; // Used by the include of actions_dellink.inc.php +//var_dump($object->lines[0]->detail_batch); /* @@ -653,7 +648,6 @@ if (empty($reshook)) else if ($action == 'updateline' && $user->rights->expedition->creer && GETPOST('save')) { // Clean parameters - $qty=0; $entrepot_id = 0; $batch_id = 0; @@ -662,9 +656,8 @@ if (empty($reshook)) $num_prod = count($lines); for ($i = 0 ; $i < $num_prod ; $i++) { - if ($lines[$i]->id == $line_id) + if ($lines[$i]->id == $line_id) // we have found line to update { - // line to update $line = new ExpeditionLigne($db); // Extrafields Lines $extrafieldsline = new ExtraFields($db); @@ -750,7 +743,7 @@ if (empty($reshook)) } } } - if ($lineIdToAddLot) + if ($lineIdToAddLot) { // add lot to existing line if ($line->fetch($lineIdToAddLot) > 0) @@ -787,7 +780,7 @@ if (empty($reshook)) } } } - else + else { setEventMessages($lotStock->error, $lotStock->errors, 'errors'); $error++; @@ -796,46 +789,61 @@ if (empty($reshook)) } else { - // line without lot - if ($lines[$i]->entrepot_id > 0) + if ($lines[$i]->fk_product > 0) + { + // line without lot + if ($lines[$i]->entrepot_id > 0) + { + // single warehouse shipment line + $stockLocation="entl".$line_id; + $qty = "qtyl".$line_id; + $line->id = $line_id; + $line->entrepot_id = GETPOST($stockLocation,'int'); + $line->qty = GETPOST($qty, 'int'); + if ($line->update($user) < 0) { + setEventMessages($line->error, $line->errors, 'errors'); + $error++; + } + unset($_POST[$stockLocation]); + unset($_POST[$qty]); + } + else if (count($lines[$i]->details_entrepot) > 1) + { + // multi warehouse shipment lines + foreach ($lines[$i]->details_entrepot as $detail_entrepot) + { + if (! $error) { + $stockLocation="entl".$detail_entrepot->line_id; + $qty = "qtyl".$detail_entrepot->line_id; + $warehouse = GETPOST($stockLocation,'int'); + if (!empty ($warehouse)) + { + $line->id = $detail_entrepot->line_id; + $line->entrepot_id = $warehouse; + $line->qty = GETPOST($qty, 'int'); + if ($line->update($user) < 0) { + setEventMessages($line->error, $line->errors, 'errors'); + $error++; + } + } + unset($_POST[$stockLocation]); + unset($_POST[$qty]); + } + } + } + } + else // Product no predefined { - // single warehouse shipment line - $stockLocation="entl".$line_id; $qty = "qtyl".$line_id; $line->id = $line_id; - $line->entrepot_id = GETPOST($stockLocation,'int'); $line->qty = GETPOST($qty, 'int'); + $line->entrepot_id = 0; if ($line->update($user) < 0) { setEventMessages($line->error, $line->errors, 'errors'); $error++; } - unset($_POST[$stockLocation]); unset($_POST[$qty]); } - else if (count($lines[$i]->details_entrepot) > 1) - { - // multi warehouse shipment lines - foreach ($lines[$i]->details_entrepot as $detail_entrepot) - { - if (! $error) { - $stockLocation="entl".$detail_entrepot->line_id; - $qty = "qtyl".$detail_entrepot->line_id; - $warehouse = GETPOST($stockLocation,'int'); - if (!empty ($warehouse)) - { - $line->id = $detail_entrepot->line_id; - $line->entrepot_id = $warehouse; - $line->qty = GETPOST($qty, 'int'); - if ($line->update($user) < 0) { - setEventMessages($line->error, $line->errors, 'errors'); - $error++; - } - } - unset($_POST[$stockLocation]); - unset($_POST[$qty]); - } - } - } } } } @@ -1178,7 +1186,8 @@ if ($action == 'create') if ($line->fk_product > 0) // If predefined product { $product->fetch($line->fk_product); - $product->load_stock('warehouseopen'); + $product->load_stock('warehouseopen'); // Load all $product->stock_warehouse[idwarehouse]->detail_batch + //var_dump($product->stock_warehouse[1]); print '
    '; print ''; // ancre pour retourner sur la ligne @@ -1259,7 +1268,7 @@ if ($action == 'create') { // Quantity to send print ''; - if ($line->product_type == 0 || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) + if ($line->product_type == Product::TYPE_PRODUCT || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) { if (GETPOST('qtyl'.$indiceAsked, 'int')) $defaultqty=GETPOST('qtyl'.$indiceAsked, 'int'); print ''; @@ -1272,7 +1281,7 @@ if ($action == 'create') if (! empty($conf->stock->enabled)) { print ''; - if ($line->product_type == 0 || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) // Type of product need stock change ? + if ($line->product_type == Product::TYPE_PRODUCT || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) // Type of product need stock change ? { // Show warehouse combo list $ent = "entl".$indiceAsked; @@ -1355,13 +1364,21 @@ if ($action == 'create') print ''; print ''; print $staticwarehouse->getNomUrl(0).' / '; - print ''; print ''; - print $langs->trans("DetailBatchFormat", $dbatch->batch, dol_print_date($dbatch->eatby,"day"), dol_print_date($dbatch->sellby,"day"), $dbatch->qty); + + $detail=''; + $detail.= $langs->trans("Batch").': '.$dbatch->batch; + $detail.= ' - '.$langs->trans("SellByDate").': '.dol_print_date($dbatch->sellby,"day"); + $detail.= ' - '.$langs->trans("EatByDate").': '.dol_print_date($dbatch->eatby,"day"); + $detail.= ' - '.$langs->trans("Qty").': '.$dbatch->dluo_qty; + $detail.= '
    '; + print $detail; + $quantityToBeDelivered -= $deliverableQty; if ($quantityToBeDelivered < 0) { @@ -1415,7 +1432,7 @@ if ($action == 'create') // Quantity to send print '
    '; - if ($line->product_type == 0 || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) + if ($line->product_type == Product::TYPE_PRODUCT || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) { print ''; print ''; @@ -1427,7 +1444,7 @@ if ($action == 'create') if (! empty($conf->stock->enabled)) { print ''; - if ($line->product_type == 0 || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) + if ($line->product_type == Product::TYPE_PRODUCT || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) { print $tmpwarehouseObject->getNomUrl(0).' '; @@ -1517,14 +1534,12 @@ if ($action == 'create') print ''; print ''; - //print $langs->trans("DetailBatchFormat", $dbatch->batch, dol_print_date($dbatch->eatby,"day"), dol_print_date($dbatch->sellby,"day"), $dbatch->qty); //print $line->fk_product.' - '.$dbatch->batch; print $langs->trans("Batch").': '; $result = $productlotObject->fetch(0, $line->fk_product, $dbatch->batch); if ($result > 0) print $productlotObject->getNomUrl(1); else print 'TableLotIncompleteRunRepair'; print ' ('.$dbatch->qty.')'; - //print $langs->trans("DetailBatchFormat", 'ee'.$dbatch->batch, dol_print_date($dbatch->eatby,"day"), dol_print_date($dbatch->sellby,"day"), $dbatch->qty); $quantityToBeDelivered -= $deliverableQty; if ($quantityToBeDelivered < 0) { @@ -1542,7 +1557,7 @@ if ($action == 'create') { print ''; print '
    '; - if ($line->product_type == 0 || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) + if ($line->product_type == Product::TYPE_PRODUCT || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) { $disabled=''; if (! empty($conf->productbatch->enabled) && $product->hasbatch()) @@ -1558,7 +1573,7 @@ if ($action == 'create') print ''; - if ($line->product_type == 0 || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) + if ($line->product_type == Product::TYPE_PRODUCT || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) { $warehouse_selected_id = GETPOST('entrepot_id','int'); if ($warehouse_selected_id > 0) @@ -2010,9 +2025,8 @@ else if ($id || $ref) print '
    '; - /* - * Lines of products - */ + // Lines of products + if ($action == 'editline') { print ' @@ -2027,11 +2041,14 @@ else if ($id || $ref) print '
    '; print ''; print ''; + // # if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { print ''; } + // Product/Service print ''; + // Qty print ''; if ($origin && $origin_id > 0) { @@ -2107,7 +2124,7 @@ else if ($id || $ref) } } - // Get list of products already sent for same source object + // Get list of products already sent for same source object into $alreadysent $alreadysent = array(); if ($origin && $origin_id > 0) { @@ -2156,6 +2173,7 @@ else if ($id || $ref) print ''; // id of order line print ''; + // # if (! empty($conf->global->MAIN_VIEW_LINE_NUMBER)) { print ''; @@ -2195,7 +2213,7 @@ else if ($id || $ref) else { print "
     '.$langs->trans("Products").''.$langs->trans("QtyOrdered").'
    '.($i+1).'"; - if ($lines[$i]->fk_product_type==1) $text = img_object($langs->trans('Service'),'service'); + if ($lines[$i]->product_type == Product::TYPE_SERVICE) $text = img_object($langs->trans('Service'),'service'); else $text = img_object($langs->trans('Product'),'product'); if (! empty($lines[$i]->label)) { @@ -2246,9 +2264,10 @@ else if ($id || $ref) if ($action == 'editline' && $lines[$i]->id == $line_id) { // edit mode - print ''; + print ''; @@ -2339,13 +2380,18 @@ else if ($id || $ref) { if (isset($lines[$i]->detail_batch)) { + print ''; print ''; // Volume print ''; @@ -2477,7 +2523,7 @@ else if ($id || $ref) } // Create bill - if (! empty($conf->facture->enabled) && $object->statut > 0) + if (! empty($conf->facture->enabled) && ($object->statut == Expedition::STATUS_VALIDATED || $object->statut == Expedition::STATUS_CLOSED)) { if ($user->rights->facture->creer) { @@ -2489,18 +2535,18 @@ else if ($id || $ref) // This is just to generate a delivery receipt //var_dump($object->linkedObjectsIds['delivery']); - if ($conf->livraison_bon->enabled && ($object->statut == 1 || $object->statut == 2) && $user->rights->expedition->livraison->creer && count($object->linkedObjectsIds['delivery']) == 0) + if ($conf->livraison_bon->enabled && ($object->statut == Expedition::STATUS_VALIDATED || $object->statut == Expedition::STATUS_CLOSED) && $user->rights->expedition->livraison->creer && count($object->linkedObjectsIds['delivery']) == 0) { print ''.$langs->trans("CreateDeliveryOrder").''; } // Close - if (! empty($conf->facture->enabled) && $object->statut > 0) + if ($object->statut == Expedition::STATUS_VALIDATED) { if ($user->rights->expedition->creer && $object->statut > 0 && ! $object->billed) { $label="Close"; $paramaction='classifyclosed'; // = Transferred/Received // Label here should be "Close" or "ClassifyBilled" if we decided to make bill on shipments instead of orders - if (! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) // TODO Quand l'option est on, il faut avoir le bouton en plus et non en remplacement du Close. + if (! empty($conf->facture->enabled) && ! empty($conf->global->WORKFLOW_BILL_ON_SHIPMENT)) // Quand l'option est on, il faut avoir le bouton en plus et non en remplacement du Close ? { $label="ClassifyBilled"; $paramaction='classifybilled'; diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index 4807564e65f..88d43335603 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -644,7 +644,6 @@ class Expedition extends CommonObject $langs->load("agenda"); // Loop on each product line to add a stock movement - // TODO in future, shipment lines may not be linked to order line $sql = "SELECT cd.fk_product, cd.subprice,"; $sql.= " ed.rowid, ed.qty, ed.fk_entrepot,"; $sql.= " edb.rowid as edbrowid, edb.eatby, edb.sellby, edb.batch, edb.qty as edbqty, edb.fk_origin_stock"; @@ -1296,8 +1295,7 @@ class Expedition extends CommonObject $sql.= ", ed.rowid as line_id, ed.qty as qty_shipped, ed.fk_origin_line, ed.fk_entrepot"; $sql.= ", p.ref as product_ref, p.label as product_label, p.fk_product_type"; $sql.= ", p.weight, p.weight_units, p.length, p.length_units, p.surface, p.surface_units, p.volume, p.volume_units, p.tobatch as product_tobatch"; - $sql.= " FROM (".MAIN_DB_PREFIX."expeditiondet as ed,"; - $sql.= " ".MAIN_DB_PREFIX."commandedet as cd)"; + $sql.= " FROM ".MAIN_DB_PREFIX."expeditiondet as ed, ".MAIN_DB_PREFIX."commandedet as cd"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product as p ON p.rowid = cd.fk_product"; $sql.= " WHERE ed.fk_expedition = ".$this->id; $sql.= " AND ed.fk_origin_line = cd.rowid"; @@ -1412,12 +1410,13 @@ class Expedition extends CommonObject { $line->detail_batch = array(); } - // Eat-by date - if (! empty($conf->productbatch->enabled) && $obj->line_id > 0) + + // Detail of batch + if (! empty($conf->productbatch->enabled) && $obj->line_id > 0 && $obj->product_tobatch > 0) { require_once DOL_DOCUMENT_ROOT.'/expedition/class/expeditionbatch.class.php'; - $newdetailbatch = ExpeditionLineBatch::fetchAll($this->db,$obj->line_id); + $newdetailbatch = ExpeditionLineBatch::fetchAll($this->db, $obj->line_id, $obj->fk_product); if (is_array($newdetailbatch)) { if ($originline != $obj->fk_origin_line) @@ -2544,8 +2543,8 @@ class ExpeditionLigne extends CommonObjectLine if (! empty($batch) && $conf->productbatch->enabled) { - dol_syslog(get_class($this)."::update expedition batch id=$expedition_batch_id, batch_id=$batch_id, batch=$batch"); - + dol_syslog(get_class($this)."::update expedition batch id=$expedition_batch_id, batch_id=$batch_id, batch=$batch"); + if (empty($batch_id) || empty($this->fk_product)) { dol_syslog(get_class($this).'::update missing fk_origin_stock (batch_id) and/or fk_product', LOG_ERR); $this->errors[]='ErrorMandatoryParametersNotProvided'; @@ -2594,10 +2593,10 @@ class ExpeditionLigne extends CommonObjectLine $error++; } } - if (! $error && $this->detail_batch->dluo_qty > 0) + if (! $error && $this->detail_batch->dluo_qty > 0) { // create lot expedition line - if (isset($lot->id)) + if (isset($lot->id)) { $shipmentLot = new ExpeditionLineBatch($this->db); $shipmentLot->batch = $lot->batch; @@ -2606,7 +2605,7 @@ class ExpeditionLigne extends CommonObjectLine $shipmentLot->entrepot_id = $this->detail_batch->entrepot_id; $shipmentLot->dluo_qty = $this->detail_batch->dluo_qty; $shipmentLot->fk_origin_stock = $batch_id; - if ($shipmentLot->create($this->id) < 0) + if ($shipmentLot->create($this->id) < 0) { $this->errors[]=$shipmentLot->errors; $error++; @@ -2619,7 +2618,7 @@ class ExpeditionLigne extends CommonObjectLine { // update line $sql = "UPDATE ".MAIN_DB_PREFIX.$this->table_element." SET"; - $sql.= " fk_entrepot = ".$this->entrepot_id; + $sql.= " fk_entrepot = ".($this->entrepot_id > 0 ? $this->entrepot_id : 'null'); $sql.= " , qty = ".$qty; $sql.= " WHERE rowid = ".$this->id; diff --git a/htdocs/expedition/class/expeditionbatch.class.php b/htdocs/expedition/class/expeditionbatch.class.php index 5253156e32a..a4b3b17a98a 100644 --- a/htdocs/expedition/class/expeditionbatch.class.php +++ b/htdocs/expedition/class/expeditionbatch.class.php @@ -169,22 +169,33 @@ class ExpeditionLineBatch extends CommonObject } /** - * Retrieve all batch number details link to a shipment line + * Retrieve all batch number detailed information of a shipment line * - * @param DoliDB $db Database object - * @param int $id_line_expdet id of shipment line - * @return variant -1 if KO, array of ExpeditionLineBatch if OK + * @param DoliDB $db Database object + * @param int $id_line_expdet id of shipment line + * @param int $fk_product If provided, load also detailed information of lot + * @return int|array -1 if KO, array of ExpeditionLineBatch if OK */ - static function fetchAll($db,$id_line_expdet) + static function fetchAll($db, $id_line_expdet, $fk_product=0) { - $sql="SELECT rowid,"; - $sql.= "fk_expeditiondet"; - $sql.= ", sellby"; - $sql.= ", eatby"; - $sql.= ", batch"; - $sql.= ", qty"; - $sql.= ", fk_origin_stock"; - $sql.= " FROM ".MAIN_DB_PREFIX.self::$_table_element; + $sql="SELECT"; + $sql.= " eb.rowid,"; + $sql.= " eb.fk_expeditiondet,"; + $sql.= " eb.sellby as oldsellby,"; // deprecated + $sql.= " eb.eatby as oldeatby,"; // deprecated + $sql.= " eb.batch,"; + $sql.= " eb.qty,"; + $sql.= " eb.fk_origin_stock"; + if ($fk_product > 0) + { + $sql.= ", pl.sellby"; + $sql.= ", pl.eatby"; + } + $sql.= " FROM ".MAIN_DB_PREFIX.self::$_table_element." as eb"; + if ($fk_product > 0) + { + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."product_lot as pl ON pl.batch = eb.batch AND pl.fk_product = ".$fk_product; + } $sql.= " WHERE fk_expeditiondet=".(int) $id_line_expdet; dol_syslog(__METHOD__ ."", LOG_DEBUG); @@ -200,8 +211,8 @@ class ExpeditionLineBatch extends CommonObject $obj = $db->fetch_object($resql); - $tmp->sellby = $db->jdate($obj->sellby); - $tmp->eatby = $db->jdate($obj->eatby); + $tmp->sellby = $db->jdate($obj->sellby ? $obj->sellby : $obj->oldsellby); + $tmp->eatby = $db->jdate($obj->eatby ? $obj->eatby : $obj->oldeatby); $tmp->batch = $obj->batch; $tmp->id = $obj->rowid; $tmp->fk_origin_stock = $obj->fk_origin_stock; @@ -216,6 +227,7 @@ class ExpeditionLineBatch extends CommonObject } else { + dol_print_error($db); return -1; } } diff --git a/htdocs/expedition/class/expeditionstats.class.php b/htdocs/expedition/class/expeditionstats.class.php index 7fa16f4210f..5303d6d8b7b 100644 --- a/htdocs/expedition/class/expeditionstats.class.php +++ b/htdocs/expedition/class/expeditionstats.class.php @@ -42,7 +42,7 @@ class ExpeditionStats extends Stats var $from; var $field; var $where; - + /** * Constructor @@ -55,13 +55,13 @@ class ExpeditionStats extends Stats function __construct($db, $socid, $mode, $userid=0) { global $user, $conf; - + $this->db = $db; - + $this->socid = ($socid > 0 ? $socid : 0); $this->userid = $userid; - $this->cachefilesuffix = $mode; - + $this->cachefilesuffix = $mode; + $object=new Expedition($this->db); $this->from = MAIN_DB_PREFIX.$object->table_element." as c"; //$this->from.= ", ".MAIN_DB_PREFIX."societe as s"; @@ -82,9 +82,10 @@ class ExpeditionStats extends Stats * Return shipment number by month for a year * * @param int $year Year to scan + * @param int $format 0=Label of absiss is a translated text, 1=Label of absiss is month number, 2=Label of absiss is first letter of month * @return array Array with number by month */ - function getNbByMonth($year) + function getNbByMonth($year, $format=0) { global $user; @@ -96,7 +97,7 @@ class ExpeditionStats extends Stats $sql.= " GROUP BY dm"; $sql.= $this->db->order('dm','DESC'); - $res=$this->_getNbByMonth($year, $sql); + $res=$this->_getNbByMonth($year, $sql, $format); return $res; } diff --git a/htdocs/expedition/list.php b/htdocs/expedition/list.php index 5c7bf296485..ff4e056e928 100644 --- a/htdocs/expedition/list.php +++ b/htdocs/expedition/list.php @@ -30,9 +30,7 @@ require_once DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/company.lib.php'; -$langs->load("sendings"); -$langs->load("deliveries"); -$langs->load('companies'); +$langs->loadLangs(array("sendings","deliveries",'companies','bills')); $socid=GETPOST('socid','int'); // Security check @@ -52,7 +50,7 @@ $search_state=trim(GETPOST("search_state")); $search_country=GETPOST("search_country",'int'); $search_type_thirdparty=GETPOST("search_type_thirdparty",'int'); $search_billed=GETPOST("search_billed",'int'); -$sall = GETPOST('sall', 'alphanohtml'); +$sall = trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alphanohtml'):GETPOST('sall', 'alphanohtml')); $optioncss = GETPOST('optioncss','alpha'); $limit = GETPOST('limit','int')?GETPOST('limit','int'):$conf->liste_limit; @@ -228,19 +226,8 @@ if ($search_company) $sql .= natural_search('s.nom', $search_company); if ($sall) $sql .= natural_search(array_keys($fieldstosearchall), $sall); // Add where from extra fields -foreach ($search_array_options as $key => $val) -{ - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $typ=$extrafields->attribute_type[$tmpkey]; - $mode_search=0; - if (in_array($typ, array('int','double','real'))) $mode_search=1; // Search on a numeric - if (in_array($typ, array('sellist','link')) && $crit != '0' && $crit != '-1') $mode_search=2; // Search on a foreign key int - if ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0') && (! in_array($typ, array('link')) || $crit != '-1')) - { - $sql .= natural_search('ef.'.$tmpkey, $crit, $mode_search); - } -} +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; + // Add where from hooks $parameters=array(); $reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters); // Note that $action and $object may have been modified by hook @@ -274,12 +261,7 @@ if ($resql) if ($search_company) $param.= "&search_company=".urlencode($search_company); if ($optioncss != '') $param.='&optioncss='.urlencode($optioncss); // Add $param from extra fields - foreach ($search_array_options as $key => $val) - { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; //$massactionbutton=$form->selectMassAction('', $massaction == 'presend' ? array() : array('presend'=>$langs->trans("SendByMail"), 'builddoc'=>$langs->trans("PDFMerge"))); @@ -384,28 +366,8 @@ if ($resql) print ''; } // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $typeofextrafield=$extrafields->attribute_type[$key]; - print ''; - } - } - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; + // Fields from hook $parameters=array('arrayfields'=>$arrayfields); $reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook @@ -600,23 +562,7 @@ if ($resql) } // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - print ''; - if (! $i) $totalarray['nbfield']++; - } - } - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); $reshook=$hookmanager->executeHooks('printFieldListValue',$parameters); // Note that $action and $object may have been modified by hook diff --git a/htdocs/expedition/shipment.php b/htdocs/expedition/shipment.php index 3d3d8a0de6c..a358d349531 100644 --- a/htdocs/expedition/shipment.php +++ b/htdocs/expedition/shipment.php @@ -774,7 +774,7 @@ if ($id > 0 || ! empty($ref)) $product->load_stock('warehouseopen'); } - if ($objp->fk_product > 0 && $type == 0 && ! empty($conf->stock->enabled)) + if ($objp->fk_product > 0 && ($type == Product::TYPE_PRODUCT || ! empty($conf->global->STOCK_SUPPORTS_SERVICES)) && ! empty($conf->stock->enabled)) { print ''; print ''; print '\n"; $labeltype=$langs->trans("PaymentType".$objp->p_code)!=("PaymentType".$objp->p_code)?$langs->trans("PaymentType".$objp->p_code):$objp->fk_typepayment; print "\n"; - if (! empty($conf->banque->enabled)) { + if (! empty($conf->banque->enabled)) + { $bankaccountstatic->id = $objp->baid; $bankaccountstatic->ref = $objp->baref; $bankaccountstatic->label = $objp->baref; @@ -2391,47 +2390,39 @@ if (GETPOST('modelselected')) { if ($action != 'presend') { - print '
    '; /* * Generate documents */ - if($user->rights->expensereport->export && $action != 'create' && $action != 'edit') + print '
    '; + print ''; // ancre + + if($user->rights->expensereport->creer && $action != 'create' && $action != 'edit') { $filename = dol_sanitizeFileName($object->ref); $filedir = $conf->expensereport->dir_output . "/" . dol_sanitizeFileName($object->ref); $urlsource = $_SERVER["PHP_SELF"]."?id=".$object->id; - $genallowed = $user->rights->expensereport->export; - $delallowed = $user->rights->expensereport->export; + $genallowed = $user->rights->expensereport->creer; + $delallowed = $user->rights->expensereport->creer; $var = true; - print $formfile->showdocuments('expensereport',$filename,$filedir,$urlsource,$genallowed,$delallowed); + print $formfile->showdocuments('expensereport', $filename, $filedir, $urlsource, $genallowed, $delallowed); $somethingshown = $formfile->numoffiles; } - print '
    '; - if ($action != 'create' && $action != 'edit' && ($id || $ref)) { - $permissiondellink=$user->rights->facture->creer; // Used by the include of actions_dellink.inc.php - include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once - - // Link invoice to intervention - if (GETPOST('LinkedFichinter')) { - $object->fetch($id); - $object->fetch_thirdparty(); - $result = $object->add_object_linked('fichinter', GETPOST('LinkedFichinter')); - } - - // Show links to link elements - $linktoelements=array(); - if (! empty($conf->global->EXPENSES_LINK_TO_INTERVENTION)) - { - $linktoelements[]='fichinter'; - $linktoelem = $form->showLinkToObjectBlock($object, $linktoelements, array('expensereport')); - $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); - } + $linktoelem = $form->showLinkToObjectBlock($object, null, array('expensereport')); + $somethingshown = $form->showLinkedObjectBlock($object, $linktoelem); } + print '
    '; + // List of actions on element + include_once DOL_DOCUMENT_ROOT . '/core/class/html.formactions.class.php'; + $formactions = new FormActions($db); + $somethingshown = $formactions->showactions($object, 'expensereport', null); + + print '
    '; + } // Presend form diff --git a/htdocs/expensereport/class/api_expensereports.class.php b/htdocs/expensereport/class/api_expensereports.class.php index e89f4e35cdc..07250466fc0 100644 --- a/htdocs/expensereport/class/api_expensereports.class.php +++ b/htdocs/expensereport/class/api_expensereports.class.php @@ -378,7 +378,6 @@ class ExpenseReports extends DolibarrApi * * @return int */ - /* function put($id, $request_data = NULL) { if(! DolibarrApiAccess::$user->rights->expensereport->creer) { throw new RestException(401); @@ -397,12 +396,15 @@ class ExpenseReports extends DolibarrApi $this->expensereport->$field = $value; } - if($this->expensereport->update(DolibarrApiAccess::$user)) + if ($this->expensereport->update(DolibarrApiAccess::$user) > 0) + { return $this->get($id); - - return false; + } + else + { + throw new RestException(500, $this->task->error); + } } - */ /** * Delete Expense Report @@ -480,6 +482,24 @@ class ExpenseReports extends DolibarrApi ); }*/ + /** + * Clean sensible object datas + * + * @param object $object Object to clean + * @return array Array of cleaned object properties + */ + function _cleanObjectDatas($object) { + + $object = parent::_cleanObjectDatas($object); + + unset($object->barcode_type); + unset($object->barcode_type_code); + unset($object->barcode_type_label); + unset($object->barcode_type_coder); + + return $object; + } + /** * Validate fields before create or update object * diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index b2d6f052a2a..796be33104f 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -38,7 +38,7 @@ class ExpenseReport extends CommonObject var $fk_element = 'fk_expensereport'; var $picto = 'trip'; - var $lignes=array(); + var $lines=array(); public $date_debut; @@ -455,7 +455,7 @@ class ExpenseReport extends CommonObject $sql.= " d.fk_statut as status, d.fk_c_paiement,"; $sql.= " dp.libelle as libelle_paiement, dp.code as code_paiement"; // INNER JOIN paiement $sql.= " FROM ".MAIN_DB_PREFIX.$this->table_element." as d"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as dp ON d.fk_c_paiement = dp.id AND dp.entity = " . getEntity('c_paiement'); + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as dp ON d.fk_c_paiement = dp.id AND dp.entity IN (".getEntity('c_paiement').")"; if ($ref) $sql.= " WHERE d.ref = '".$this->db->escape($ref)."'"; else $sql.= " WHERE d.rowid = ".$id; //$sql.= $restrict; @@ -1520,13 +1520,13 @@ class ExpenseReport extends CommonObject $this->error=$obj->error; $this->errors=$obj->errors; //dol_print_error($this->db,get_class($this)."::getNextNumRef ".$obj->error); - return ""; + return -1; } } else { - print $langs->trans("Error")." ".$langs->trans("Error_EXPENSEREPORT_ADDON_NotDefined"); - return ""; + $this->error = "Error_EXPENSEREPORT_ADDON_NotDefined"; + return -2; } } @@ -1934,7 +1934,7 @@ class ExpenseReport extends CommonObject $tmp = calcul_price_total($qty, $value_unit, 0, $vatrate, 0, 0, 0, 'TTC', 0, $type, $seller, $localtaxes_type); - // calcul de tous les totaux de la ligne + // calcul total of line //$total_ttc = price2num($qty*$value_unit, 'MT'); $tx_tva = $vatrate / 100; @@ -2565,7 +2565,7 @@ class ExpenseReportLine $this->db->begin(); - // Mise a jour ligne en base + // Update line in database $sql = "UPDATE ".MAIN_DB_PREFIX."expensereport_det SET"; $sql.= " comments='".$this->db->escape($this->comments)."'"; $sql.= ",value_unit=".$this->value_unit; diff --git a/htdocs/expensereport/class/expensereport_ik.class.php b/htdocs/expensereport/class/expensereport_ik.class.php index da5c68da91b..a93d4e9062c 100644 --- a/htdocs/expensereport/class/expensereport_ik.class.php +++ b/htdocs/expensereport/class/expensereport_ik.class.php @@ -99,7 +99,7 @@ class ExpenseReportIk extends CoreObject $sql = 'SELECT rowid, label, entity, active'; $sql.= ' FROM '.MAIN_DB_PREFIX.'c_exp_tax_cat'; - $sql.= ' WHERE entity IN (0,'. getEntity('').')'; + $sql.= ' WHERE entity IN ('. getEntity('c_exp_tax_cat').')'; if ($mode == 1) $sql.= ' AND active = 1'; elseif ($mode == 2) $sql.= 'AND active = 0'; diff --git a/htdocs/expensereport/class/expensereportstats.class.php b/htdocs/expensereport/class/expensereportstats.class.php index d29e1202bf4..07396663f42 100644 --- a/htdocs/expensereport/class/expensereportstats.class.php +++ b/htdocs/expensereport/class/expensereportstats.class.php @@ -60,9 +60,9 @@ class ExpenseReportStats extends Stats $this->field='total_ht'; //$this->where = " e.fk_statut > 0"; - //$this->where.= " AND e.date_valid > '2000-01-01'"; // To filter only correct "valid date". If date is invalid, the group by on it will fails. Launch a repair.php if you have. + //$this->where.= " AND e.date_valid > '2000-01-01'"; // To filter only correct "valid date". If date is invalid, the group by on it will fails. Launch a repair.php if you have. $this->where.= ' e.entity IN ('.getEntity('expensereport').')'; - + //$this->where.= " AND entity = ".$conf->entity; if ($this->socid) { @@ -100,10 +100,11 @@ class ExpenseReportStats extends Stats /** * Renvoie le nombre de facture par mois pour une annee donnee * - * @param string $year Year to scan - * @return array Array of values + * @param string $year Year to scan + * @param int $format 0=Label of absiss is a translated text, 1=Label of absiss is month number, 2=Label of absiss is first letter of month + * @return array Array of values */ - function getNbByMonth($year) + function getNbByMonth($year, $format=0) { $sql = "SELECT MONTH(".$this->db->ifsql('e.date_valid IS NULL','e.date_create','e.date_valid').") as dm, count(*)"; $sql.= " FROM ".$this->from; @@ -112,7 +113,7 @@ class ExpenseReportStats extends Stats $sql.= " GROUP BY dm"; $sql.= $this->db->order('dm','DESC'); - $res=$this->_getNbByMonth($year, $sql); + $res=$this->_getNbByMonth($year, $sql, $format); //var_dump($res);print '
    '; return $res; } @@ -122,9 +123,10 @@ class ExpenseReportStats extends Stats * Renvoie le montant de facture par mois pour une annee donnee * * @param int $year Year to scan + * @param int $format 0=Label of absiss is a translated text, 1=Label of absiss is month number, 2=Label of absiss is first letter of month * @return array Array of values */ - function getAmountByMonth($year) + function getAmountByMonth($year, $format=0) { $sql = "SELECT date_format(".$this->db->ifsql('e.date_valid IS NULL','e.date_create','e.date_valid').",'%m') as dm, sum(".$this->field.")"; $sql.= " FROM ".$this->from; @@ -133,7 +135,7 @@ class ExpenseReportStats extends Stats $sql.= " GROUP BY dm"; $sql.= $this->db->order('dm','DESC'); - $res=$this->_getAmountByMonth($year, $sql); + $res=$this->_getAmountByMonth($year, $sql, $format); //var_dump($res);print '
    '; return $res; } diff --git a/htdocs/expensereport/class/paymentexpensereport.class.php b/htdocs/expensereport/class/paymentexpensereport.class.php index b836f410245..023a9709d08 100644 --- a/htdocs/expensereport/class/paymentexpensereport.class.php +++ b/htdocs/expensereport/class/paymentexpensereport.class.php @@ -165,10 +165,10 @@ class PaymentExpenseReport extends CommonObject $sql.= " t.fk_user_modif,"; $sql.= " pt.code as type_code, pt.libelle as type_libelle,"; $sql.= ' b.fk_account'; - $sql.= " FROM (".MAIN_DB_PREFIX."c_paiement as pt, ".MAIN_DB_PREFIX."payment_expensereport as t)"; + $sql.= " FROM ".MAIN_DB_PREFIX."payment_expensereport as t"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as pt ON t.fk_typepayment = pt.id AND pt.entity IN (".getEntity('c_paiement').")"; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON t.fk_bank = b.rowid'; - $sql.= " WHERE t.rowid = ".$id." AND t.fk_typepayment = pt.id"; - $sql.= " AND pt.entity = " . getEntity('c_paiement'); + $sql.= " WHERE t.rowid = ".$id; dol_syslog(get_class($this)."::fetch", LOG_DEBUG); $resql=$this->db->query($sql); diff --git a/htdocs/expensereport/index.php b/htdocs/expensereport/index.php index 0d9bcd20577..77db05da49a 100644 --- a/htdocs/expensereport/index.php +++ b/htdocs/expensereport/index.php @@ -118,14 +118,23 @@ print "\n"; $listoftype=$tripandexpense_static->listOfTypes(); foreach ($listoftype as $code => $label) { - $dataseries[]=array('label'=>$label,'data'=>(isset($somme[$code])?(int) $somme[$code]:0)); + $dataseries[]=array($label, (isset($somme[$code])?(int) $somme[$code]:0)); } if ($conf->use_javascript_ajax) { - print ''; } @@ -208,7 +217,7 @@ if ($result) print $expensereportstatic->LibStatut($obj->fk_status,3); print ''; print ''; - + $i++; } diff --git a/htdocs/expensereport/list.php b/htdocs/expensereport/list.php index a9f1e0ecde4..caae068461a 100644 --- a/htdocs/expensereport/list.php +++ b/htdocs/expensereport/list.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2016 Laurent Destailleur + * Copyright (C) 2004-2017 Laurent Destailleur * Copyright (C) 2004 Eric Seigne * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2015 Alexandre Spangaro @@ -66,7 +66,7 @@ if (!$sortfield) $sortfield="d.date_debut"; $id = GETPOST('id', 'int'); -$sall = GETPOST('sall', 'alphanohtml'); +$sall = trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alphanohtml'):GETPOST('sall', 'alphanohtml')); $search_ref = GETPOST('search_ref'); $search_user = GETPOST('search_user','int'); $search_amount_ht = GETPOST('search_amount_ht','alpha'); @@ -77,7 +77,7 @@ $month_start = GETPOST("month_start","int"); $year_start = GETPOST("year_start","int"); $month_end = GETPOST("month_end","int"); $year_end = GETPOST("year_end","int"); -$optioncss = GETPOST('optioncss','alpha'); +$optioncss = GETPOST('optioncss','alpha'); if ($search_status == '') $search_status=-1; if ($search_user == '') $search_user=-1; @@ -114,7 +114,7 @@ $arrayfields=array( 'd.total_ht'=>array('label'=>$langs->trans("AmountHT"), 'checked'=>1), 'd.total_vat'=>array('label'=>$langs->trans("AmountVAT"), 'checked'=>1), 'd.total_ttc'=>array('label'=>$langs->trans("AmountTTC"), 'checked'=>1), - 'd.datec'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), + 'd.date_create'=>array('label'=>$langs->trans("DateCreation"), 'checked'=>0, 'position'=>500), 'd.tms'=>array('label'=>$langs->trans("DateModificationShort"), 'checked'=>0, 'position'=>500), 'd.fk_statut'=>array('label'=>$langs->trans("Status"), 'checked'=>1, 'position'=>1000), ); @@ -319,19 +319,7 @@ if (empty($user->rights->expensereport->readall) && empty($user->rights->expense $sql.= " AND d.fk_user_author IN (".join(',',$childids).")\n"; } // Add where from extra fields -foreach ($search_array_options as $key => $val) -{ - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $typ=$extrafields->attribute_type[$tmpkey]; - $mode_search=0; - if (in_array($typ, array('int','double','real'))) $mode_search=1; // Search on a numeric - if (in_array($typ, array('sellist','link')) && $crit != '0' && $crit != '-1') $mode_search=2; // Search on a foreign key int - if ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0') && (! in_array($typ, array('link')) || $crit != '-1')) - { - $sql .= natural_search('ef.'.$tmpkey, $crit, $mode_search); - } -} +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; // Add where from hooks $parameters=array(); $reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters); // Note that $action and $object may have been modified by hook @@ -367,19 +355,14 @@ if ($resql) if ($search_status >= 0) $param.="&search_status=".$search_status; if ($optioncss != '') $param.='&optioncss='.$optioncss; // Add $param from extra fields - foreach ($search_array_options as $key => $val) - { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; // List of mass actions available $arrayofmassactions = array( 'presend'=>$langs->trans("SendByMail"), 'builddoc'=>$langs->trans("PDFMerge"), ); - if ($user->rights->expensereport->supprimer) $arrayofmassactions['delete']=$langs->trans("Delete"); + if ($user->rights->expensereport->supprimer) $arrayofmassactions['predelete']=$langs->trans("Delete"); if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array(); $massactionbutton=$form->selectMassAction('', $arrayofmassactions); @@ -489,7 +472,7 @@ if ($resql) $topicmail="SendExpenseReport"; $modelmail="expensereport"; $objecttmp=new ExpenseReport($db); - $trackid='int'.$object->id; + $trackid='exp'.$object->id; include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; if ($sall) @@ -586,34 +569,14 @@ if ($resql) print ''; } // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $typeofextrafield=$extrafields->attribute_type[$key]; - print ''; - } - } - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; + // Fields from hook $parameters=array('arrayfields'=>$arrayfields); $reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation - if (! empty($arrayfields['d.datec']['checked'])) + if (! empty($arrayfields['d.date_create']['checked'])) { print ''; @@ -650,26 +613,14 @@ if ($resql) if (! empty($arrayfields['d.total_vat']['checked'])) print_liste_field_titre($arrayfields['d.total_vat']['label'],$_SERVER["PHP_SELF"],"d.total_tva","",$param,'align="right"',$sortfield,$sortorder); if (! empty($arrayfields['d.total_ttc']['checked'])) print_liste_field_titre($arrayfields['d.total_ttc']['label'],$_SERVER["PHP_SELF"],"d.total_ttc","",$param,'align="right"',$sortfield,$sortorder); // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $sortonfield = "ef.".$key; - if (! empty($extrafields->attribute_computed[$key])) $sortonfield=''; - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],$sortonfield,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; // Hook fields $parameters=array('arrayfields'=>$arrayfields); $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; - if (! empty($arrayfields['d.datec']['checked'])) print_liste_field_titre($arrayfields['d.datec']['label'],$_SERVER["PHP_SELF"],"d.date_creation","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['d.tms']['checked'])) print_liste_field_titre($arrayfields['d.tms']['label'],$_SERVER["PHP_SELF"],"d.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); - if (! empty($arrayfields['d.fk_statut']['checked'])) print_liste_field_titre($arrayfields['d.fk_statut']['label'],$_SERVER["PHP_SELF"],"d.fk_statut","",$param,'align="right"',$sortfield,$sortorder); + if (! empty($arrayfields['d.date_create']['checked'])) print_liste_field_titre($arrayfields['d.date_create']['label'],$_SERVER["PHP_SELF"],"d.date_create","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['d.tms']['checked'])) print_liste_field_titre($arrayfields['d.tms']['label'],$_SERVER["PHP_SELF"],"d.tms","",$param,'align="center" class="nowrap"',$sortfield,$sortorder); + if (! empty($arrayfields['d.fk_statut']['checked'])) print_liste_field_titre($arrayfields['d.fk_statut']['label'],$_SERVER["PHP_SELF"],"d.fk_statut","",$param,'align="right"',$sortfield,$sortorder); print_liste_field_titre($selectedfields, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch '); print "\n"; @@ -791,29 +742,13 @@ if ($resql) } // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - print 'getAlignFlag($key); - if ($align) print ' align="'.$align.'"'; - print '>'; - $tmpkey='options_'.$key; - print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1); - print ''; - if (! $i) $totalarray['nbfield']++; - } - } - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); $reshook=$hookmanager->executeHooks('printFieldListValue',$parameters); // Note that $action and $object may have been modified by hook print $hookmanager->resPrint; // Date creation - if (! empty($arrayfields['d.datec']['checked'])) + if (! empty($arrayfields['d.date_create']['checked'])) { print ''; } $var=true; @@ -138,7 +148,7 @@ if ($resql) { if (! $conf->use_javascript_ajax) { - + print ''; print ''; print ''; print ''; @@ -311,7 +321,7 @@ if (! empty($conf->ficheinter->enabled)) $var = true; while ($i < $num) { - + $obj = $db->fetch_object($resql); print ''; print ''; } // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $typeofextrafield=$extrafields->attribute_type[$key]; - print ''; - } - } - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; + // Fields from hook $parameters=array('arrayfields'=>$arrayfields); $reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook @@ -424,19 +393,7 @@ if ($resql) if (! empty($arrayfields['fd.date']['checked'])) print_liste_field_titre("Date",$_SERVER["PHP_SELF"],"fd.date","",$param,'align="center"',$sortfield,$sortorder); if (! empty($arrayfields['fd.duree']['checked'])) print_liste_field_titre("Duration",$_SERVER["PHP_SELF"],"fd.duree","",$param,'align="right"',$sortfield,$sortorder); // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $sortonfield = "ef.".$key; - if (! empty($extrafields->attribute_computed[$key])) $sortonfield=''; - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],$sortonfield,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; // Hook fields $parameters=array('arrayfields'=>$arrayfields); $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook @@ -532,23 +489,7 @@ if ($resql) } // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - print 'getAlignFlag($key); - if ($align) print ' align="'.$align.'"'; - print '>'; - $tmpkey='options_'.$key; - print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1); - print ''; - if (! $i) $totalarray['nbfield']++; - } - } - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); $reshook=$hookmanager->executeHooks('printFieldListValue',$parameters); // Note that $action and $object may have been modified by hook diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index 84f0b2c8056..c270e2f44fa 100644 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -31,7 +31,7 @@ */ if (! defined('DOL_APPLICATION_TITLE')) define('DOL_APPLICATION_TITLE','Dolibarr'); -if (! defined('DOL_VERSION')) define('DOL_VERSION','7.0.0-alpha'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c +if (! defined('DOL_VERSION')) define('DOL_VERSION','7.0.0-beta'); // a.b.c-alpha, a.b.c-beta, a.b.c-rcX or a.b.c if (! defined('EURO')) define('EURO',chr(128)); diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php index 08a57fae706..6f473f8deb3 100644 --- a/htdocs/fourn/card.php +++ b/htdocs/fourn/card.php @@ -132,7 +132,7 @@ if ($object->id > 0) dol_fiche_head($head, 'supplier', $langs->trans("ThirdParty"), -1, 'company'); - $linkback = ''.$langs->trans("BackToList").''; + $linkback = ''.$langs->trans("BackToList").''; dol_banner_tab($object, 'socid', $linkback, ($user->societe_id?0:1), 'rowid', 'nom'); diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 437732b71d0..868014ea618 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -223,8 +223,8 @@ class CommandeFournisseur extends CommonOrder $sql.= ', c.fk_incoterms, c.location_incoterms'; $sql.= ', i.libelle as libelle_incoterms'; $sql.= " FROM ".MAIN_DB_PREFIX."commande_fournisseur as c"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_payment_term as cr ON (c.fk_cond_reglement = cr.rowid AND cr.entity = " . getEntity('c_payment_term') . ")"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as p ON (c.fk_mode_reglement = p.id AND p.entity = " . getEntity('c_paiement') . ")"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_payment_term as cr ON c.fk_cond_reglement = cr.rowid AND cr.entity IN (".getEntity('c_payment_term').")"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as p ON c.fk_mode_reglement = p.id AND p.entity IN (".getEntity('c_paiement').")"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_input_method as cm ON cm.rowid = c.fk_input_method"; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON c.fk_incoterms = i.rowid'; $sql.= " WHERE c.entity = ".$conf->entity; @@ -1953,7 +1953,7 @@ class CommandeFournisseur extends CommonOrder // List of already dispatched lines $sql = "SELECT p.ref, p.label,"; - $sql.= " e.rowid as warehouse_id, e.label as entrepot,"; + $sql.= " e.rowid as warehouse_id, e.ref as entrepot,"; $sql.= " cfd.rowid as dispatchlineid, cfd.fk_product, cfd.qty, cfd.eatby, cfd.sellby, cfd.batch, cfd.comment, cfd.status"; $sql.= " FROM ".MAIN_DB_PREFIX."product as p,"; $sql.= " ".MAIN_DB_PREFIX."commande_fournisseur_dispatch as cfd"; @@ -2350,7 +2350,7 @@ class CommandeFournisseur extends CommonOrder * @param string $ref_supplier Supplier ref * @return int < 0 if error, > 0 if ok */ - public function updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0, $txlocaltax2=0, $price_base_type='HT', $info_bits=0, $type=0, $notrigger=false, $date_start='', $date_end='', $array_options=0, $fk_unit=null, $pu_ht_devise=0, $ref_supplier='') + public function updateline($rowid, $desc, $pu, $qty, $remise_percent, $txtva, $txlocaltax1=0, $txlocaltax2=0, $price_base_type='HT', $info_bits=0, $type=0, $notrigger=0, $date_start='', $date_end='', $array_options=0, $fk_unit=null, $pu_ht_devise=0, $ref_supplier='') { global $mysoc, $conf; dol_syslog(get_class($this)."::updateline $rowid, $desc, $pu, $qty, $remise_percent, $txtva, $price_base_type, $info_bits, $type, $fk_unit"); diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 249fda336f1..2be366cfc46 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -552,8 +552,8 @@ class FactureFournisseur extends CommonInvoice $sql.= ' t.fk_multicurrency, t.multicurrency_code, t.multicurrency_tx, t.multicurrency_total_ht, t.multicurrency_total_tva, t.multicurrency_total_ttc'; $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_fourn as t'; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."societe as s ON (t.fk_soc = s.rowid)"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_payment_term as cr ON (t.fk_cond_reglement = cr.rowid AND cr.entity = " . getEntity('c_payment_term') . ")"; - $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as p ON (t.fk_mode_reglement = p.id AND p.entity = " . getEntity('c_paiement') . ")"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_payment_term as cr ON t.fk_cond_reglement = cr.rowid AND cr.entity IN (".getEntity('c_payment_term').")"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as p ON t.fk_mode_reglement = p.id AND p.entity IN (".getEntity('c_paiement').")"; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_incoterms as i ON t.fk_incoterms = i.rowid'; if ($id) $sql.= " WHERE t.rowid=".$id; if ($ref) $sql.= " WHERE t.ref='".$this->db->escape($ref)."'"; @@ -2518,6 +2518,7 @@ class SupplierInvoiceLine extends CommonObjectLine $this->product_type = $obj->product_type; $this->product_label = $obj->label; $this->info_bits = $obj->info_bits; + $this->tva_npr = ($obj->info_bits & 1 == 1) ? 1 : 0; $this->fk_parent_line = $obj->fk_parent_line; $this->special_code = $obj->special_code; $this->rang = $obj->rang; @@ -2756,7 +2757,7 @@ class SupplierInvoiceLine extends CommonObjectLine $sql.= " VALUES (".$this->fk_facture_fourn.","; $sql.= " ".($this->fk_parent_line>0?"'".$this->db->escape($this->fk_parent_line)."'":"null").","; $sql.= " ".(! empty($this->label)?"'".$this->db->escape($this->label)."'":"null").","; - $sql.= " '".$this->db->escape($this->desc)."',"; + $sql.= " '".$this->db->escape($this->desc ? $this->desc : $this->description)."',"; $sql.= " '".$this->db->escape($this->ref_supplier)."',"; $sql.= " ".price2num($this->qty).","; diff --git a/htdocs/fourn/class/paiementfourn.class.php b/htdocs/fourn/class/paiementfourn.class.php index 43f39ce2287..8f99c24f7a7 100644 --- a/htdocs/fourn/class/paiementfourn.class.php +++ b/htdocs/fourn/class/paiementfourn.class.php @@ -79,16 +79,17 @@ class PaiementFourn extends Paiement $sql = 'SELECT p.rowid, p.ref, p.entity, p.datep as dp, p.amount, p.statut, p.fk_bank,'; $sql.= ' c.code as paiement_code, c.libelle as paiement_type,'; $sql.= ' p.num_paiement, p.note, b.fk_account'; - $sql.= ' FROM '.MAIN_DB_PREFIX.'c_paiement as c, '.MAIN_DB_PREFIX.'paiementfourn as p'; + $sql.= ' FROM '.MAIN_DB_PREFIX.'paiementfourn as p'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id AND c.entity IN ('.getEntity('c_paiement').')'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid '; - $sql.= ' WHERE p.fk_paiement = c.id'; - $sql.= ' AND c.entity IN (' . getEntity('c_paiement').')'; + $sql.= ' WHERE p.entity IN ('.getEntity('facture_fourn').')'; if ($id > 0) $sql.= ' AND p.rowid = '.$id; else if ($ref) $sql.= ' AND p.rowid = '.$ref; else if ($fk_bank) $sql.= ' AND p.fk_bank = '.$fk_bank; + //print $sql; $resql = $this->db->query($sql); if ($resql) @@ -533,9 +534,10 @@ class PaiementFourn extends Paiement * @param int $withpicto 0=No picto, 1=Include picto into link, 2=Only picto * @param string $option Sur quoi pointe le lien * @param string $mode 'withlistofinvoices'=Include list of invoices into tooltip + * @param int $notooltip 1=Disable tooltip * @return string Chaine avec URL */ - function getNomUrl($withpicto=0,$option='',$mode='withlistofinvoices') + function getNomUrl($withpicto=0, $option='', $mode='withlistofinvoices', $notooltip=0) { global $langs; @@ -548,13 +550,14 @@ class PaiementFourn extends Paiement } $label = $langs->trans("ShowPayment").': '.$text; - $link = ''; - $linkend=''; + $linkstart = ''; + $linkend = ''; + $result .= $linkstart; + if ($withpicto) $result.=img_object(($notooltip?'':$label), ($this->picto?$this->picto:'generic'), ($notooltip?(($withpicto != 2) ? 'class="paddingright"' : ''):'class="'.(($withpicto != 2) ? 'paddingright ' : '').'classfortooltip"'), 0, 0, $notooltip?0:1); + if ($withpicto != 2) $result.= $this->ref; + $result .= $linkend; - if ($withpicto) $result.=($link.img_object($langs->trans("ShowPayment"), 'payment', 'class="classfortooltip"').$linkend); - if ($withpicto && $withpicto != 2) $result.=' '; - if ($withpicto != 2) $result.=$link.$text.$linkend; return $result; } diff --git a/htdocs/fourn/commande/card.php b/htdocs/fourn/commande/card.php index c96c42e2297..8395a7d432f 100644 --- a/htdocs/fourn/commande/card.php +++ b/htdocs/fourn/commande/card.php @@ -1520,6 +1520,8 @@ if ($action=='create') $langs->load('projects'); print ''; } @@ -2186,10 +2188,10 @@ elseif (! empty($object->id)) } } // Create event - if ($conf->agenda->enabled && ! empty($conf->global->MAIN_ADD_EVENT_ON_ELEMENT_CARD)) // Add hidden condition because this is not a "workflow" action so should appears somewhere else on page. + /*if ($conf->agenda->enabled && ! empty($conf->global->MAIN_ADD_EVENT_ON_ELEMENT_CARD)) // Add hidden condition because this is not a "workflow" action so should appears somewhere else on page. { print ''; - } + }*/ // Modify if ($object->statut == 1) diff --git a/htdocs/fourn/commande/dispatch.php b/htdocs/fourn/commande/dispatch.php index a7c528e11c2..d500039d5f2 100644 --- a/htdocs/fourn/commande/dispatch.php +++ b/htdocs/fourn/commande/dispatch.php @@ -735,7 +735,7 @@ if ($id > 0 || ! empty($ref)) { // List of lines already dispatched $sql = "SELECT p.ref, p.label,"; - $sql .= " e.rowid as warehouse_id, e.label as entrepot,"; + $sql .= " e.rowid as warehouse_id, e.ref as entrepot,"; $sql .= " cfd.rowid as dispatchlineid, cfd.fk_product, cfd.qty, cfd.eatby, cfd.sellby, cfd.batch, cfd.comment, cfd.status"; $sql .= " FROM " . MAIN_DB_PREFIX . "product as p,"; $sql .= " " . MAIN_DB_PREFIX . "commande_fournisseur_dispatch as cfd"; diff --git a/htdocs/fourn/commande/index.php b/htdocs/fourn/commande/index.php index ccb54930573..ca395d0cf47 100644 --- a/htdocs/fourn/commande/index.php +++ b/htdocs/fourn/commande/index.php @@ -116,10 +116,10 @@ if ($resql) print "\n"; foreach (array(0,1,2,3,4,5,6) as $statut) { - $dataseries[]=array('label'=>$commandestatic->LibStatut($statut,1),'data'=>(isset($vals[$statut])?(int) $vals[$statut]:0)); + $dataseries[]=array($commandestatic->LibStatut($statut,1), (isset($vals[$statut])?(int) $vals[$statut]:0)); if (! $conf->use_javascript_ajax) { - + print ''; print ''; print ''; @@ -129,8 +129,17 @@ if ($resql) if ($conf->use_javascript_ajax) { print ''; } //if ($totalinprocess != $total) @@ -177,7 +186,7 @@ if ($resql) while ($i < $num) { $row = $db->fetch_row($resql); - + print ''; print ''; @@ -225,7 +234,7 @@ if (! empty($conf->fournisseur->enabled)) $var = True; while ($i < $num) { - + $obj = $db->fetch_object($resql); print ''; print ''; print ''; diff --git a/htdocs/fourn/commande/list.php b/htdocs/fourn/commande/list.php index db947f4011f..d044e5566e8 100644 --- a/htdocs/fourn/commande/list.php +++ b/htdocs/fourn/commande/list.php @@ -575,19 +575,7 @@ if ($search_total_vat != '') $sql.= natural_search('cf.tva', $search_total_vat, if ($search_total_ttc != '') $sql.= natural_search('cf.total_ttc', $search_total_ttc, 1); if ($search_project_ref != '') $sql.= natural_search("p.ref",$search_project_ref); // Add where from extra fields -foreach ($search_array_options as $key => $val) -{ - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $typ=$extrafields->attribute_type[$tmpkey]; - $mode_search=0; - if (in_array($typ, array('int','double','real'))) $mode_search=1; // Search on a numeric - if (in_array($typ, array('sellist','link')) && $crit != '0' && $crit != '-1') $mode_search=2; // Search on a foreign key int - if ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0') && (! in_array($typ, array('link')) || $crit != '-1')) - { - $sql .= natural_search('ef.'.$tmpkey, $crit, $mode_search); - } -} +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; // Add where from hooks $parameters=array(); $reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters); // Note that $action and $object may have been modified by hook @@ -647,12 +635,7 @@ if ($resql) if ($show_files) $param.='&show_files=' .$show_files; if ($optioncss != '') $param.='&optioncss='.$optioncss; // Add $param from extra fields - foreach ($search_array_options as $key => $val) - { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; // List of mass actions available $arrayofmassactions = array( @@ -660,7 +643,7 @@ if ($resql) 'builddoc'=>$langs->trans("PDFMerge"), ); //if($user->rights->fournisseur->facture->creer) $arrayofmassactions['createbills']=$langs->trans("CreateInvoiceForThisCustomer"); - if ($user->rights->fournisseur->commande->supprimer) $arrayofmassactions['delete']=$langs->trans("Delete"); + if ($user->rights->fournisseur->commande->supprimer) $arrayofmassactions['predelete']=$langs->trans("Delete"); if (in_array($massaction, array('presend','predelete','createbills'))) $arrayofmassactions=array(); $massactionbutton=$form->selectMassAction('', $arrayofmassactions); @@ -871,28 +854,8 @@ if ($resql) print ''; } // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $typeofextrafield=$extrafields->attribute_type[$key]; - print ''; - } - } - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; + // Fields from hook $parameters=array('arrayfields'=>$arrayfields); $reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook @@ -949,19 +912,7 @@ if ($resql) if (! empty($arrayfields['cf.total_vat']['checked'])) print_liste_field_titre($arrayfields['cf.total_vat']['label'],$_SERVER["PHP_SELF"],"cf.tva","",$param,'align="right"',$sortfield,$sortorder); if (! empty($arrayfields['cf.total_ttc']['checked'])) print_liste_field_titre($arrayfields['cf.total_ttc']['label'],$_SERVER["PHP_SELF"],"cf.total_ttc","",$param,'align="right"',$sortfield,$sortorder); // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $sortonfield = "ef.".$key; - if (! empty($extrafields->attribute_computed[$key])) $sortonfield=''; - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],$sortonfield,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; // Hook fields $parameters=array('arrayfields'=>$arrayfields); $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook @@ -1151,23 +1102,7 @@ if ($resql) } // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - print 'getAlignFlag($key); - if ($align) print ' align="'.$align.'"'; - print '>'; - $tmpkey='options_'.$key; - print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1); - print ''; - if (! $i) $totalarray['nbfield']++; - } - } - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); $reshook=$hookmanager->executeHooks('printFieldListValue',$parameters); // Note that $action and $object may have been modified by hook diff --git a/htdocs/fourn/commande/orderstoinvoice.php b/htdocs/fourn/commande/orderstoinvoice.php index 012574915ab..890cac8e1b2 100644 --- a/htdocs/fourn/commande/orderstoinvoice.php +++ b/htdocs/fourn/commande/orderstoinvoice.php @@ -53,7 +53,7 @@ $action = GETPOST('action', 'alpha'); $confirm = GETPOST('confirm', 'alpha'); $sref = GETPOST('sref'); $sref_client = GETPOST('sref_client'); -$sall = GETPOST('sall', 'alphanohtml'); +$sall = trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alphanohtml'):GETPOST('sall', 'alphanohtml')); $socid = GETPOST('socid', 'int'); $selected = GETPOST('orders_to_invoice'); $sortfield = GETPOST("sortfield", 'alpha'); diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 59f15ea155b..febfc28a88a 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -52,12 +52,7 @@ if (!empty($conf->variants->enabled)) { if (! empty($conf->accounting->enabled)) require_once DOL_DOCUMENT_ROOT . '/accountancy/class/accountingjournal.class.php'; -$langs->load('bills'); -$langs->load('compta'); -$langs->load('suppliers'); -$langs->load('companies'); -$langs->load('products'); -$langs->load('banks'); +$langs->loadLangs(array('bills','compta','suppliers','companies','products','banks')); if (!empty($conf->incoterm->enabled)) $langs->load('incoterm'); $id = (GETPOST('facid','int') ? GETPOST('facid','int') : GETPOST('id','int')); @@ -469,7 +464,7 @@ if (empty($reshook)) // Credit note invoice if ($_POST['type'] == FactureFournisseur::TYPE_CREDIT_NOTE) { - $sourceinvoice = GETPOST('fac_avoir'); + $sourceinvoice = GETPOST('fac_avoir','int'); if (! ($sourceinvoice > 0) && empty($conf->global->INVOICE_CREDIT_NOTE_STANDALONE)) { $error ++; @@ -1601,7 +1596,7 @@ if ($action == 'create') } */ - /* Not yet supporter for supplier + /* Not yet supported for supplier if ($societe->id > 0) { // Replacement @@ -1926,7 +1921,24 @@ else // fetch optionals attributes and labels $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); - $alreadypaid=$object->getSommePaiement(); + $totalpaye = $object->getSommePaiement(); + $totalcreditnotes = $object->getSumCreditNotesUsed(); + $totaldeposits = $object->getSumDepositsUsed(); + // print "totalpaye=".$totalpaye." totalcreditnotes=".$totalcreditnotes." totaldeposts=".$totaldeposits." + // selleruserrevenuestamp=".$selleruserevenustamp; + + // We can also use bcadd to avoid pb with floating points + // For example print 239.2 - 229.3 - 9.9; does not return 0. + // $resteapayer=bcadd($object->total_ttc,$totalpaye,$conf->global->MAIN_MAX_DECIMALS_TOT); + // $resteapayer=bcadd($resteapayer,$totalavoir,$conf->global->MAIN_MAX_DECIMALS_TOT); + $resteapayer = price2num($object->total_ttc - $totalpaye - $totalcreditnotes - $totaldeposits, 'MT'); + + if ($object->paye) + { + $resteapayer = 0; + } + $resteapayeraffiche = $resteapayer; + /* * View card @@ -2124,7 +2136,7 @@ else } $morehtmlref.=''; - $object->totalpaye = $alreadypaid; // To give a chance to dol_banner_tab to use already paid amount to show correct status + $object->totalpaye = $totalpaye; // To give a chance to dol_banner_tab to use already paid amount to show correct status dol_banner_tab($object, 'ref', $linkback, 1, 'ref', 'ref', $morehtmlref); @@ -2412,7 +2424,7 @@ else $sql.= ' FROM '.MAIN_DB_PREFIX.'paiementfourn as p'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id AND c.entity IN (' . getEntity('c_paiement').')'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement as c ON p.fk_paiement = c.id AND c.entity IN ('.getEntity('c_paiement').')'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn as pf ON pf.fk_paiementfourn = p.rowid'; $sql.= ' WHERE pf.fk_facturefourn = '.$object->id; $sql.= ' ORDER BY p.datep, p.tms'; @@ -2439,12 +2451,14 @@ else { $objp = $db->fetch_object($result); - print ''; + print ''; print ''; @@ -2612,6 +2626,8 @@ else } else // Credit note { + $cssforamountpaymentcomplete=''; + // Total already paid back print ''; - print ''; + print ''; print ''; // Sold credit note @@ -2816,10 +2832,10 @@ else } // Create event - if ($conf->agenda->enabled && ! empty($conf->global->MAIN_ADD_EVENT_ON_ELEMENT_CARD)) // Add hidden condition because this is not a "workflow" action so should appears somewhere else on page. + /*if ($conf->agenda->enabled && ! empty($conf->global->MAIN_ADD_EVENT_ON_ELEMENT_CARD)) // Add hidden condition because this is not a "workflow" action so should appears somewhere else on page. { print ''; - } + }*/ // Clone if ($action != 'edit' && $user->rights->fournisseur->facture->creer) @@ -2839,9 +2855,26 @@ else // Delete if ($action != 'confirm_edit' && $user->rights->fournisseur->facture->supprimer) { - if ($object->getSommePaiement()) { - print ''; - } else { + $isErasable=$object->is_erasable(); + //var_dump($isErasable); + if ($isErasable == -4) { + print ''; + } + elseif ($isErasable == -3) { // Should never happen with supplier invoice + print ''; + } + elseif ($isErasable == -2) { // Should never happen with supplier invoice + print ''; + } + elseif ($isErasable == -1) { + print ''; + } + elseif ($isErasable <= 0) // Any other cases + { + print ''; + } + else + { print ''; } } diff --git a/htdocs/fourn/facture/info.php b/htdocs/fourn/facture/info.php index ffda7e2f4cd..d2241b9841a 100644 --- a/htdocs/fourn/facture/info.php +++ b/htdocs/fourn/facture/info.php @@ -30,6 +30,7 @@ require_once DOL_DOCUMENT_ROOT.'/fourn/class/fournisseur.facture.class.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/fourn.lib.php'; require_once DOL_DOCUMENT_ROOT.'/core/lib/functions2.lib.php'; +$langs->load('companies'); $langs->load('bills'); $id = GETPOST("facid",'int')?GETPOST("facid",'int'):GETPOST("id",'int'); diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index bdf9349763b..2227c750927 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -68,7 +68,7 @@ if ($user->societe_id > 0) $mode=GETPOST("mode"); -$search_all = GETPOST('sall', 'alphanohtml'); +$search_all = trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alphanohtml'):GETPOST('sall', 'alphanohtml')); $search_label = GETPOST("search_label","alpha"); $search_company = GETPOST("search_company","alpha"); $search_amount_no_tax = GETPOST("search_amount_no_tax","alpha"); @@ -367,19 +367,7 @@ if ($search_user > 0) $sql.= " AND ec.fk_c_type_contact = tc.rowid AND tc.element='invoice_supplier' AND tc.source='internal' AND ec.element_id = f.rowid AND ec.fk_socpeople = ".$search_user; } // Add where from extra fields -foreach ($search_array_options as $key => $val) -{ - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $typ=$extrafields->attribute_type[$tmpkey]; - $mode_search=0; - if (in_array($typ, array('int','double','real'))) $mode_search=1; // Search on a numeric - if (in_array($typ, array('sellist','link')) && $crit != '0' && $crit != '-1') $mode_search=2; // Search on a foreign key int - if ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0') && (! in_array($typ, array('link')) || $crit != '-1')) - { - $sql .= natural_search('ef.'.$tmpkey, $crit, $mode_search); - } -} +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; // Add where from hooks $parameters=array(); $reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters); // Note that $action and $object may have been modified by hook @@ -457,12 +445,7 @@ if ($resql) if ($option) $param.="&option=".$option; if ($optioncss != '') $param.='&optioncss='.$optioncss; // Add $param from extra fields - foreach ($search_array_options as $key => $val) - { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; // List of mass actions available $arrayofmassactions = array( @@ -471,7 +454,7 @@ if ($resql) //'builddoc'=>$langs->trans("PDFMerge"), ); //if($user->rights->fournisseur->facture->creer) $arrayofmassactions['createbills']=$langs->trans("CreateInvoiceForThisCustomer"); - if ($user->rights->fournisseur->facture->supprimer) $arrayofmassactions['delete']=$langs->trans("Delete"); + if ($user->rights->fournisseur->facture->supprimer) $arrayofmassactions['predelete']=$langs->trans("Delete"); if (in_array($massaction, array('presend','predelete','createbills'))) $arrayofmassactions=array(); $massactionbutton=$form->selectMassAction('', $arrayofmassactions); @@ -718,28 +701,8 @@ if ($resql) print ''; } // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $typeofextrafield=$extrafields->attribute_type[$key]; - print ''; - } - } - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_input.tpl.php'; + // Fields from hook $parameters=array('arrayfields'=>$arrayfields); $reshook=$hookmanager->executeHooks('printFieldListOption',$parameters); // Note that $action and $object may have been modified by hook @@ -794,19 +757,7 @@ if ($resql) if (! empty($arrayfields['dynamount_payed']['checked'])) print_liste_field_titre($arrayfields['dynamount_payed']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="right"',$sortfield,$sortorder); if (! empty($arrayfields['rtp']['checked'])) print_liste_field_titre($arrayfields['rtp']['label'],$_SERVER['PHP_SELF'],'','',$param,'align="right"',$sortfield,$sortorder); // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - $align=$extrafields->getAlignFlag($key); - $sortonfield = "ef.".$key; - if (! empty($extrafields->attribute_computed[$key])) $sortonfield=''; - print_liste_field_titre($extralabels[$key],$_SERVER["PHP_SELF"],$sortonfield,"",$param,($align?'align="'.$align.'"':''),$sortfield,$sortorder); - } - } - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_title.tpl.php'; // Hook fields $parameters=array('arrayfields'=>$arrayfields); $reshook=$hookmanager->executeHooks('printFieldListTitle',$parameters); // Note that $action and $object may have been modified by hook @@ -1045,23 +996,7 @@ if ($resql) // Extra fields - if (is_array($extrafields->attribute_label) && count($extrafields->attribute_label)) - { - foreach($extrafields->attribute_label as $key => $val) - { - if (! empty($arrayfields["ef.".$key]['checked'])) - { - print 'getAlignFlag($key); - if ($align) print ' align="'.$align.'"'; - print '>'; - $tmpkey='options_'.$key; - print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1); - print ''; - if (! $i) $totalarray['nbfield']++; - } - } - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_print_fields.tpl.php'; // Fields from hook $parameters=array('arrayfields'=>$arrayfields, 'obj'=>$obj); $reshook=$hookmanager->executeHooks('printFieldListValue',$parameters); // Note that $action and $object may have been modified by hook diff --git a/htdocs/fourn/facture/paiement.php b/htdocs/fourn/facture/paiement.php index 000bf0b9743..64223d4b4e9 100644 --- a/htdocs/fourn/facture/paiement.php +++ b/htdocs/fourn/facture/paiement.php @@ -745,7 +745,7 @@ if (empty($action)) $sql.= ' FROM '.MAIN_DB_PREFIX.'paiementfourn AS p'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'paiementfourn_facturefourn AS pf ON p.rowid=pf.fk_paiementfourn'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'facture_fourn AS f ON f.rowid=pf.fk_facturefourn'; - $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement AS c ON p.fk_paiement = c.id AND c.entity IN (' . getEntity('c_paiement').')'; + $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'c_paiement AS c ON p.fk_paiement = c.id AND c.entity IN ('.getEntity('c_paiement').')'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'societe AS s ON s.rowid = f.fk_soc'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank as b ON p.fk_bank = b.rowid'; $sql.= ' LEFT JOIN '.MAIN_DB_PREFIX.'bank_account as ba ON b.fk_account = ba.rowid'; @@ -773,8 +773,11 @@ if (empty($action)) if ($search_payment_num != '') $sql .= natural_search('p.num_paiement', $search_payment_num); if ($search_amount) $sql .= natural_search('p.amount', $search_amount, 1); if ($search_company) $sql .= natural_search('s.nom', $search_company); + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; $sql.= " GROUP BY p.rowid, p.datep, p.amount, p.num_paiement, s.rowid, s.nom, c.code, c.libelle, ba.rowid, ba.label"; if (!$user->rights->societe->client->voir) $sql .= ", sc.fk_soc, sc.fk_user"; + // Add where from extra fields + $sql.= $db->order($sortfield,$sortorder); $nbtotalofrecords = ''; @@ -805,12 +808,7 @@ if (empty($action)) if ($search_payment_num) $param.=($search_payment_num?"&search_payment_num=".urlencode($search_payment_num):""); if ($optioncss != '') $param.='&optioncss='.$optioncss; // Add $param from extra fields - foreach ($search_array_options as $key => $val) - { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; $massactionbutton=$form->selectMassAction('', $massaction == 'presend' ? array() : array('presend'=>$langs->trans("SendByMail"), 'builddoc'=>$langs->trans("PDFMerge"))); diff --git a/htdocs/fourn/paiement/card.php b/htdocs/fourn/paiement/card.php index 14eca2c58d0..6023e7c050a 100644 --- a/htdocs/fourn/paiement/card.php +++ b/htdocs/fourn/paiement/card.php @@ -296,11 +296,14 @@ if ($result > 0) { $objp = $db->fetch_object($resql); + $facturestatic->id=$objp->facid; + $facturestatic->ref=($objp->ref?$objp->ref:$objp->rowid); + print ''; // Ref - print '\n"; + print '\n"; // Ref supplier print '\n"; // Third party diff --git a/htdocs/fourn/product/list.php b/htdocs/fourn/product/list.php index c5b39a87681..c71825eda0f 100644 --- a/htdocs/fourn/product/list.php +++ b/htdocs/fourn/product/list.php @@ -54,6 +54,8 @@ if (! $sortfield) $sortfield="p.ref"; // Set here default search field if (! $sortorder) $sortorder="ASC"; $fourn_id = GETPOST('fourn_id', 'intcomma'); +if ($user->societe_id) $fourn_id=$user->societe_id; + $catid = GETPOST('catid', 'intcomma'); // Initialize technical object to manage hooks. Note that conf->hooks_modules contains array @@ -118,7 +120,7 @@ $arrayofmassactions = array( 'presend'=>$langs->trans("SendByMail"), 'builddoc'=>$langs->trans("PDFMerge"), ); -if ($user->rights->mymodule->supprimer) $arrayofmassactions['delete']=$langs->trans("Delete"); +if ($user->rights->mymodule->supprimer) $arrayofmassactions['predelete']=$langs->trans("Delete"); if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array(); $massactionbutton=$form->selectMassAction('', $arrayofmassactions); @@ -209,6 +211,12 @@ if ($resql) print ''; print ''; + $topicmail="Information"; + $modelmail="product"; + $objecttmp=new Product($db); + $trackid='prod'.$object->id; + include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; + print '
    '; if (is_array($lines[$i]->detail_batch) && count($lines[$i]->detail_batch) > 0) { + print ''; $line = new ExpeditionLigne($db); foreach ($lines[$i]->detail_batch as $detail_batch) { @@ -2274,30 +2293,52 @@ else if ($id || $ref) } else if (! empty($conf->stock->enabled)) { - if ($lines[$i]->entrepot_id > 0) + if ($lines[$i]->fk_product > 0) { - print ''; - // Qty to ship or shipped - print ''; - // Warehouse source - print ''; - // Batch number managment - print ''; - print ''; - } - else if (count($lines[$i]->details_entrepot) > 1) - { - foreach ($lines[$i]->details_entrepot as $detail_entrepot) + if ($lines[$i]->entrepot_id > 0) { + print ''; print ''; // Qty to ship or shipped - print ''; + print ''; // Warehouse source - print ''; + print ''; // Batch number managment print ''; print ''; } + else if (count($lines[$i]->details_entrepot) > 1) + { + print ''; + foreach ($lines[$i]->details_entrepot as $detail_entrepot) + { + print ''; + // Qty to ship or shipped + print ''; + // Warehouse source + print ''; + // Batch number managment + print ''; + print ''; + } + } + else + { + print ''; + print ''; + } + } + else + { + print ''; + print ''; + // Qty to ship or shipped + print ''; + // Warehouse source + print ''; + // Batch number managment + print ''; + print ''; } } print '
    ' . '' . '' . $formproduct->selectWarehouses($lines[$i]->entrepot_id, 'entl'.$line_id, '', 1, 0, $lines[$i]->fk_product, '', 1). ' - ' . $langs->trans("NA") . '
    ' . '' . '' . '' . '' . $formproduct->selectWarehouses($detail_entrepot->entrepot_id, 'entl'.$detail_entrepot->line_id, '', 1, 0, $lines[$i]->fk_product, '', 1) . '' . $formproduct->selectWarehouses($lines[$i]->entrepot_id, 'entl'.$line_id, '', 1, 0, $lines[$i]->fk_product, '', 1). ' - ' . $langs->trans("NA") . '
    ' . '' . '' . $formproduct->selectWarehouses($detail_entrepot->entrepot_id, 'entl'.$detail_entrepot->line_id, '', 1, 0, $lines[$i]->fk_product, '', 1) . ' - ' . $langs->trans("NA") . '
    '.$langs->trans("NotEnoughStock").'
    ' . '' . '' . '' . '
    '; if ($lines[$i]->product_tobatch) { $detail = ''; foreach ($lines[$i]->detail_batch as $dbatch) { - $detail.= $langs->trans("DetailBatchFormat",$dbatch->batch,dol_print_date($dbatch->eatby,"day"),dol_print_date($dbatch->sellby,"day"),$dbatch->dluo_qty).'
    '; + $detail.= $langs->trans("Batch").': '.$dbatch->batch; + $detail.= ' - '.$langs->trans("SellByDate").': '.dol_print_date($dbatch->sellby,"day"); + $detail.= ' - '.$langs->trans("EatByDate").': '.dol_print_date($dbatch->eatby,"day"); + $detail.= ' - '.$langs->trans("Qty").': '.$dbatch->dluo_qty; + $detail.= '
    '; } print $form->textwithtooltip(img_picto('', 'object_barcode').' '.$langs->trans("DetailBatchNumber"),$detail); } @@ -2362,13 +2408,13 @@ else if ($id || $ref) // Weight print '
    '; - if ($lines[$i]->fk_product_type == 0) print $lines[$i]->weight*$lines[$i]->qty_shipped.' '.measuring_units_string($lines[$i]->weight_units,"weight"); + if ($lines[$i]->fk_product_type == Product::TYPE_PRODUCT) print $lines[$i]->weight*$lines[$i]->qty_shipped.' '.measuring_units_string($lines[$i]->weight_units,"weight"); else print ' '; print ''; - if ($lines[$i]->fk_product_type == 0) print $lines[$i]->volume*$lines[$i]->qty_shipped.' '.measuring_units_string($lines[$i]->volume_units,"volume"); + if ($lines[$i]->fk_product_type == Product::TYPE_PRODUCT) print $lines[$i]->volume*$lines[$i]->qty_shipped.' '.measuring_units_string($lines[$i]->volume_units,"volume"); else print ' '; print ' '; - if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select'))) - { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $searchclass=''; - if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; - if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; - print ''; - } - print 'getAlignFlag($key); - if ($align) print ' align="'.$align.'"'; - print '>'; - $tmpkey='options_'.$key; - print $extrafields->showOutputField($key, $obj->$tmpkey, '', 1); - print ''; print $product->stock_reel; diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index dc2c0a22f66..29bc181a358 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -222,7 +222,7 @@ if (empty($reshook)) if ($ret < 0) $error++; } - if ($object->periode_existe($fuser,$object->date_debut,$object->date_fin)) + if (empty($conf->global->EXPENSEREPORT_ALLOW_OVERLAPPING_PERIODS) && $object->periode_existe($fuser,$object->date_debut,$object->date_fin)) { $error++; setEventMessages($langs->trans("ErrorDoubleDeclaration"), null, 'errors'); @@ -1862,16 +1862,13 @@ else $sql = "SELECT p.rowid, p.num_payment, p.datep as dp, p.amount, p.fk_bank,"; $sql.= "c.code as p_code, c.libelle as payment_type,"; $sql.= "ba.rowid as baid, ba.ref as baref, ba.label, ba.number as banumber, ba.account_number, ba.fk_accountancy_journal"; - $sql.= " FROM ".MAIN_DB_PREFIX."expensereport as e"; - $sql.= ", ".MAIN_DB_PREFIX."c_paiement as c "; - $sql.= ", ".MAIN_DB_PREFIX."payment_expensereport as p"; - $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'bank as b ON p.fk_bank = b.rowid'; - $sql .= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'bank_account as ba ON b.fk_account = ba.rowid'; + $sql.= " FROM ".MAIN_DB_PREFIX."expensereport as e, ".MAIN_DB_PREFIX."payment_expensereport as p"; + $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as c ON p.fk_typepayment = c.id AND c.entity IN (".getEntity('c_paiement').")"; + $sql.= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'bank as b ON p.fk_bank = b.rowid'; + $sql.= ' LEFT JOIN ' . MAIN_DB_PREFIX . 'bank_account as ba ON b.fk_account = ba.rowid'; $sql.= " WHERE e.rowid = '".$id."'"; $sql.= " AND p.fk_expensereport = e.rowid"; $sql.= ' AND e.entity IN ('.getEntity('expensereport').')'; - $sql.= " AND p.fk_typepayment = c.id"; - $sql.= " AND c.entity = " . getEntity('c_paiement'); $sql.= " ORDER BY dp"; $resql = $db->query($sql); @@ -1883,19 +1880,21 @@ else { $objp = $db->fetch_object($resql); + $paymentexpensereportstatic->id = $objp->rowid; + $paymentexpensereportstatic->datepaye = $db->jdate($objp->dp); + $paymentexpensereportstatic->ref = $objp->rowid; + $paymentexpensereportstatic->num_paiement = $objp->num_paiement; + $paymentexpensereportstatic->payment_code = $objp->payment_code; + print '
    '; - $paymentexpensereportstatic->id = $objp->rowid; - $paymentexpensereportstatic->datepaye = $db->jdate($objp->dp); - $paymentexpensereportstatic->ref = $objp->rowid; - $paymentexpensereportstatic->num_paiement = $objp->num_paiement; - $paymentexpensereportstatic->payment_code = $objp->payment_code; print $paymentexpensereportstatic->getNomUrl(1); print ''.dol_print_date($db->jdate($objp->dp),'day')."".$labeltype.' '.$objp->num_payment."
    '; - $data=array('series'=>$dataseries); - dol_print_graph('stats',320,180,$data,1,'pie',0,'',0); + print '
    '; + + include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; + $dolgraph = new DolGraph(); + $dolgraph->SetData($dataseries); + $dolgraph->setShowLegend(1); + $dolgraph->setShowPercent(1); + $dolgraph->SetType(array('pie')); + $dolgraph->setWidth('100%'); + $dolgraph->draw('idgraphstatus'); + print $dolgraph->show($totalnb?0:1); + print '
    '; - if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select'))) - { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $searchclass=''; - if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; - if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; - print ''; - } - print ''; print '
    '; print dol_print_date($db->jdate($obj->date_create), 'dayhour'); diff --git a/htdocs/exports/export.php b/htdocs/exports/export.php index 4c15a7c4480..fe19d3073ae 100644 --- a/htdocs/exports/export.php +++ b/htdocs/exports/export.php @@ -64,7 +64,8 @@ $entitytoicon = array( 'virtualproduct'=>'product', 'subproduct' => 'product', 'warehouse' => 'stock', - 'batch' => 'stock', + 'batch' => 'stock', + 'stockbatch' => 'stock', 'category' => 'category', 'shipment' => 'sending', 'shipment_line'=> 'sending', @@ -100,7 +101,8 @@ $entitytolang = array( 'service' => 'Service', 'stock' => 'Stock', 'movement' => 'StockMovement', - 'batch' => 'Batch', + 'batch' => 'Batch', + 'stockbatch' => 'StockDetailPerBatch', 'warehouse' => 'Warehouse', 'category' => 'Category', 'other' => 'Other', @@ -1228,7 +1230,7 @@ if ($step == 5 && $datatoexport) $var=true; print ''; print ''; - print ''; + print ''; print ''; print ''; print ''."\n"; @@ -1245,11 +1247,13 @@ if ($step == 5 && $datatoexport) print ''; - print ''; + print ''; - print ''."\n"; + print $form->textwithpicto($label,$text).''; + print ''; + print ''; + print ''."\n"; } print '
    '.$langs->trans("AvailableFormats").''.$langs->trans("AvailableFormats").''.$langs->trans("LibraryUsed").''.$langs->trans("LibraryVersion").'
    '.img_picto_common($key,$objmodelexport->getPictoForKey($key)).''.img_picto_common($key,$objmodelexport->getPictoForKey($key)).' '; $text=$objmodelexport->getDriverDescForKey($key); $label=$listeall[$key]; - print ''.$form->textwithpicto($label,$text).''.$objmodelexport->getLibLabelForKey($key).''.$objmodelexport->getLibVersionForKey($key).'
    '.$objmodelexport->getLibLabelForKey($key).''.$objmodelexport->getLibVersionForKey($key).'
    '; diff --git a/htdocs/externalsite/admin/externalsite.php b/htdocs/externalsite/admin/externalsite.php index 99791a499fb..3d1fb6af478 100644 --- a/htdocs/externalsite/admin/externalsite.php +++ b/htdocs/externalsite/admin/externalsite.php @@ -54,7 +54,6 @@ if ($action == 'update') $i+=dolibarr_set_const($db,'EXTERNALSITE_LABEL',trim($label),'chaine',0,'',$conf->entity); $i+=dolibarr_set_const($db,'EXTERNALSITE_URL',trim($exturl),'chaine',0,'',$conf->entity); - //$i+=dolibarr_set_const($db,'EXTERNALSITE_LABEL',trim($_POST["EXTERNALSITE_LABEL"]),'chaine',0,'',$conf->entity); if ($i >= 2) { diff --git a/htdocs/fichinter/card.php b/htdocs/fichinter/card.php index d2e6dd26765..cb505831e7d 100644 --- a/htdocs/fichinter/card.php +++ b/htdocs/fichinter/card.php @@ -483,7 +483,7 @@ if (empty($reshook)) // Add line else if ($action == "addline" && $user->rights->ficheinter->creer) { - if (!GETPOST('np_desc') && empty($conf->global->FICHINTER_EMPTY_LINE_DESC) ) + if (!GETPOST('np_desc','none') && empty($conf->global->FICHINTER_EMPTY_LINE_DESC) ) { $mesg='
    '.$langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Description")).'
    '; $error++; @@ -502,7 +502,7 @@ if (empty($reshook)) { $db->begin(); - $desc=GETPOST('np_desc'); + $desc=GETPOST('np_desc','none'); $date_intervention = dol_mktime(GETPOST('dihour','int'), GETPOST('dimin','int'), 0, GETPOST('dimonth','int'), GETPOST('diday','int'), GETPOST('diyear','int')); $duration = empty($conf->global->FICHINTER_WITHOUT_DURATION)?convertTime2Seconds(GETPOST('durationhour','int'), GETPOST('durationmin','int')) : 0; diff --git a/htdocs/fichinter/class/fichinterstats.class.php b/htdocs/fichinter/class/fichinterstats.class.php index 9fb17eb25f2..b435398fec2 100644 --- a/htdocs/fichinter/class/fichinterstats.class.php +++ b/htdocs/fichinter/class/fichinterstats.class.php @@ -59,8 +59,8 @@ class FichinterStats extends Stats $this->socid = ($socid > 0 ? $socid : 0); $this->userid = $userid; - $this->cachefilesuffix = $mode; - + $this->cachefilesuffix = $mode; + $this->where.= " c.entity = ".$conf->entity; if ($mode == 'customer') { @@ -83,9 +83,10 @@ class FichinterStats extends Stats * Return intervention number by month for a year * * @param int $year Year to scan + * @param int $format 0=Label of absiss is a translated text, 1=Label of absiss is month number, 2=Label of absiss is first letter of month * @return array Array with number by month */ - function getNbByMonth($year) + function getNbByMonth($year, $format=0) { global $user; @@ -97,7 +98,7 @@ class FichinterStats extends Stats $sql.= " GROUP BY dm"; $sql.= $this->db->order('dm','DESC'); - $res=$this->_getNbByMonth($year, $sql); + $res=$this->_getNbByMonth($year, $sql, $format); return $res; } @@ -124,10 +125,11 @@ class FichinterStats extends Stats /** * Return the intervention amount by month for a year * - * @param int $year Year to scan - * @return array Array with amount by month + * @param int $year Year to scan + * @param int $format 0=Label of absiss is a translated text, 1=Label of absiss is month number, 2=Label of absiss is first letter of month + * @return array Array with amount by month */ - function getAmountByMonth($year) + function getAmountByMonth($year, $format=0) { global $user; @@ -139,7 +141,7 @@ class FichinterStats extends Stats $sql.= " GROUP BY dm"; $sql.= $this->db->order('dm','DESC'); - $res=$this->_getAmountByMonth($year, $sql); + $res=$this->_getAmountByMonth($year, $sql, $format); return $res; } @@ -205,6 +207,6 @@ class FichinterStats extends Stats return $this->_getAllByProduct($sql); } - + } diff --git a/htdocs/fichinter/index.php b/htdocs/fichinter/index.php index 53116dae843..d7cae075eb1 100644 --- a/htdocs/fichinter/index.php +++ b/htdocs/fichinter/index.php @@ -3,7 +3,7 @@ * Copyright (C) 2004-2015 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2015 Charlie Benke - + * * 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 @@ -121,15 +121,25 @@ if ($resql) $bool=false; foreach ($listofstatus as $status) { - $dataseries[]=array('label'=>$fichinterstatic->LibStatut($status,$bool,1),'data'=>(isset($vals[$status.$bool])?(int) $vals[$status.$bool]:0)); + $dataseries[]=array($fichinterstatic->LibStatut($status,$bool,1), (isset($vals[$status.$bool])?(int) $vals[$status.$bool]:0)); if ($status==3 && ! $bool) $bool=true; else $bool=false; } if ($conf->use_javascript_ajax) { print '
    '; + + include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; + $dolgraph = new DolGraph(); + $dolgraph->SetData($dataseries); + $dolgraph->setShowLegend(1); + $dolgraph->setShowPercent(1); + $dolgraph->SetType(array('pie')); + $dolgraph->setWidth('100%'); + $dolgraph->draw('idgraphstatus'); + print $dolgraph->show($total?0:1); $data=array('series'=>$dataseries); - dol_print_graph('stats',300,180,$data,1,'pie',1); + print '
    '.$fichinterstatic->LibStatut($status,$bool,0).''.(isset($vals[$status.$bool])?$vals[$status.$bool]:0).' '; @@ -190,7 +200,7 @@ if (! empty($conf->ficheinter->enabled)) $var = true; while ($i < $num) { - + $obj = $db->fetch_object($resql); print '
    '; @@ -240,7 +250,7 @@ if ($resql) $var = true; while ($i < $num) { - + $obj = $db->fetch_object($resql); print '
    '; diff --git a/htdocs/fichinter/list.php b/htdocs/fichinter/list.php index baf90355249..49cb1837d35 100644 --- a/htdocs/fichinter/list.php +++ b/htdocs/fichinter/list.php @@ -46,7 +46,7 @@ $search_ref=GETPOST('search_ref')?GETPOST('search_ref','alpha'):GETPOST('search_ $search_company=GETPOST('search_company','alpha'); $search_desc=GETPOST('search_desc','alpha'); $search_status=GETPOST('search_status'); -$sall=GETPOST('sall'); +$sall=trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alphanohtml'):GETPOST('sall', 'alphanohtml')); $optioncss = GETPOST('optioncss','alpha'); $socid=GETPOST('socid','int'); @@ -75,7 +75,7 @@ if (! $sortfield) // Initialize technical object to manage context to save list fields $contextpage=GETPOST('contextpage','aZ')?GETPOST('contextpage','aZ'):'interventionlist'; -$sall=GETPOST('sall', 'alphanohtml'); +$sall=trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alphanohtml'):GETPOST('sall', 'alphanohtml')); $search_ref=GETPOST('search_ref')?GETPOST('search_ref','alpha'):GETPOST('search_inter','alpha'); $search_company=GETPOST('search_company','alpha'); $search_desc=GETPOST('search_desc','alpha'); @@ -217,19 +217,7 @@ if ($sall) { $sql .= natural_search(array_keys($fieldstosearchall), $sall); } // Add where from extra fields -foreach ($search_array_options as $key => $val) -{ - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $typ=$extrafields->attribute_type[$tmpkey]; - $mode_search=0; - if (in_array($typ, array('int','double','real'))) $mode_search=1; // Search on a numeric - if (in_array($typ, array('sellist','link')) && $crit != '0' && $crit != '-1') $mode_search=2; // Search on a foreign key int - if ($crit != '' && (! in_array($typ, array('select','sellist')) || $crit != '0') && (! in_array($typ, array('link')) || $crit != '-1')) - { - $sql .= natural_search('ef.'.$tmpkey, $crit, $mode_search); - } -} +include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_sql.tpl.php'; // Add where from hooks $parameters=array(); $reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters); // Note that $action and $object may have been modified by hook @@ -273,20 +261,15 @@ if ($resql) if ($show_files) $param.='&show_files=' .$show_files; if ($optioncss != '') $param.='&optioncss='.$optioncss; // Add $param from extra fields - foreach ($search_array_options as $key => $val) - { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - if ($val != '') $param.='&search_options_'.$tmpkey.'='.urlencode($val); - } + include DOL_DOCUMENT_ROOT.'/core/tpl/extrafields_list_search_param.tpl.php'; // List of mass actions available $arrayofmassactions = array( //'presend'=>$langs->trans("SendByMail"), 'builddoc'=>$langs->trans("PDFMerge"), ); - if ($user->rights->ficheinter->supprimer) $arrayofmassactions['delete']=$langs->trans("Delete"); - //if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array(); + if ($user->rights->ficheinter->supprimer) $arrayofmassactions['predelete']=$langs->trans("Delete"); + if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array(); $massactionbutton=$form->selectMassAction('', $arrayofmassactions); // Lines of title fields @@ -302,6 +285,12 @@ if ($resql) print_barre_liste($title, $page, $_SERVER['PHP_SELF'], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_commercial.png', 0, '', '', $limit); + $topicmail="Information"; + $modelmail="intervention"; + $objecttmp=new Fichinter($db); + $trackid='int'.$object->id; + include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; + if ($sall) { foreach($fieldstosearchall as $key => $val) $fieldstosearchall[$key]=$langs->trans($val); @@ -362,28 +351,8 @@ if ($resql) print ' '; - if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select'))) - { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $searchclass=''; - if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; - if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; - print ''; - } - print '
    ' . $langs->trans('Project') . ''; $formproject->select_projects((empty($conf->global->PROJECT_CAN_ALWAYS_LINK_TO_ALL_SUPPLIERS)?$societe->id:-1), $projectid, 'projectid', 0, 0, 1, 1); + print '   id).'">' . $langs->trans("AddProject") . ''; + print '
    '.$commandestatic->LibStatut($statut,0).''.(isset($vals[$statut])?$vals[$statut]:0).'
    '; - $data=array('series'=>$dataseries); - dol_print_graph('stats',300,180,$data,1,'pie',1,'',0); + + include_once DOL_DOCUMENT_ROOT.'/core/class/dolgraph.class.php'; + $dolgraph = new DolGraph(); + $dolgraph->SetData($dataseries); + $dolgraph->setShowLegend(1); + $dolgraph->setShowPercent(1); + $dolgraph->SetType(array('pie')); + $dolgraph->setWidth('100%'); + $dolgraph->draw('idgraphstatus'); + print $dolgraph->show($total?0:1); + print '
    '.$langs->trans($commandestatic->statuts[$row[1]]).'
    '; @@ -268,7 +277,7 @@ if ($resql) while ($i < $num) { $obj = $db->fetch_object($resql); - + print '
    '; @@ -324,7 +333,7 @@ if ($resql) $var = True; while ($i < $num) { - + $obj = $db->fetch_object($resql); print '
    '; - if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select'))) - { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $searchclass=''; - if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; - if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; - print ''; - } - print '
    '; $paymentstatic->id=$objp->rowid; $paymentstatic->datepaye=$db->jdate($objp->dp); $paymentstatic->ref=($objp->ref ? $objp->ref : $objp->rowid);; $paymentstatic->num_paiement=$objp->num_paiement; $paymentstatic->payment_code=$objp->payment_code; + + print '
    '; print $paymentstatic->getNomUrl(1); print ''.dol_print_date($db->jdate($objp->dp), 'day') . '
    '; print $langs->trans('AlreadyPaidBack'); @@ -2627,7 +2643,7 @@ else else print $langs->trans('ExcessPaydBack'); print ' :' . price($sign * $resteapayeraffiche) . '' . price($sign * $resteapayeraffiche) . ' 
    '; - if (in_array($typeofextrafield, array('varchar', 'int', 'double', 'select'))) - { - $crit=$val; - $tmpkey=preg_replace('/search_options_/','',$key); - $searchclass=''; - if (in_array($typeofextrafield, array('varchar', 'select'))) $searchclass='searchstring'; - if (in_array($typeofextrafield, array('int', 'double'))) $searchclass='searchnum'; - print ''; - } - print '
    '.img_object($langs->trans('ShowBill'),'bill').' '; - print ($objp->ref?$objp->ref:$objp->rowid); - print "'; + print $facturestatic->getNomUrl(1); + print "'.$objp->ref_supplier."
    '; // Lignes des champs de filtre diff --git a/htdocs/holiday/card.php b/htdocs/holiday/card.php index c957ec67a5b..e3009c975bc 100644 --- a/htdocs/holiday/card.php +++ b/htdocs/holiday/card.php @@ -149,11 +149,11 @@ if ($action == 'create') { $object->fk_user = $fuserid; $object->description = $description; - $object->date_debut = $date_debut; - $object->date_fin = $date_fin; $object->fk_validator = $valideur; - $object->halfday = $halfday; $object->fk_type = $type; + $object->date_debut = $date_debut; + $object->date_fin = $date_fin; + $object->halfday = $halfday; $result = $object->create($user); if ($result <= 0) @@ -386,7 +386,9 @@ if ($action == 'confirm_send') $message.= "- ".$langs->transnoentitiesnoconv("Link")." : ".$dolibarr_main_url_root."/holiday/card.php?id=".$object->id."\n\n"; $message.= "\n"; - $mail = new CMailFile($subject,$emailTo,$emailFrom,$message); + $trackid='leav'.$object->id; + + $mail = new CMailFile($subject, $emailTo, $emailFrom, $message, null, null, null, '', '', 0, 0, '', '', $trackid); // Envoi du mail $result=$mail->sendfile(); @@ -472,12 +474,14 @@ if ($action == 'confirm_valid') $message.= "- ".$langs->transnoentitiesnoconv("Link")." : ".$dolibarr_main_url_root."/holiday/card.php?id=".$object->id."\n\n"; $message.= "\n"; - $mail = new CMailFile($subject,$emailTo,$emailFrom,$message); + $trackid='leav'.$object->id; + + $mail = new CMailFile($subject, $emailTo, $emailFrom, $message, null, null, null, '', '', 0, 0, '', '', $trackid); // Envoi du mail $result=$mail->sendfile(); - if(!$result) { + if (!$result) { header('Location: '.$_SERVER["PHP_SELF"].'?id='.$object->id.'&error=mail&error_content='.$mail->error); exit; } @@ -547,7 +551,9 @@ if ($action == 'confirm_refuse') $message.= "- ".$langs->transnoentitiesnoconv("Link")." : ".$dolibarr_main_url_root."/holiday/card.php?id=".$object->id."\n\n"; $message.= "\n"; - $mail = new CMailFile($subject,$emailTo,$emailFrom,$message); + $trackid='leav'.$object->id; + + $mail = new CMailFile($subject, $emailTo, $emailFrom, $message, null, null, null, '', '', 0, 0, '', '', $trackid); // Envoi du mail $result=$mail->sendfile(); @@ -684,7 +690,9 @@ if ($action == 'confirm_cancel' && GETPOST('confirm') == 'yes') $message.= "- ".$langs->transnoentitiesnoconv("Link")." : ".$dolibarr_main_url_root."/holiday/card.php?id=".$object->id."\n\n"; $message.= "\n"; - $mail = new CMailFile($subject,$emailTo,$emailFrom,$message); + $trackid='leav'.$object->id; + + $mail = new CMailFile($subject, $emailTo, $emailFrom, $message, null, null, null, '', '', 0, 0, '', '', $trackid); // Envoi du mail $result=$mail->sendfile(); @@ -1081,7 +1089,7 @@ else print ''; print ''; print ''; } @@ -1103,7 +1111,7 @@ else print ''; print ''; print ''; } diff --git a/htdocs/holiday/class/holiday.class.php b/htdocs/holiday/class/holiday.class.php index 4381eacb3a7..26551847772 100644 --- a/htdocs/holiday/class/holiday.class.php +++ b/htdocs/holiday/class/holiday.class.php @@ -698,14 +698,14 @@ class Holiday extends CommonObject * Warning: It consumes a lot of memory because it load in ->holiday all holiday of a dedicated user at each call. * * @param int $fk_user Id user - * @param date $dateDebut Start date of period to check - * @param date $dateFin End date of period to check + * @param date $dateStart Start date of period to check + * @param date $dateEnd End date of period to check * @param int $halfday Tag to define how start and end the period to check: - * 0:Full days, 2:Sart afternoon end monring, -1:Start afternoon, 1:End morning - * @return boolean False is on holiday at least partially into the period, True is never on holiday during chcked period. + * 0:Full days, 2:Start afternoon end morning, -1:Start afternoon end afternoon, 1:Start morning end morning + * @return boolean False = New range overlap an existing holiday, True = no overlapping (is never on holiday during checked period). * @see verifDateHolidayForTimestamp */ - function verifDateHolidayCP($fk_user, $dateDebut, $dateFin, $halfday=0) + function verifDateHolidayCP($fk_user, $dateStart, $dateEnd, $halfday=0) { $this->fetchByUser($fk_user,'',''); @@ -713,34 +713,59 @@ class Holiday extends CommonObject { if ($infos_CP['statut'] == 4) continue; // ignore not validated holidays if ($infos_CP['statut'] == 5) continue; // ignore not validated holidays + /* + var_dump("--"); + var_dump("old: ".dol_print_date($infos_CP['date_debut'],'dayhour').' '.dol_print_date($infos_CP['date_fin'],'dayhour').' '.$infos_CP['halfday']); + var_dump("new: ".dol_print_date($dateStart,'dayhour').' '.dol_print_date($dateEnd,'dayhour').' '.$halfday); + */ - // TODO Also use halfday for the check if ($halfday == 0) { - if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) + if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) + { + return false; + } + if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) { return false; } } elseif ($halfday == -1) { - if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) + // new start afternoon, new end afternoon + if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) { - return false; + if ($dateStart < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) return false; + } + if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) + { + if ($dateStart < $dateEnd) return false; + if ($dateEnd < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) return false; } } elseif ($halfday == 1) { - if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) + // new start morning, new end morning + if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) { - return false; + if ($dateStart < $dateEnd) return false; + if ($dateStart > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) return false; + } + if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) + { + if ($dateEnd > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) return false; } } elseif ($halfday == 2) { - if ($dateDebut >= $infos_CP['date_debut'] && $dateDebut <= $infos_CP['date_fin'] || $dateFin <= $infos_CP['date_fin'] && $dateFin >= $infos_CP['date_debut']) + // new start afternoon, new end morning + if ($dateStart >= $infos_CP['date_debut'] && $dateStart <= $infos_CP['date_fin']) { - return false; + if ($dateStart < $infos_CP['date_fin'] || in_array($infos_CP['halfday'], array(0, -1))) return false; + } + if ($dateEnd <= $infos_CP['date_fin'] && $dateEnd >= $infos_CP['date_debut']) + { + if ($dateEnd > $infos_CP['date_debut'] || in_array($infos_CP['halfday'], array(0, 1))) return false; } } else @@ -1096,7 +1121,7 @@ class Holiday extends CommonObject while ($i < $nbUser) { $now_holiday = $this->getCPforUser($users[$i]['rowid'], $val['rowid']); - $new_solde = $now_holiday + $this->getConfCP('nbHolidayEveryMonth'); + $new_solde = $now_holiday + $nb_holiday; // We add a log for each user $this->addLogCP($user->id, $users[$i]['rowid'], $langs->trans('HolidaysMonthlyUpdate'), $new_solde, $val['rowid']); diff --git a/htdocs/holiday/list.php b/htdocs/holiday/list.php index 1d89bbbdd94..cf81d0a98fa 100644 --- a/htdocs/holiday/list.php +++ b/htdocs/holiday/list.php @@ -73,7 +73,7 @@ if (! $sortorder) $sortorder="DESC"; $id = GETPOST('id','int'); -$sall = GETPOST('sall', 'alphanohtml'); +$sall = trim((GETPOST('search_all', 'alphanohtml')!='')?GETPOST('search_all', 'alphanohtml'):GETPOST('sall', 'alphanohtml')); $search_ref = GETPOST('search_ref'); $month_create = GETPOST('month_create'); $year_create = GETPOST('year_create'); @@ -298,8 +298,8 @@ $arrayofmassactions = array( //'presend'=>$langs->trans("SendByMail"), //'builddoc'=>$langs->trans("PDFMerge"), ); -if ($user->rights->holiday->delete) $arrayofmassactions['delete']=$langs->trans("Delete"); -//if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array(); +if ($user->rights->holiday->delete) $arrayofmassactions['predelete']=$langs->trans("Delete"); +if (in_array($massaction, array('presend','predelete'))) $arrayofmassactions=array(); $massactionbutton=$form->selectMassAction('', $arrayofmassactions); print ''; @@ -352,14 +352,11 @@ else //print count($holiday->holiday); print_barre_liste($langs->trans("ListeCP"), $page, $_SERVER["PHP_SELF"], $param, $sortfield, $sortorder, $massactionbutton, $num, $nbtotalofrecords, 'title_hrm.png', 0, '', '', $limit); - /*if (empty($conf->global->HOLIDAY_HIDE_BALANCE)) - { - dol_fiche_head('', '', '', -1); - - showMyBalance($holiday, $user_id); - - dol_fiche_end(); - }*/ + $topicmail="Information"; + $modelmail="leaverequest"; + $objecttmp=new Holiday($db); + $trackid='leav'.$object->id; + include DOL_DOCUMENT_ROOT.'/core/tpl/massactions_pre.tpl.php'; } if ($sall) @@ -474,6 +471,8 @@ print_liste_field_titre("Status",$_SERVER["PHP_SELF"],"cp.statut","",$param,'ali print getTitleFieldOfList($selectedfields, 0, $_SERVER["PHP_SELF"],"",'','','align="center"',$sortfield,$sortorder,'maxwidthsearch ')."\n"; print "\n"; +$listhalfday=array('morning'=>$langs->trans("Morning"),"afternoon"=>$langs->trans("Afternoon")); + // Lines if (! empty($holiday->holiday)) { @@ -484,6 +483,10 @@ if (! empty($holiday->holiday)) foreach($holiday->holiday as $infos_CP) { + // Leave request + $holidaystatic->id=$infos_CP['rowid']; + $holidaystatic->ref=$infos_CP['rowid']; + // User $userstatic->id=$infos_CP['fk_user']; $userstatic->lastname=$infos_CP['user_lastname']; @@ -502,10 +505,11 @@ if (! empty($holiday->holiday)) $date = $infos_CP['date_create']; + $starthalfday=($infos_CP['halfday'] == -1 || $infos_CP['halfday'] == 2)?'afternoon':'morning'; + $endhalfday=($infos_CP['halfday'] == 1 || $infos_CP['halfday'] == 2)?'morning':'afternoon'; + print ''; print ''; print ''; @@ -518,8 +522,14 @@ if (! empty($holiday->holiday)) $nbopenedday=num_open_day($infos_CP['date_debut_gmt'], $infos_CP['date_fin_gmt'], 0, 1, $infos_CP['halfday']); print $nbopenedday.' '.$langs->trans('DurationDays'); print ''; - print ''; - print ''; + print ''; + print ''; print ''; // Action column diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index 1549e7124e0..6223bf92aad 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -1478,7 +1478,7 @@ if ($step == 5 && $datatoimport) while ($sourcelinenb < $nboflines && ! $endoffile) { $sourcelinenb++; - // Read line and stor it into $arrayrecord + // Read line and store it into $arrayrecord $arrayrecord=$obj->import_read_record(); if ($arrayrecord === false) { diff --git a/htdocs/includes/jquery/plugins/tablednd/README.txt b/htdocs/includes/jquery/plugins/tablednd/README.txt index 1fab924b7f0..9de4f5db79e 100644 --- a/htdocs/includes/jquery/plugins/tablednd/README.txt +++ b/htdocs/includes/jquery/plugins/tablednd/README.txt @@ -1,3 +1,5 @@ ----- jquery.tablednd ----- - New versions are found into directory js of https://github.com/isocra/TableDnD -- Version 0.7, 0.8 seems to be not compatible. \ No newline at end of file +- Distribution available on 'npm install tablednd' +- Current version V1.0 RC for 7.0 alpha +- TODO update to V1.0 for 7.0 beta \ No newline at end of file diff --git a/htdocs/includes/jquery/plugins/tablednd/jquery.tablednd.0.6.js b/htdocs/includes/jquery/plugins/tablednd/jquery.tablednd.0.6.js deleted file mode 100644 index 34f3c88232b..00000000000 --- a/htdocs/includes/jquery/plugins/tablednd/jquery.tablednd.0.6.js +++ /dev/null @@ -1,400 +0,0 @@ -/** - * TableDnD plug-in for JQuery, allows you to drag and drop table rows - * You can set up various options to control how the system will work - * Copyright (c) Denis Howlett - * Licensed like jQuery, see http://docs.jquery.com/License. - * - * Configuration options: - * - * onDragStyle - * This is the style that is assigned to the row during drag. There are limitations to the styles that can be - * associated with a row (such as you can't assign a border--well you can, but it won't be - * displayed). (So instead consider using onDragClass.) The CSS style to apply is specified as - * a map (as used in the jQuery css(...) function). - * onDropStyle - * This is the style that is assigned to the row when it is dropped. As for onDragStyle, there are limitations - * to what you can do. Also this replaces the original style, so again consider using onDragClass which - * is simply added and then removed on drop. - * onDragClass - * This class is added for the duration of the drag and then removed when the row is dropped. It is more - * flexible than using onDragStyle since it can be inherited by the row cells and other content. The default - * is class is tDnD_whileDrag. So to use the default, simply customise this CSS class in your - * stylesheet. - * onDrop - * Pass a function that will be called when the row is dropped. The function takes 2 parameters: the table - * and the row that was dropped. You can work out the new order of the rows by using - * table.rows. - * onDragStart - * Pass a function that will be called when the user starts dragging. The function takes 2 parameters: the - * table and the row which the user has started to drag. - * onAllowDrop - * Pass a function that will be called as a row is over another row. If the function returns true, allow - * dropping on that row, otherwise not. The function takes 2 parameters: the dragged row and the row under - * the cursor. It returns a boolean: true allows the drop, false doesn't allow it. - * scrollAmount - * This is the number of pixels to scroll if the user moves the mouse cursor to the top or bottom of the - * window. The page should automatically scroll up or down as appropriate (tested in IE6, IE7, Safari, FF2, - * FF3 beta - * dragHandle - * This is the name of a class that you assign to one or more cells in each row that is draggable. If you - * specify this class, then you are responsible for setting cursor: move in the CSS and only these cells - * will have the drag behaviour. If you do not specify a dragHandle, then you get the old behaviour where - * the whole row is draggable. - * - * Other ways to control behaviour: - * - * Add class="nodrop" to any rows for which you don't want to allow dropping, and class="nodrag" to any rows - * that you don't want to be draggable. - * - * Inside the onDrop method you can also call $.tableDnD.serialize() this returns a string of the form - * []=&[]= so that you can send this back to the server. The table must have - * an ID as must all the rows. - * - * Other methods: - * - * $("...").tableDnDUpdate() - * Will update all the matching tables, that is it will reapply the mousedown method to the rows (or handle cells). - * This is useful if you have updated the table rows using Ajax and you want to make the table draggable again. - * The table maintains the original configuration (so you don't have to specify it again). - * - * $("...").tableDnDSerialize() - * Will serialize and return the serialized string as above, but for each of the matching tables--so it can be - * called from anywhere and isn't dependent on the currentTable being set up correctly before calling - * - * Known problems: - * - Auto-scoll has some problems with IE7 (it scrolls even when it shouldn't), work-around: set scrollAmount to 0 - * - * Version 0.2: 2008-02-20 First public version - * Version 0.3: 2008-02-07 Added onDragStart option - * Made the scroll amount configurable (default is 5 as before) - * Version 0.4: 2008-03-15 Changed the noDrag/noDrop attributes to nodrag/nodrop classes - * Added onAllowDrop to control dropping - * Fixed a bug which meant that you couldn't set the scroll amount in both directions - * Added serialize method - * Version 0.5: 2008-05-16 Changed so that if you specify a dragHandle class it doesn't make the whole row - * draggable - * Improved the serialize method to use a default (and settable) regular expression. - * Added tableDnDupate() and tableDnDSerialize() to be called when you are outside the table - * Version 0.6: 2011-12-02 Added support for touch devices - */ -// Determine if this is a touch device -var hasTouch = 'ontouchstart' in document.documentElement, - startEvent = hasTouch ? 'touchstart' : 'mousedown', - moveEvent = hasTouch ? 'touchmove' : 'mousemove', - endEvent = hasTouch ? 'touchend' : 'mouseup'; - -jQuery.tableDnD = { - /** Keep hold of the current table being dragged */ - currentTable : null, - /** Keep hold of the current drag object if any */ - dragObject: null, - /** The current mouse offset */ - mouseOffset: null, - /** Remember the old value of Y so that we don't do too much processing */ - oldY: 0, - - - /** Actually build the structure */ - build: function(options) { - // Set up the defaults if any - - this.each(function() { - // This is bound to each matching table, set up the defaults and override with user options - this.tableDnDConfig = jQuery.extend({ - onDragStyle: null, - onDropStyle: null, - // Add in the default class for whileDragging - onDragClass: "tDnD_whileDrag", - onDrop: null, - onDragStart: null, - scrollAmount: 5, - - serializeRegexp: /[^\-]*$/, // The regular expression to use to trim row IDs - serializeParamName: null, // If you want to specify another parameter name instead of the table ID - dragHandle: null // If you give the name of a class here, then only Cells with this class will be draggable - }, options || {}); - // Now make the rows draggable - jQuery.tableDnD.makeDraggable(this); - }); - - // Don't break the chain - return this; - }, - - /** This function makes all the rows on the table draggable apart from those marked as "NoDrag" */ - makeDraggable: function(table) { - - var config = table.tableDnDConfig; - if (config.dragHandle) { - // We only need to add the event to the specified cells - var cells = jQuery("td."+table.tableDnDConfig.dragHandle, table); - cells.each(function() { - // The cell is bound to "this" - jQuery(this).bind(startEvent, function(ev) { - jQuery.tableDnD.initialiseDrag(this.parentNode, table, this, ev, config); - return false; - }); - }) - } else { - // For backwards compatibility, we add the event to the whole row - var rows = jQuery("tr", table); // get all the rows as a wrapped set - rows.each(function() { - // Iterate through each row, the row is bound to "this" - var row = jQuery(this); - if (! row.hasClass("nodrag")) { - row.bind(startEvent, function(ev) { - if (ev.target.tagName == "TD") { - jQuery.tableDnD.initialiseDrag(this, table, this, ev, config); - return false; - } - }).css("cursor", "move"); // Store the tableDnD object - } - }); - } - }, - - initialiseDrag: function(dragObject, table, target, evnt, config) { - jQuery.tableDnD.dragObject = dragObject; - jQuery.tableDnD.currentTable = table; - jQuery.tableDnD.mouseOffset = jQuery.tableDnD.getMouseOffset(target, evnt); - jQuery.tableDnD.originalOrder = jQuery.tableDnD.serialize(); - // Now we need to capture the mouse up and mouse move event - // We can use bind so that we don't interfere with other event handlers - jQuery(document) - .bind(moveEvent, jQuery.tableDnD.mousemove) - .bind(endEvent, jQuery.tableDnD.mouseup); - if (config.onDragStart) { - // Call the onDragStart method if there is one - config.onDragStart(table, target); - } - }, - - updateTables: function() { - this.each(function() { - // this is now bound to each matching table - if (this.tableDnDConfig) { - jQuery.tableDnD.makeDraggable(this); - } - }) - }, - - /** Get the mouse coordinates from the event (allowing for browser differences) */ - mouseCoords: function(ev){ - if(ev.pageX || ev.pageY){ - return {x:ev.pageX, y:ev.pageY}; - } - return { - x:ev.clientX + document.body.scrollLeft - document.body.clientLeft, - y:ev.clientY + document.body.scrollTop - document.body.clientTop - }; - }, - - /** Given a target element and a mouse event, get the mouse offset from that element. - To do this we need the element's position and the mouse position */ - getMouseOffset: function(target, ev) { - ev = ev || window.event; - - var docPos = this.getPosition(target); - var mousePos = this.mouseCoords(ev); - return {x:mousePos.x - docPos.x, y:mousePos.y - docPos.y}; - }, - - /** Get the position of an element by going up the DOM tree and adding up all the offsets */ - getPosition: function(e){ - var left = 0; - var top = 0; - /** Safari fix -- thanks to Luis Chato for this! */ - if (e.offsetHeight == 0) { - /** Safari 2 doesn't correctly grab the offsetTop of a table row - this is detailed here: - http://jacob.peargrove.com/blog/2006/technical/table-row-offsettop-bug-in-safari/ - the solution is likewise noted there, grab the offset of a table cell in the row - the firstChild. - note that firefox will return a text node as a first child, so designing a more thorough - solution may need to take that into account, for now this seems to work in firefox, safari, ie */ - e = e.firstChild; // a table cell - } - - while (e.offsetParent){ - left += e.offsetLeft; - top += e.offsetTop; - e = e.offsetParent; - } - - left += e.offsetLeft; - top += e.offsetTop; - - return {x:left, y:top}; - }, - - mousemove: function(ev) { - if (jQuery.tableDnD.dragObject == null) { - return; - } - if (ev.type == 'touchmove') { - // prevent touch device screen scrolling - event.preventDefault(); - } - - var dragObj = jQuery(jQuery.tableDnD.dragObject); - var config = jQuery.tableDnD.currentTable.tableDnDConfig; - var mousePos = jQuery.tableDnD.mouseCoords(ev); - var y = mousePos.y - jQuery.tableDnD.mouseOffset.y; - //auto scroll the window - var yOffset = window.pageYOffset; - if (document.all) { - // Windows version - //yOffset=document.body.scrollTop; - if (typeof document.compatMode != 'undefined' && - document.compatMode != 'BackCompat') { - yOffset = document.documentElement.scrollTop; - } - else if (typeof document.body != 'undefined') { - yOffset=document.body.scrollTop; - } - - } - - if (mousePos.y-yOffset < config.scrollAmount) { - window.scrollBy(0, -config.scrollAmount); - } else { - var windowHeight = window.innerHeight ? window.innerHeight - : document.documentElement.clientHeight ? document.documentElement.clientHeight : document.body.clientHeight; - if (windowHeight-(mousePos.y-yOffset) < config.scrollAmount) { - window.scrollBy(0, config.scrollAmount); - } - } - - - if (y != jQuery.tableDnD.oldY) { - // work out if we're going up or down... - var movingDown = y > jQuery.tableDnD.oldY; - // update the old value - jQuery.tableDnD.oldY = y; - // update the style to show we're dragging - if (config.onDragClass) { - dragObj.addClass(config.onDragClass); - } else { - dragObj.css(config.onDragStyle); - } - // If we're over a row then move the dragged row to there so that the user sees the - // effect dynamically - var currentRow = jQuery.tableDnD.findDropTargetRow(dragObj, y); - if (currentRow) { - // TODO worry about what happens when there are multiple TBODIES - if (movingDown && jQuery.tableDnD.dragObject != currentRow) { - jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject, currentRow.nextSibling); - } else if (! movingDown && jQuery.tableDnD.dragObject != currentRow) { - jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject, currentRow); - } - } - } - - return false; - }, - - /** We're only worried about the y position really, because we can only move rows up and down */ - findDropTargetRow: function(draggedRow, y) { - var rows = jQuery.tableDnD.currentTable.rows; - for (var i=0; i rowY - rowHeight) && (y < (rowY + rowHeight))) { - // that's the row we're over - // If it's the same as the current row, ignore it - if (row == draggedRow) {return null;} - var config = jQuery.tableDnD.currentTable.tableDnDConfig; - if (config.onAllowDrop) { - if (config.onAllowDrop(draggedRow, row)) { - return row; - } else { - return null; - } - } else { - // If a row has nodrop class, then don't allow dropping (inspired by John Tarr and Famic) - var nodrop = jQuery(row).hasClass("nodrop"); - if (! nodrop) { - return row; - } else { - return null; - } - } - return row; - } - } - return null; - }, - - mouseup: function(e) { - if (jQuery.tableDnD.currentTable && jQuery.tableDnD.dragObject) { - // Unbind the event handlers - jQuery(document) - .unbind(moveEvent, jQuery.tableDnD.mousemove) - .unbind(endEvent, jQuery.tableDnD.mouseup); - var droppedRow = jQuery.tableDnD.dragObject; - var config = jQuery.tableDnD.currentTable.tableDnDConfig; - // If we have a dragObject, then we need to release it, - // The row will already have been moved to the right place so we just reset stuff - if (config.onDragClass) { - jQuery(droppedRow).removeClass(config.onDragClass); - } else { - jQuery(droppedRow).css(config.onDropStyle); - } - jQuery.tableDnD.dragObject = null; - var newOrder = jQuery.tableDnD.serialize(); - if (config.onDrop && (jQuery.tableDnD.originalOrder != newOrder)) { - // Call the onDrop method if there is one - config.onDrop(jQuery.tableDnD.currentTable, droppedRow); - } - jQuery.tableDnD.currentTable = null; // let go of the table too - } - }, - - serialize: function() { - if (jQuery.tableDnD.currentTable) { - return jQuery.tableDnD.serializeTable(jQuery.tableDnD.currentTable); - } else { - return "Error: No Table id set, you need to set an id on your table and every row"; - } - }, - - serializeTable: function(table) { - var result = ""; - var tableId = table.id; - var rows = table.rows; - for (var i=0; i 0) result += "&"; - var rowId = rows[i].id; - if (rowId && rowId && table.tableDnDConfig && table.tableDnDConfig.serializeRegexp) { - rowId = rowId.match(table.tableDnDConfig.serializeRegexp)[0]; - } - - result += tableId + '[]=' + rowId; - } - return result; - }, - - serializeTables: function() { - var result = ""; - this.each(function() { - // this is now bound to each matching table - result += jQuery.tableDnD.serializeTable(this); - }); - return result; - } - -}; - - -jQuery.fn.extend( - { - tableDnD : jQuery.tableDnD.build, - tableDnDUpdate : jQuery.tableDnD.updateTables, - tableDnDSerialize: jQuery.tableDnD.serializeTables - } -); \ No newline at end of file diff --git a/htdocs/includes/jquery/plugins/tablednd/jquery.tablednd.0.6.min.js b/htdocs/includes/jquery/plugins/tablednd/jquery.tablednd.0.6.min.js deleted file mode 100644 index 7201855a3c9..00000000000 --- a/htdocs/includes/jquery/plugins/tablednd/jquery.tablednd.0.6.min.js +++ /dev/null @@ -1 +0,0 @@ -var hasTouch='ontouchstart'in document.documentElement,startEvent=hasTouch?'touchstart':'mousedown',moveEvent=hasTouch?'touchmove':'mousemove',endEvent=hasTouch?'touchend':'mouseup';jQuery.tableDnD={currentTable:null,dragObject:null,mouseOffset:null,oldY:0,build:function(options){this.each(function(){this.tableDnDConfig=jQuery.extend({onDragStyle:null,onDropStyle:null,onDragClass:"tDnD_whileDrag",onDrop:null,onDragStart:null,scrollAmount:5,serializeRegexp:/[^\-]*$/,serializeParamName:null,dragHandle:null},options||{});jQuery.tableDnD.makeDraggable(this)});return this},makeDraggable:function(table){var config=table.tableDnDConfig;if(config.dragHandle){var cells=jQuery("td."+table.tableDnDConfig.dragHandle,table);cells.each(function(){jQuery(this).bind(startEvent,function(ev){jQuery.tableDnD.initialiseDrag(this.parentNode,table,this,ev,config);return false})})}else{var rows=jQuery("tr",table);rows.each(function(){var row=jQuery(this);if(!row.hasClass("nodrag")){row.bind(startEvent,function(ev){if(ev.target.tagName=="TD"){jQuery.tableDnD.initialiseDrag(this,table,this,ev,config);return false}}).css("cursor","move")}})}},initialiseDrag:function(dragObject,table,target,evnt,config){jQuery.tableDnD.dragObject=dragObject;jQuery.tableDnD.currentTable=table;jQuery.tableDnD.mouseOffset=jQuery.tableDnD.getMouseOffset(target,evnt);jQuery.tableDnD.originalOrder=jQuery.tableDnD.serialize();jQuery(document).bind(moveEvent,jQuery.tableDnD.mousemove).bind(endEvent,jQuery.tableDnD.mouseup);if(config.onDragStart){config.onDragStart(table,target)}},updateTables:function(){this.each(function(){if(this.tableDnDConfig){jQuery.tableDnD.makeDraggable(this)}})},mouseCoords:function(ev){if(ev.pageX||ev.pageY){return{x:ev.pageX,y:ev.pageY}}return{x:ev.clientX+document.body.scrollLeft-document.body.clientLeft,y:ev.clientY+document.body.scrollTop-document.body.clientTop}},getMouseOffset:function(target,ev){ev=ev||window.event;var docPos=this.getPosition(target);var mousePos=this.mouseCoords(ev);return{x:mousePos.x-docPos.x,y:mousePos.y-docPos.y}},getPosition:function(e){var left=0;var top=0;if(e.offsetHeight==0){e=e.firstChild}while(e.offsetParent){left+=e.offsetLeft;top+=e.offsetTop;e=e.offsetParent}left+=e.offsetLeft;top+=e.offsetTop;return{x:left,y:top}},mousemove:function(ev){if(jQuery.tableDnD.dragObject==null){return}if(ev.type=='touchmove'){event.preventDefault()}var dragObj=jQuery(jQuery.tableDnD.dragObject);var config=jQuery.tableDnD.currentTable.tableDnDConfig;var mousePos=jQuery.tableDnD.mouseCoords(ev);var y=mousePos.y-jQuery.tableDnD.mouseOffset.y;var yOffset=window.pageYOffset;if(document.all){if(typeof document.compatMode!='undefined'&&document.compatMode!='BackCompat'){yOffset=document.documentElement.scrollTop}else if(typeof document.body!='undefined'){yOffset=document.body.scrollTop}}if(mousePos.y-yOffsetjQuery.tableDnD.oldY;jQuery.tableDnD.oldY=y;if(config.onDragClass){dragObj.addClass(config.onDragClass)}else{dragObj.css(config.onDragStyle)}var currentRow=jQuery.tableDnD.findDropTargetRow(dragObj,y);if(currentRow){if(movingDown&&jQuery.tableDnD.dragObject!=currentRow){jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject,currentRow.nextSibling)}else if(!movingDown&&jQuery.tableDnD.dragObject!=currentRow){jQuery.tableDnD.dragObject.parentNode.insertBefore(jQuery.tableDnD.dragObject,currentRow)}}}return false},findDropTargetRow:function(draggedRow,y){var rows=jQuery.tableDnD.currentTable.rows;for(var i=0;irowY-rowHeight)&&(y<(rowY+rowHeight))){if(row==draggedRow){return null}var config=jQuery.tableDnD.currentTable.tableDnDConfig;if(config.onAllowDrop){if(config.onAllowDrop(draggedRow,row)){return row}else{return null}}else{var nodrop=jQuery(row).hasClass("nodrop");if(!nodrop){return row}else{return null}}return row}}return null},mouseup:function(e){if(jQuery.tableDnD.currentTable&&jQuery.tableDnD.dragObject){jQuery(document).unbind(moveEvent,jQuery.tableDnD.mousemove).unbind(endEvent,jQuery.tableDnD.mouseup);var droppedRow=jQuery.tableDnD.dragObject;var config=jQuery.tableDnD.currentTable.tableDnDConfig;if(config.onDragClass){jQuery(droppedRow).removeClass(config.onDragClass)}else{jQuery(droppedRow).css(config.onDropStyle)}jQuery.tableDnD.dragObject=null;var newOrder=jQuery.tableDnD.serialize();if(config.onDrop&&(jQuery.tableDnD.originalOrder!=newOrder)){config.onDrop(jQuery.tableDnD.currentTable,droppedRow)}jQuery.tableDnD.currentTable=null}},serialize:function(){if(jQuery.tableDnD.currentTable){return jQuery.tableDnD.serializeTable(jQuery.tableDnD.currentTable)}else{return"Error: No Table id set, you need to set an id on your table and every row"}},serializeTable:function(table){var result="";var tableId=table.id;var rows=table.rows;for(var i=0;i0)result+="&";var rowId=rows[i].id;if(rowId&&rowId&&table.tableDnDConfig&&table.tableDnDConfig.serializeRegexp){rowId=rowId.match(table.tableDnDConfig.serializeRegexp)[0]}result+=tableId+'[]='+rowId}return result},serializeTables:function(){var result="";this.each(function(){result+=jQuery.tableDnD.serializeTable(this)});return result}};jQuery.fn.extend({tableDnD:jQuery.tableDnD.build,tableDnDUpdate:jQuery.tableDnD.updateTables,tableDnDSerialize:jQuery.tableDnD.serializeTables}); \ No newline at end of file diff --git a/htdocs/includes/jquery/plugins/tablednd/jquery.tablednd.js b/htdocs/includes/jquery/plugins/tablednd/jquery.tablednd.js new file mode 100644 index 00000000000..4a6923f1336 --- /dev/null +++ b/htdocs/includes/jquery/plugins/tablednd/jquery.tablednd.js @@ -0,0 +1,604 @@ +/** + * TableDnD plug-in for JQuery, allows you to drag and drop table rows + * You can set up various options to control how the system will work + * Copyright (c) Denis Howlett + * License: MIT. + * See https://github.com/isocra/TableDnD + */ + +/*jshint -W054 */ +/*jshint laxbreak: true */ +/*jshint expr: true */ + +!function ($, window, document, undefined) { +// Determine if this is a touch device +var hasTouch = 'ontouchstart' in document.documentElement, + startEvent = 'touchstart mousedown', + moveEvent = 'touchmove mousemove', + endEvent = 'touchend mouseup'; + +$(document).ready(function () { + function parseStyle(css) { + var objMap = {}, + parts = css.match(/([^;:]+)/g) || []; + while (parts.length) + objMap[parts.shift()] = parts.shift().trim(); + + return objMap; + } + $('table').each(function () { + if ($(this).data('table') === 'dnd') { + + $(this).tableDnD({ + onDragStyle: $(this).data('ondragstyle') && parseStyle($(this).data('ondragstyle')) || null, + onDropStyle: $(this).data('ondropstyle') && parseStyle($(this).data('ondropstyle')) || null, + onDragClass: $(this).data('ondragclass') === undefined && "tDnD_whileDrag" || $(this).data('ondragclass'), + onDrop: $(this).data('ondrop') && new Function('table', 'row', $(this).data('ondrop')), // 'return eval("'+$(this).data('ondrop')+'");') || null, + onDragStart: $(this).data('ondragstart') && new Function('table', 'row' ,$(this).data('ondragstart')), // 'return eval("'+$(this).data('ondragstart')+'");') || null, + onDragStop: $(this).data('ondragstop') && new Function('table', 'row' ,$(this).data('ondragstop')), + scrollAmount: $(this).data('scrollamount') || 5, + sensitivity: $(this).data('sensitivity') || 10, + hierarchyLevel: $(this).data('hierarchylevel') || 0, + indentArtifact: $(this).data('indentartifact') || '
     
    ', + autoWidthAdjust: $(this).data('autowidthadjust') || true, + autoCleanRelations: $(this).data('autocleanrelations') || true, + jsonPretifySeparator: $(this).data('jsonpretifyseparator') || '\t', + serializeRegexp: $(this).data('serializeregexp') && new RegExp($(this).data('serializeregexp')) || /[^\-]*$/, + serializeParamName: $(this).data('serializeparamname') || false, + dragHandle: $(this).data('draghandle') || null + }); + } + + + }); +}); + +jQuery.tableDnD = { + /** Keep hold of the current table being dragged */ + currentTable: null, + /** Keep hold of the current drag object if any */ + dragObject: null, + /** The current mouse offset */ + mouseOffset: null, + /** Remember the old value of X and Y so that we don't do too much processing */ + oldX: 0, + oldY: 0, + + /** Actually build the structure */ + build: function(options) { + // Set up the defaults if any + + this.each(function() { + // This is bound to each matching table, set up the defaults and override with user options + this.tableDnDConfig = $.extend({ + onDragStyle: null, + onDropStyle: null, + // Add in the default class for whileDragging + onDragClass: "tDnD_whileDrag", + onDrop: null, + onDragStart: null, + onDragStop: null, + scrollAmount: 5, + /** Sensitivity setting will throttle the trigger rate for movement detection */ + sensitivity: 10, + /** Hierarchy level to support parent child. 0 switches this functionality off */ + hierarchyLevel: 0, + /** The html artifact to prepend the first cell with as indentation */ + indentArtifact: '
     
    ', + /** Automatically adjust width of first cell */ + autoWidthAdjust: true, + /** Automatic clean-up to ensure relationship integrity */ + autoCleanRelations: true, + /** Specify a number (4) as number of spaces or any indent string for JSON.stringify */ + jsonPretifySeparator: '\t', + /** The regular expression to use to trim row IDs */ + serializeRegexp: /[^\-]*$/, + /** If you want to specify another parameter name instead of the table ID */ + serializeParamName: false, + /** If you give the name of a class here, then only Cells with this class will be draggable */ + dragHandle: null + }, options || {}); + + // Now make the rows draggable + $.tableDnD.makeDraggable(this); + // Prepare hierarchy support + this.tableDnDConfig.hierarchyLevel + && $.tableDnD.makeIndented(this); + }); + + // Don't break the chain + return this; + }, + makeIndented: function (table) { + var config = table.tableDnDConfig, + rows = table.rows, + firstCell = $(rows).first().find('td:first')[0], + indentLevel = 0, + cellWidth = 0, + longestCell, + tableStyle; + + if ($(table).hasClass('indtd')) + return null; + + tableStyle = $(table).addClass('indtd').attr('style'); + $(table).css({whiteSpace: "nowrap"}); + + for (var w = 0; w < rows.length; w++) { + if (cellWidth < $(rows[w]).find('td:first').text().length) { + cellWidth = $(rows[w]).find('td:first').text().length; + longestCell = w; + } + } + $(firstCell).css({width: 'auto'}); + for (w = 0; w < config.hierarchyLevel; w++) + $(rows[longestCell]).find('td:first').prepend(config.indentArtifact); + firstCell && $(firstCell).css({width: firstCell.offsetWidth}); + tableStyle && $(table).css(tableStyle); + + for (w = 0; w < config.hierarchyLevel; w++) + $(rows[longestCell]).find('td:first').children(':first').remove(); + + config.hierarchyLevel + && $(rows).each(function () { + indentLevel = $(this).data('level') || 0; + indentLevel <= config.hierarchyLevel + && $(this).data('level', indentLevel) + || $(this).data('level', 0); + for (var i = 0; i < $(this).data('level'); i++) + $(this).find('td:first').prepend(config.indentArtifact); + }); + + return this; + }, + /** This function makes all the rows on the table draggable apart from those marked as "NoDrag" */ + makeDraggable: function(table) { + var config = table.tableDnDConfig; + + config.dragHandle + // We only need to add the event to the specified cells + && $(config.dragHandle, table).each(function() { + // The cell is bound to "this" + $(this).bind(startEvent, function(e) { + $.tableDnD.initialiseDrag($(this).parents('tr')[0], table, this, e, config); + return false; + }); + }) + // For backwards compatibility, we add the event to the whole row + // get all the rows as a wrapped set + || $(table.rows).each(function() { + // Iterate through each row, the row is bound to "this" + if (! $(this).hasClass("nodrag")) { + $(this).bind(startEvent, function(e) { + if (e.target.tagName === "TD") { + $.tableDnD.initialiseDrag(this, table, this, e, config); + return false; + } + }).css("cursor", "move"); // Store the tableDnD object + } else { + $(this).css("cursor", ""); // Remove the cursor if we don't have the nodrag class + } + }); + }, + currentOrder: function() { + var rows = this.currentTable.rows; + return $.map(rows, function (val) { + return ($(val).data('level') + val.id).replace(/\s/g, ''); + }).join(''); + }, + initialiseDrag: function(dragObject, table, target, e, config) { + this.dragObject = dragObject; + this.currentTable = table; + this.mouseOffset = this.getMouseOffset(target, e); + this.originalOrder = this.currentOrder(); + + // Now we need to capture the mouse up and mouse move event + // We can use bind so that we don't interfere with other event handlers + $(document) + .bind(moveEvent, this.mousemove) + .bind(endEvent, this.mouseup); + + // Call the onDragStart method if there is one + config.onDragStart + && config.onDragStart(table, target); + }, + updateTables: function() { + this.each(function() { + // this is now bound to each matching table + if (this.tableDnDConfig) + $.tableDnD.makeDraggable(this); + }); + }, + /** Get the mouse coordinates from the event (allowing for browser differences) */ + mouseCoords: function(e) { + if (e.originalEvent.changedTouches) + return { + x: e.originalEvent.changedTouches[0].clientX, + y: e.originalEvent.changedTouches[0].clientY + }; + + if(e.pageX || e.pageY) + return { + x: e.pageX, + y: e.pageY + }; + + return { + x: e.clientX + document.body.scrollLeft - document.body.clientLeft, + y: e.clientY + document.body.scrollTop - document.body.clientTop + }; + }, + /** Given a target element and a mouse eent, get the mouse offset from that element. + To do this we need the element's position and the mouse position */ + getMouseOffset: function(target, e) { + var mousePos, + docPos; + + e = e || window.event; + + docPos = this.getPosition(target); + mousePos = this.mouseCoords(e); + + return { + x: mousePos.x - docPos.x, + y: mousePos.y - docPos.y + }; + }, + /** Get the position of an element by going up the DOM tree and adding up all the offsets */ + getPosition: function(element) { + var left = 0, + top = 0; + + // Safari fix -- thanks to Luis Chato for this! + // Safari 2 doesn't correctly grab the offsetTop of a table row + // this is detailed here: + // http://jacob.peargrove.com/blog/2006/technical/table-row-offsettop-bug-in-safari/ + // the solution is likewise noted there, grab the offset of a table cell in the row - the firstChild. + // note that firefox will return a text node as a first child, so designing a more thorough + // solution may need to take that into account, for now this seems to work in firefox, safari, ie + if (element.offsetHeight === 0) + element = element.firstChild; // a table cell + + while (element.offsetParent) { + left += element.offsetLeft; + top += element.offsetTop; + element = element.offsetParent; + } + + left += element.offsetLeft; + top += element.offsetTop; + + return { + x: left, + y: top + }; + }, + autoScroll: function (mousePos) { + var config = this.currentTable.tableDnDConfig, + yOffset = window.pageYOffset, + windowHeight = window.innerHeight + ? window.innerHeight + : document.documentElement.clientHeight + ? document.documentElement.clientHeight + : document.body.clientHeight; + + // Windows version + // yOffset=document.body.scrollTop; + if (document.all) + if (typeof document.compatMode !== 'undefined' + && document.compatMode !== 'BackCompat') + yOffset = document.documentElement.scrollTop; + else if (typeof document.body !== 'undefined') + yOffset = document.body.scrollTop; + + mousePos.y - yOffset < config.scrollAmount + && window.scrollBy(0, - config.scrollAmount) + || windowHeight - (mousePos.y - yOffset) < config.scrollAmount + && window.scrollBy(0, config.scrollAmount); + + }, + moveVerticle: function (moving, currentRow) { + + if (0 !== moving.vertical + // If we're over a row then move the dragged row to there so that the user sees the + // effect dynamically + && currentRow + && this.dragObject !== currentRow + && this.dragObject.parentNode === currentRow.parentNode) + 0 > moving.vertical + && this.dragObject.parentNode.insertBefore(this.dragObject, currentRow.nextSibling) + || 0 < moving.vertical + && this.dragObject.parentNode.insertBefore(this.dragObject, currentRow); + + }, + moveHorizontal: function (moving, currentRow) { + var config = this.currentTable.tableDnDConfig, + currentLevel; + + if (!config.hierarchyLevel + || 0 === moving.horizontal + // We only care if moving left or right on the current row + || !currentRow + || this.dragObject !== currentRow) + return null; + + currentLevel = $(currentRow).data('level'); + + 0 < moving.horizontal + && currentLevel > 0 + && $(currentRow).find('td:first').children(':first').remove() + && $(currentRow).data('level', --currentLevel); + + 0 > moving.horizontal + && currentLevel < config.hierarchyLevel + && $(currentRow).prev().data('level') >= currentLevel + && $(currentRow).children(':first').prepend(config.indentArtifact) + && $(currentRow).data('level', ++currentLevel); + + }, + mousemove: function(e) { + var dragObj = $($.tableDnD.dragObject), + config = $.tableDnD.currentTable.tableDnDConfig, + currentRow, + mousePos, + moving, + x, + y; + + e && e.preventDefault(); + + if (!$.tableDnD.dragObject) + return false; + + // prevent touch device screen scrolling + e.type === 'touchmove' + && event.preventDefault(); // TODO verify this is event and not really e + + // update the style to show we're dragging + config.onDragClass + && dragObj.addClass(config.onDragClass) + || dragObj.css(config.onDragStyle); + + mousePos = $.tableDnD.mouseCoords(e); + x = mousePos.x - $.tableDnD.mouseOffset.x; + y = mousePos.y - $.tableDnD.mouseOffset.y; + + // auto scroll the window + $.tableDnD.autoScroll(mousePos); + + currentRow = $.tableDnD.findDropTargetRow(dragObj, y); + moving = $.tableDnD.findDragDirection(x, y); + + $.tableDnD.moveVerticle(moving, currentRow); + $.tableDnD.moveHorizontal(moving, currentRow); + + return false; + }, + findDragDirection: function (x,y) { + var sensitivity = this.currentTable.tableDnDConfig.sensitivity, + oldX = this.oldX, + oldY = this.oldY, + xMin = oldX - sensitivity, + xMax = oldX + sensitivity, + yMin = oldY - sensitivity, + yMax = oldY + sensitivity, + moving = { + horizontal: x >= xMin && x <= xMax ? 0 : x > oldX ? -1 : 1, + vertical : y >= yMin && y <= yMax ? 0 : y > oldY ? -1 : 1 + }; + + // update the old value + if (moving.horizontal !== 0) + this.oldX = x; + if (moving.vertical !== 0) + this.oldY = y; + + return moving; + }, + /** We're only worried about the y position really, because we can only move rows up and down */ + findDropTargetRow: function(draggedRow, y) { + var rowHeight = 0, + rows = this.currentTable.rows, + config = this.currentTable.tableDnDConfig, + rowY = 0, + row = null; + + for (var i = 0; i < rows.length; i++) { + row = rows[i]; + rowY = this.getPosition(row).y; + rowHeight = parseInt(row.offsetHeight) / 2; + if (row.offsetHeight === 0) { + rowY = this.getPosition(row.firstChild).y; + rowHeight = parseInt(row.firstChild.offsetHeight) / 2; + } + // Because we always have to insert before, we need to offset the height a bit + if (y > (rowY - rowHeight) && y < (rowY + rowHeight)) + // that's the row we're over + // If it's the same as the current row, ignore it + if (draggedRow.is(row) + || (config.onAllowDrop + && !config.onAllowDrop(draggedRow, row)) + // If a row has nodrop class, then don't allow dropping (inspired by John Tarr and Famic) + || $(row).hasClass("nodrop")) + return null; + else + return row; + } + return null; + }, + processMouseup: function() { + if (!this.currentTable || !this.dragObject) + return null; + + var config = this.currentTable.tableDnDConfig, + droppedRow = this.dragObject, + parentLevel = 0, + myLevel = 0; + + // Unbind the event handlers + $(document) + .unbind(moveEvent, this.mousemove) + .unbind(endEvent, this.mouseup); + + config.hierarchyLevel + && config.autoCleanRelations + && $(this.currentTable.rows).first().find('td:first').children().each(function () { + myLevel = $(this).parents('tr:first').data('level'); + myLevel + && $(this).parents('tr:first').data('level', --myLevel) + && $(this).remove(); + }) + && config.hierarchyLevel > 1 + && $(this.currentTable.rows).each(function () { + myLevel = $(this).data('level'); + if (myLevel > 1) { + parentLevel = $(this).prev().data('level'); + while (myLevel > parentLevel + 1) { + $(this).find('td:first').children(':first').remove(); + $(this).data('level', --myLevel); + } + } + }); + + // If we have a dragObject, then we need to release it, + // The row will already have been moved to the right place so we just reset stuff + config.onDragClass + && $(droppedRow).removeClass(config.onDragClass) + || $(droppedRow).css(config.onDropStyle); + + this.dragObject = null; + // Call the onDrop method if there is one + config.onDrop + && this.originalOrder !== this.currentOrder() + && $(droppedRow).hide().fadeIn('fast') + && config.onDrop(this.currentTable, droppedRow); + + // Call the onDragStop method if there is one + config.onDragStop + && config.onDragStop(this.currentTable, droppedRow); + + this.currentTable = null; // let go of the table too + }, + mouseup: function(e) { + e && e.preventDefault(); + $.tableDnD.processMouseup(); + return false; + }, + jsonize: function(pretify) { + var table = this.currentTable; + if (pretify) + return JSON.stringify( + this.tableData(table), + null, + table.tableDnDConfig.jsonPretifySeparator + ); + return JSON.stringify(this.tableData(table)); + }, + serialize: function() { + return $.param(this.tableData(this.currentTable)); + }, + serializeTable: function(table) { + var result = ""; + var paramName = table.tableDnDConfig.serializeParamName || table.id; + var rows = table.rows; + for (var i=0; i 0) result += "&"; + var rowId = rows[i].id; + if (rowId && table.tableDnDConfig && table.tableDnDConfig.serializeRegexp) { + rowId = rowId.match(table.tableDnDConfig.serializeRegexp)[0]; + result += paramName + '[]=' + rowId; + } + } + return result; + }, + serializeTables: function() { + var result = []; + $('table').each(function() { + this.id && result.push($.param($.tableDnD.tableData(this))); + }); + return result.join('&'); + }, + tableData: function (table) { + var config = table.tableDnDConfig, + previousIDs = [], + currentLevel = 0, + indentLevel = 0, + rowID = null, + data = {}, + getSerializeRegexp, + paramName, + currentID, + rows; + + if (!table) + table = this.currentTable; + if (!table || !table.rows || !table.rows.length) + return {error: { code: 500, message: "Not a valid table."}}; + if (!table.id && !config.serializeParamName) + return {error: { code: 500, message: "No serializable unique id provided."}}; + + rows = config.autoCleanRelations + && table.rows + || $.makeArray(table.rows); + paramName = config.serializeParamName || table.id; + currentID = paramName; + + getSerializeRegexp = function (rowId) { + if (rowId && config && config.serializeRegexp) + return rowId.match(config.serializeRegexp)[0]; + return rowId; + }; + + data[currentID] = []; + !config.autoCleanRelations + && $(rows[0]).data('level') + && rows.unshift({id: 'undefined'}); + + + + for (var i=0; i < rows.length; i++) { + if (config.hierarchyLevel) { + indentLevel = $(rows[i]).data('level') || 0; + if (indentLevel === 0) { + currentID = paramName; + previousIDs = []; + } + else if (indentLevel > currentLevel) { + previousIDs.push([currentID, currentLevel]); + currentID = getSerializeRegexp(rows[i-1].id); + } + else if (indentLevel < currentLevel) { + for (var h = 0; h < previousIDs.length; h++) { + if (previousIDs[h][1] === indentLevel) + currentID = previousIDs[h][0]; + if (previousIDs[h][1] >= currentLevel) + previousIDs[h][1] = 0; + } + } + currentLevel = indentLevel; + + if (!$.isArray(data[currentID])) + data[currentID] = []; + rowID = getSerializeRegexp(rows[i].id); + rowID && data[currentID].push(rowID); + } + else { + rowID = getSerializeRegexp(rows[i].id); + rowID && data[currentID].push(rowID); + } + } + return data; + } +}; + +jQuery.fn.extend( + { + tableDnD : $.tableDnD.build, + tableDnDUpdate : $.tableDnD.updateTables, + tableDnDSerialize : $.proxy($.tableDnD.serialize, $.tableDnD), + tableDnDSerializeAll : $.tableDnD.serializeTables, + tableDnDData : $.proxy($.tableDnD.tableData, $.tableDnD) + } +); + +}(jQuery, window, window.document); diff --git a/htdocs/includes/jquery/plugins/tablednd/jquery.tablednd.min.js b/htdocs/includes/jquery/plugins/tablednd/jquery.tablednd.min.js new file mode 100644 index 00000000000..c07ff347456 --- /dev/null +++ b/htdocs/includes/jquery/plugins/tablednd/jquery.tablednd.min.js @@ -0,0 +1,2 @@ +/*! jquery.tablednd.js 19-11-2017 */ +!function(a,b,c,d){var e=("ontouchstart"in c.documentElement,"touchstart mousedown"),f="touchmove mousemove",g="touchend mouseup";a(c).ready(function(){function b(a){for(var b={},c=a.match(/([^;:]+)/g)||[];c.length;)b[c.shift()]=c.shift().trim();return b}a("table").each(function(){"dnd"==a(this).data("table")&&a(this).tableDnD({onDragStyle:a(this).data("ondragstyle")&&b(a(this).data("ondragstyle"))||null,onDropStyle:a(this).data("ondropstyle")&&b(a(this).data("ondropstyle"))||null,onDragClass:a(this).data("ondragclass")===d&&"tDnD_whileDrag"||a(this).data("ondragclass"),onDrop:a(this).data("ondrop")&&new Function("table","row",a(this).data("ondrop")),onDragStart:a(this).data("ondragstart")&&new Function("table","row",a(this).data("ondragstart")),onDragStop:a(this).data("ondragstop")&&new Function("table","row",a(this).data("ondragstop")),scrollAmount:a(this).data("scrollamount")||5,sensitivity:a(this).data("sensitivity")||10,hierarchyLevel:a(this).data("hierarchylevel")||0,indentArtifact:a(this).data("indentartifact")||'
     
    ',autoWidthAdjust:a(this).data("autowidthadjust")||!0,autoCleanRelations:a(this).data("autocleanrelations")||!0,jsonPretifySeparator:a(this).data("jsonpretifyseparator")||" ",serializeRegexp:a(this).data("serializeregexp")&&new RegExp(a(this).data("serializeregexp"))||/[^\-]*$/,serializeParamName:a(this).data("serializeparamname")||!1,dragHandle:a(this).data("draghandle")||null})})}),jQuery.tableDnD={currentTable:null,dragObject:null,mouseOffset:null,oldX:0,oldY:0,build:function(b){return this.each(function(){this.tableDnDConfig=a.extend({onDragStyle:null,onDropStyle:null,onDragClass:"tDnD_whileDrag",onDrop:null,onDragStart:null,onDragStop:null,scrollAmount:5,sensitivity:10,hierarchyLevel:0,indentArtifact:'
     
    ',autoWidthAdjust:!0,autoCleanRelations:!0,jsonPretifySeparator:" ",serializeRegexp:/[^\-]*$/,serializeParamName:!1,dragHandle:null},b||{}),a.tableDnD.makeDraggable(this),this.tableDnDConfig.hierarchyLevel&&a.tableDnD.makeIndented(this)}),this},makeIndented:function(b){var c,d,e=b.tableDnDConfig,f=b.rows,g=a(f).first().find("td:first")[0],h=0,i=0;if(a(b).hasClass("indtd"))return null;d=a(b).addClass("indtd").attr("style"),a(b).css({whiteSpace:"nowrap"});for(var j=0;ja.vertical&&this.dragObject.parentNode.insertBefore(this.dragObject,b.nextSibling)||00&&a(c).find("td:first").children(":first").remove()&&a(c).data("level",--d),void(0>b.horizontal&&d=d&&a(c).children(":first").prepend(e.indentArtifact)&&a(c).data("level",++d))):null},mousemove:function(b){var c,d,e,f,g,h=a(a.tableDnD.dragObject),i=a.tableDnD.currentTable.tableDnDConfig;return b&&b.preventDefault(),a.tableDnD.dragObject?("touchmove"===b.type&&event.preventDefault(),i.onDragClass&&h.addClass(i.onDragClass)||h.css(i.onDragStyle),d=a.tableDnD.mouseCoords(b),f=d.x-a.tableDnD.mouseOffset.x,g=d.y-a.tableDnD.mouseOffset.y,a.tableDnD.autoScroll(d),c=a.tableDnD.findDropTargetRow(h,g),e=a.tableDnD.findDragDirection(f,g),a.tableDnD.moveVerticle(e,c),a.tableDnD.moveHorizontal(e,c),!1):!1},findDragDirection:function(a,b){var c=this.currentTable.tableDnDConfig.sensitivity,d=this.oldX,e=this.oldY,f=d-c,g=d+c,h=e-c,i=e+c,j={horizontal:a>=f&&g>=a?0:a>d?-1:1,vertical:b>=h&&i>=b?0:b>e?-1:1};return 0!==j.horizontal&&(this.oldX=a),0!==j.vertical&&(this.oldY=b),j},findDropTargetRow:function(b,c){for(var d=0,e=this.currentTable.rows,f=this.currentTable.tableDnDConfig,g=0,h=null,i=0;ig-d&&g+d>c)return b.is(h)||f.onAllowDrop&&!f.onAllowDrop(b,h)||a(h).hasClass("nodrop")?null:h;return null},processMouseup:function(){if(!this.currentTable||!this.dragObject)return null;var b=this.currentTable.tableDnDConfig,d=this.dragObject,e=0,h=0;a(c).unbind(f,this.mousemove).unbind(g,this.mouseup),b.hierarchyLevel&&b.autoCleanRelations&&a(this.currentTable.rows).first().find("td:first").children().each(function(){h=a(this).parents("tr:first").data("level"),h&&a(this).parents("tr:first").data("level",--h)&&a(this).remove()})&&b.hierarchyLevel>1&&a(this.currentTable.rows).each(function(){if(h=a(this).data("level"),h>1)for(e=a(this).prev().data("level");h>e+1;)a(this).find("td:first").children(":first").remove(),a(this).data("level",--h)}),b.onDragClass&&a(d).removeClass(b.onDragClass)||a(d).css(b.onDropStyle),this.dragObject=null,b.onDrop&&this.originalOrder!==this.currentOrder()&&a(d).hide().fadeIn("fast")&&b.onDrop(this.currentTable,d),b.onDragStop&&b.onDragStop(this.currentTable,d),this.currentTable=null},mouseup:function(b){return b&&b.preventDefault(),a.tableDnD.processMouseup(),!1},jsonize:function(a){var b=this.currentTable;return a?JSON.stringify(this.tableData(b),null,b.tableDnDConfig.jsonPretifySeparator):JSON.stringify(this.tableData(b))},serialize:function(){return a.param(this.tableData(this.currentTable))},serializeTable:function(a){for(var b="",c=a.tableDnDConfig.serializeParamName||a.id,d=a.rows,e=0;e0&&(b+="&");var f=d[e].id;f&&a.tableDnDConfig&&a.tableDnDConfig.serializeRegexp&&(f=f.match(a.tableDnDConfig.serializeRegexp)[0],b+=c+"[]="+f)}return b},serializeTables:function(){var b=[];return a("table").each(function(){this.id&&b.push(a.param(a.tableDnD.tableData(this)))}),b.join("&")},tableData:function(b){var c,d,e,f,g=b.tableDnDConfig,h=[],i=0,j=0,k=null,l={};if(b||(b=this.currentTable),!b||!b.rows||!b.rows.length)return{error:{code:500,message:"Not a valid table."}};if(!b.id&&!g.serializeParamName)return{error:{code:500,message:"No serializable unique id provided."}};f=g.autoCleanRelations&&b.rows||a.makeArray(b.rows),d=g.serializeParamName||b.id,e=d,c=function(a){return a&&g&&g.serializeRegexp?a.match(g.serializeRegexp)[0]:a},l[e]=[],!g.autoCleanRelations&&a(f[0]).data("level")&&f.unshift({id:"undefined"});for(var m=0;mi)h.push([e,i]),e=c(f[m-1].id);else if(i>j)for(var n=0;n=i&&(h[n][1]=0);i=j,a.isArray(l[e])||(l[e]=[]),k=c(f[m].id),k&&l[e].push(k)}else k=c(f[m].id),k&&l[e].push(k);return l}},jQuery.fn.extend({tableDnD:a.tableDnD.build,tableDnDUpdate:a.tableDnD.updateTables,tableDnDSerialize:a.proxy(a.tableDnD.serialize,a.tableDnD),tableDnDSerializeAll:a.tableDnD.serializeTables,tableDnDData:a.proxy(a.tableDnD.tableData,a.tableDnD)})}(jQuery,window,window.document); \ No newline at end of file diff --git a/htdocs/includes/nusoap/lib/nusoap.php b/htdocs/includes/nusoap/lib/nusoap.php index 56d1cf4c1a8..6bd651e512c 100644 --- a/htdocs/includes/nusoap/lib/nusoap.php +++ b/htdocs/includes/nusoap/lib/nusoap.php @@ -6374,7 +6374,9 @@ class wsdl extends nusoap_base { $elements = $eElements; } - if (count($attrs) > 0) { + // @CHANGE LDR FIX for PHP7.2 + //if (count($attrs) > 0) { + if (is_array($attrs) && count($attrs) > 0) { foreach($attrs as $n => $a){ // expand each attribute foreach ($a as $k => $v) { diff --git a/htdocs/includes/odtphp/Segment.php b/htdocs/includes/odtphp/Segment.php index f9a44b996b2..8cea06db50b 100644 --- a/htdocs/includes/odtphp/Segment.php +++ b/htdocs/includes/odtphp/Segment.php @@ -173,19 +173,20 @@ class Segment implements IteratorAggregate, Countable */ public function macroReplace($text) { + include_once DOL_DOCUMENT_ROOT.'/core/lib/date.lib.php'; global $langs; $hoy = dol_getdate(dol_now('tzuser')); $dateinonemontharray = dol_get_next_month($hoy['mon'], $hoy['year']); $nextMonth = $dateinonemontharray['month']; - + $patterns=array( '/__CURRENTDAY__/u','/__CURENTWEEKDAY__/u', '/__CURRENTMONTH__/u','/__CURRENTMONTHLONG__/u', '/__NEXTMONTH__/u','/__NEXTMONTHLONG__/u', '/__CURRENTYEAR__/u','/__NEXTYEAR__/u' ); - $values=array( $hoy['mday'], $langs->transnoentitiesnoconv($hoy['weekday']), - $hoy['mon'], $langs->transnoentitiesnoconv($hoy['month']), - $nextMonth, monthArray($langs)[$nextMonth], + $values=array( $hoy['mday'], $langs->transnoentitiesnoconv($hoy['weekday']), + $hoy['mon'], $langs->transnoentitiesnoconv($hoy['month']), + $nextMonth, monthArray($langs)[$nextMonth], $hoy['year'], $hoy['year']+1 ); $text=preg_replace($patterns, $values, $text); diff --git a/htdocs/includes/parsedown/Parsedown.php b/htdocs/includes/parsedown/Parsedown.php index 20863a7537a..a1ec563683f 100644 --- a/htdocs/includes/parsedown/Parsedown.php +++ b/htdocs/includes/parsedown/Parsedown.php @@ -141,7 +141,11 @@ class Parsedown foreach ($parts as $part) { - $shortage = 4 - mb_strlen($line, 'utf-8') % 4; + // @CHANGE LDR Fix when mb_strlen is not available + //$shortage = 4 - mb_strlen($line, 'utf-8') % 4; + if (function_exists('mb_strlen')) $len = mb_strlen($line, 'utf-8'); + else $len = strlen($line); + $shortage = 4 - $len % 4; $line .= str_repeat(' ', $shortage); $line .= $part; @@ -515,10 +519,10 @@ class Parsedown ), ); - if($name === 'ol') + if($name === 'ol') { $listStart = stristr($matches[0], '.', true); - + if($listStart !== '1') { $Block['element']['attributes'] = array('start' => $listStart); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php b/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php index 20a33ee3b70..300eadb0f70 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/AutoLoader.php @@ -307,10 +307,10 @@ class AutoLoader */ private function alias($className, $currentClass) { - // @CHANGE LDR + // @CHANGE LDR if ($className == 'Luracast\Restler\string') return; if ($className == 'Luracast\Restler\mixed') return; - + if ($className != $currentClass && false !== strpos($className, $currentClass)) if (!class_exists($currentClass, false) diff --git a/htdocs/includes/restler/framework/Luracast/Restler/CommentParser.php b/htdocs/includes/restler/framework/Luracast/Restler/CommentParser.php index 8a3023cab20..e8248a385fa 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/CommentParser.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/CommentParser.php @@ -505,7 +505,7 @@ class CommentParser $data = explode('|', $data); $r['type'] = count($data) == 1 ? $data[0] : $data; } - if (isset($r['type']) && is_string($r['type']) && Text::endsWith($r['type'], '[]')) { + if (isset($r['type']) && Text::endsWith($r['type'], '[]')) { $r[static::$embeddedDataName]['type'] = substr($r['type'], 0, -2); $r['type'] = 'array'; } diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Data/Object.php b/htdocs/includes/restler/framework/Luracast/Restler/Data/Obj.php similarity index 99% rename from htdocs/includes/restler/framework/Luracast/Restler/Data/Object.php rename to htdocs/includes/restler/framework/Luracast/Restler/Data/Obj.php index 5ef5850b86e..003f1df8794 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Data/Object.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Data/Obj.php @@ -13,7 +13,7 @@ namespace Luracast\Restler\Data; * @link http://luracast.com/products/restler/ * @version 3.0.0rc6 */ -class Object +class Obj { /** * @var bool|string|callable diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Data/Validator.php b/htdocs/includes/restler/framework/Luracast/Restler/Data/Validator.php index be2ef28f40a..28202efb7ad 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Data/Validator.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Data/Validator.php @@ -454,7 +454,10 @@ class Validator implements iValidate } if (isset ($info->choice)) { - if (is_array($input)) { + if (!$info->required && empty($input)) { + //since its optional, and empty let it pass. + $input = null; + } elseif (is_array($input)) { foreach ($input as $i) { if (!in_array($i, $info->choice)) { $error .= ". Expected one of (" . implode(',', $info->choice) . ")."; @@ -468,6 +471,11 @@ class Validator implements iValidate } if (method_exists($class = get_called_class(), $info->type) && $info->type != 'validate') { + if(!$info->required && empty($input)) + { + //optional parameter with a empty value assume null + return null; + } try { return call_user_func("$class::$info->type", $input, $info); } catch (Invalid $e) { @@ -669,4 +677,4 @@ class Validator implements iValidate throw $e; } } -} \ No newline at end of file +} diff --git a/htdocs/includes/restler/framework/Luracast/Restler/EventDispatcher.php b/htdocs/includes/restler/framework/Luracast/Restler/EventDispatcher.php index 1c173d38baa..f8cd883af46 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/EventDispatcher.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/EventDispatcher.php @@ -44,7 +44,7 @@ class EventDispatcher public function __call($eventName, $params) { if (0 === strpos($eventName, 'on')) { - if (!@is_array($this->listeners[$eventName])) + if (!isset($this->listeners[$eventName]) || !is_array($this->listeners[$eventName])) $this->listeners[$eventName] = array(); $this->listeners[$eventName][] = $params[0]; } diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Explorer.php b/htdocs/includes/restler/framework/Luracast/Restler/Explorer.php index 9522441c5b0..686c4c2fc23 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Explorer.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Explorer.php @@ -16,7 +16,12 @@ use Luracast\Restler\Scope; */ class Explorer implements iProvideMultiVersionApi { - const SWAGGER_VERSION = '1.2'; + const SWAGGER = '2.0'; + + /** + * @var array http schemes supported. http or https or both http and https + */ + public static $schemes = array(); /** * @var bool should protected resources be shown to unauthenticated users? */ @@ -70,17 +75,17 @@ class Explorer implements iProvideMultiVersionApi */ public static $dataTypeAlias = array( //'string' => 'string', - 'int' => 'integer', - 'number' => 'number', - 'float' => array('number', 'float'), - 'bool' => 'boolean', + 'int' => 'integer', + 'number' => 'number', + 'float' => array('number', 'float'), + 'bool' => 'boolean', //'boolean' => 'boolean', //'NULL' => 'null', - 'array' => 'array', + 'array' => 'array', //'object' => 'object', 'stdClass' => 'object', - 'mixed' => 'string', - 'date' => array('string', 'date'), + 'mixed' => 'string', + 'date' => array('string', 'date'), 'datetime' => array('string', 'date-time'), ); @@ -89,9 +94,9 @@ class Explorer implements iProvideMultiVersionApi * protected api */ public static $apiDescriptionSuffixSymbols = array( - 0 => '  ', //public api - 1 => '  ', //hybrid api - 2 => '  ', //protected api + 0 => ' 🔓', //'  ', //public api + 1 => ' ◑', //'  ', //hybrid api + 2 => ' 🔐', //'  ', //protected api ); protected $models = array(); @@ -100,27 +105,23 @@ class Explorer implements iProvideMultiVersionApi */ protected $_fullDataRequested = false; protected $crud = array( - 'POST' => 'create', - 'GET' => 'retrieve', - 'PUT' => 'update', + 'POST' => 'create', + 'GET' => 'retrieve', + 'PUT' => 'update', 'DELETE' => 'delete', - 'PATCH' => 'partial update' + 'PATCH' => 'partial update' ); protected static $prefixes = array( - 'get' => 'retrieve', - 'index' => 'list', - 'post' => 'create', - 'put' => 'update', - 'patch' => 'modify', + 'get' => 'retrieve', + 'index' => 'list', + 'post' => 'create', + 'put' => 'update', + 'patch' => 'modify', 'delete' => 'remove', ); protected $_authenticated = false; protected $cacheName = ''; - public function __construct() - { - - } /** * Serve static files for exploring @@ -131,7 +132,7 @@ class Explorer implements iProvideMultiVersionApi */ public function get() { - if (func_num_args() > 1 && func_get_arg(0) == 'resources') { + if (func_num_args() > 1 && func_get_arg(0) == 'swagger') { /** * BUGFIX: * If we use common resourcePath (e.g. $r->addAPIClass([api-class], 'api/shop')), than we must determine resource-ID of e.g. 'api/shop'! @@ -141,6 +142,7 @@ class Explorer implements iProvideMultiVersionApi array_shift($arguments); // create ID $id = implode('/', $arguments); + return $this->getResources($id); } $filename = implode('/', func_get_args()); @@ -161,125 +163,75 @@ class Explorer implements iProvideMultiVersionApi ) { $filename .= '.js'; } - PassThrough::file(__DIR__ . '/explorer/' . (empty($filename) ? 'index.html' : $filename), false, 0); //60 * 60 * 24); + PassThrough::file(__DIR__ . '/explorer/' . (empty($filename) ? 'index.html' : $filename), false, + 0); //60 * 60 * 24); } - public function resources() + /** + * @return stdClass + */ + public function swagger() { $r = new stdClass(); - $r->apiVersion = (string)$this->restler->getRequestedApiVersion(); - $r->swaggerVersion = static::SWAGGER_VERSION; - $r->apis = $this->apis($r->apiVersion); - $r->authorizations = $this->authorizations(); - $r->info = array_filter(get_class_vars(static::$infoClass)); - return $r; - } + $version = (string)$this->restler->getRequestedApiVersion(); + $r->swagger = static::SWAGGER; - public function getResources($id) - { - $r = new stdClass(); - $r->apiVersion = (string)$this->restler->getRequestedApiVersion(); - $r->swaggerVersion = static::SWAGGER_VERSION; - $r->basePath = $this->restler->getBaseUrl(); - $r->resourcePath = "/$id"; - - $r->apis = $this->apis($r->apiVersion, $id); - $r->models = (object)$this->models; + $info = parse_url($this->restler->getBaseUrl()); + $r->host = $info['host']; + if (isset($info['port'])) { + $r->host .= ':' . $info['port']; + } + $r->basePath = isset($info['path']) ? $info['path'] : ''; + if (!empty(static::$schemes)) { + $r->schemes = static::$schemes; + } $r->produces = $this->restler->getWritableMimeTypes(); $r->consumes = $this->restler->getReadableMimeTypes(); - $r->authorizations = $this->authorizations(); + + $r->paths = $this->paths($version); + $r->definitions = (object)$this->models; + $r->securityDefinitions = $this->securityDefinitions(); + $r->info = compact('version') + array_filter(get_class_vars(static::$infoClass)); + return $r; } - private function apis($version = 1, $resource = false) + private function paths($version = 1) { $map = Routes::findAll(static::$excludedPaths + array($this->base()), static::$excludedHttpMethods, $version); - $r = array(); - $a = array(); + $paths = array(); foreach ($map as $path => $data) { - $route = $data[0]['route']; $access = $data[0]['access']; - if ($access && !Text::contains($path, '{')) { - $r[] = array( - 'path' => empty($path) ? '/root' : "/$path", - //'description' => '' - //TODO: Util::nestedValue($route, 'metadata', 'classDescription') ? : '' - ); - } - if (static::$hideProtected && !$access) + if (static::$hideProtected && !$access) { continue; - $grouper = array(); + } foreach ($data as $item) { $route = $item['route']; $access = $item['access']; - if (static::$hideProtected && !$access) + if (static::$hideProtected && !$access) { continue; + } $url = $route['url']; - if (isset($grouper[$url])) { - $grouper[$url]['operations'][] = $this->operation($route); - } else { - $api = array( - 'path' => "/$url", - 'description' => - Util::nestedValue($route, 'metadata', 'classDescription') ? : '', - 'operations' => array($this->operation($route)) - ); - static::$groupOperations - ? $grouper[$url] = $api - : $a[$path][] = $api; - } + $paths["/$url"][strtolower($route['httpMethod'])] = $this->operation($route); } - if (!empty($grouper)) { - $a[$path] = array_values($grouper); - // sort REST-endpoints by path - foreach ($a as & $b) { - usort( - $b, - function ($x, $y) { - return $x['path'] > $y['path']; - } - ); - } - } else { - $order = array( - 'GET' => 1, - 'POST' => 2, - 'PUT' => 3, - 'PATCH' => 4, - 'DELETE' => 5 - ); - foreach ($a as & $b) { - usort( - $b, - function ($x, $y) use ($order) { - return - $x['operations'][0]->method == - $y['operations'][0]->method - ? $x['path'] > $y['path'] - : $order[$x['operations'][0]->method] > - $order[$y['operations'][0]->method]; + } - } - ); - } - } - } - if (false !== $resource) { - if ($resource == 'root') $resource = ''; - if (isset($a[$resource])) return $a[$resource]; - } - return $r; + return $paths; } private function operation($route) { $r = new stdClass(); - $r->method = $route['httpMethod']; - $r->nickname = $this->nickname($route); + $m = $route['metadata']; + $r->operationId = $this->operationId($route); + $base = strtok($route['url'], '/'); + if (empty($base)) { + $base = 'root'; + } + $r->tags = array($base); $r->parameters = $this->parameters($route); - $m = $route['metadata']; $r->summary = isset($m['description']) ? $m['description'] @@ -287,13 +239,18 @@ class Explorer implements iProvideMultiVersionApi $r->summary .= $route['accessLevel'] > 2 ? static::$apiDescriptionSuffixSymbols[2] : static::$apiDescriptionSuffixSymbols[$route['accessLevel']]; - $r->notes = isset($m['longDescription']) + $r->description = isset($m['longDescription']) ? $m['longDescription'] : ''; - $r->responseMessages = $this->responseMessages($route); + $r->responses = $this->responses($route); + //TODO: avoid hard coding. Properly detect security + if ($route['accessLevel']) { + $r->security = array(array('api_key' => array())); + } + /* $this->setType( $r, - new ValidationInfo(Util::nestedValue($m, 'return') ? : array()) + new ValidationInfo(Util::nestedValue($m, 'return') ?: array()) ); if (is_null($r->type) || 'mixed' == $r->type) { $r->type = 'array'; @@ -302,7 +259,7 @@ class Explorer implements iProvideMultiVersionApi } elseif (Text::contains($r->type, '|')) { $r->type = 'array'; } - + */ //TODO: add $r->authorizations //A list of authorizations required to execute this operation. While not mandatory, if used, it overrides //the value given at the API Declaration's authorizations. In order to completely remove API Declaration's @@ -324,8 +281,9 @@ class Explorer implements iProvideMultiVersionApi $info = new ValidationInfo($param); $description = isset($param['description']) ? $param['description'] : ''; if ('body' == $info->from) { - if ($info->required) + if ($info->required) { $required = true; + } $param['description'] = $description; $children[] = $param; } else { @@ -341,31 +299,31 @@ class Explorer implements iProvideMultiVersionApi if (empty($firstChild['children'])) { $description = $firstChild['description']; } else { - $description = '
    '; + $description = ''; //'
    '; foreach ($firstChild['children'] as $child) { $description .= isset($child['required']) && $child['required'] - ? '' . $child['name'] . ' (required)
    ' - : $child['name'] . '
    '; + ? '**' . $child['name'] . '** (required) '.PHP_EOL + : $child['name'] . ' '.PHP_EOL; } - $description .= '
    '; + //$description .= '
    '; } $r[] = $this->parameter(new ValidationInfo($firstChild), $description); } else { - $description = '
    '; + $description = ''; //'
    '; foreach ($children as $child) { - $description .= isset($child['required']) && $child['required'] - ? '' . $child['name'] . ' (required)
    ' - : $child['name'] . '
    '; + $description .= isset($child['required']) && $child['required'] + ? '**' . $child['name'] . '** (required) '.PHP_EOL + : $child['name'] . ' '.PHP_EOL; } - $description .= '
    '; + //$description .= '
    '; //lets group all body parameters under a generated model name - $name = $this->nameModel($route); + $name = $this->modelName($route); $r[] = $this->parameter( new ValidationInfo(array( - 'name' => $name, - 'type' => $name, - 'from' => 'body', + 'name' => $name, + 'type' => $name, + 'from' => 'body', 'required' => $required, 'children' => $children )), @@ -373,196 +331,224 @@ class Explorer implements iProvideMultiVersionApi ); } } + return $r; } private function parameter(ValidationInfo $info, $description = '') { $p = new stdClass(); - if(isset($info->rules['model'])){ - $info->type = $info->rules['model']; + if (isset($info->rules['model'])) { + //$info->type = $info->rules['model']; } $p->name = $info->name; $this->setType($p, $info); if (empty($info->children) || $info->type != 'array') { //primitives - if ($info->default) + if ($info->default) { $p->defaultValue = $info->default; - if ($info->choice) + } + if ($info->choice) { $p->enum = $info->choice; - if ($info->min) + } + if ($info->min) { $p->minimum = $info->min; - if ($info->max) + } + if ($info->max) { $p->maximum = $info->max; + } //TODO: $p->items and $p->uniqueItems boolean } $p->description = $description; - $p->paramType = $info->from; //$info->from == 'body' ? 'form' : $info->from; + $p->in = $info->from; //$info->from == 'body' ? 'form' : $info->from; $p->required = $info->required; - $p->allowMultiple = false; + + //$p->allowMultiple = false; + + if (isset($p->{'$ref'})) { + $p->schema = (object)array('$ref' => ($p->{'$ref'})); + unset($p->{'$ref'}); + } + return $p; } - private function responseMessages(array $route) + private function responses(array $route) { - $r = array(); + $code = '200'; + $r = array( + $code => (object)array( + 'description' => 'Success', + 'schema' => new stdClass() + ) + ); + $return = Util::nestedValue($route, 'metadata', 'return'); + if (!empty($return)) { + $this->setType($r[$code]->schema, new ValidationInfo($return)); + } + if (is_array($throws = Util::nestedValue($route, 'metadata', 'throws'))) { foreach ($throws as $message) { - $m = (object)$message; - //TODO: add $m->responseModel from composer class - $r[] = $m; + $r[$message['code']] = array('description' => $message['message']); } } + return $r; } private function model($type, array $children) { - /** - * Bugfix: - * If we use namespaces, than the model will not be correct, if we use a short name for the type! - * - * Example (phpDoc/annotations in API-class, which uses custom domain-model with namespace): - * @param Car $car {@from body} {@type Aoe\RestServices\Domain\Model\Car} - * @return Car {@type Aoe\RestServices\Domain\Model\Car} - * Than, the model (in swagger-spec) must also be 'Aoe\RestServices\Domain\Model\Car' and not 'Car' - * - * When we use namespaces, than we must use the @type-annotation, otherwise the automatic reconstitution - * from request-data (e.g. when it is a POST-request) to custom domain-model-object will not work! - * - * Summary: - * - When we use no namespaces, than the type would not be changed, if we would call 'Util::getShortName' - * - When we use namespaces, than the model will not be correct, if we would call 'Util::getShortName' - * ...so this method-call is either needless or will create a bug/error - */ - //$type = Util::getShortName($type); - if (isset($this->models[$type])) + if (isset($this->models[$type])) { return $this->models[$type]; + } $r = new stdClass(); - $r->id = $type; - $r->description = "$type Model"; //TODO: enhance this on Router - $r->required = array(); $r->properties = array(); + $required = array(); foreach ($children as $child) { $info = new ValidationInfo($child); $p = new stdClass(); $this->setType($p, $info); $p->description = isset($child['description']) ? $child['description'] : ''; - if ($info->default) + if ($info->default) { $p->defaultValue = $info->default; - if ($info->choice) + } + if ($info->choice) { $p->enum = $info->choice; - if ($info->min) + } + if ($info->min) { $p->minimum = $info->min; - if ($info->max) + } + if ($info->max) { $p->maximum = $info->max; - if ($info->required) - $r->required[] = $info->name; + } + if ($info->required) { + $required[] = $info->name; + } $r->properties[$info->name] = $p; } + if (!empty($required)) { + $r->required = $required; + } //TODO: add $r->subTypes https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#527-model-object //TODO: add $r->discriminator https://github.com/wordnik/swagger-spec/blob/master/versions/1.2.md#527-model-object $this->models[$type] = $r; + return $r; } private function setType(&$object, ValidationInfo $info) { //TODO: proper type management + $type = Util::getShortName($info->type); if ($info->type == 'array') { + $object->type = 'array'; if ($info->children) { - $this->model($info->contentType, $info->children); + $contentType = Util::getShortName($info->contentType); + $model = $this->model($contentType, $info->children); $object->items = (object)array( - '$ref' => $info->contentType + '$ref' => "#/definitions/$contentType" ); } elseif ($info->contentType && $info->contentType == 'associative') { unset($info->contentType); $this->model($info->type = 'Object', array( array( - 'name' => 'property', - 'type' => 'string', - 'default' => '', - 'required' => false, + 'name' => 'property', + 'type' => 'string', + 'default' => '', + 'required' => false, 'description' => '' ) )); } elseif ($info->contentType && $info->contentType != 'indexed') { - $object->items = (object)array( - 'type' => $info->contentType - ); + if (is_string($info->contentType) && $t = Util::nestedValue(static::$dataTypeAlias, + strtolower($info->contentType))) { + if (is_array($t)) { + $object->items = (object)array( + 'type' => $t[0], + 'format' => $t[1], + ); + } else { + $object->items = (object)array( + 'type' => $t, + ); + } + } else { + $contentType = Util::getShortName($info->contentType); + $object->items = (object)array( + '$ref' => "#/definitions/$contentType" + ); + } } else { $object->items = (object)array( 'type' => 'string' ); } } elseif ($info->children) { - $this->model($info->type, $info->children); + $this->model($type, $info->children); + $object->{'$ref'} = "#/definitions/$type"; } elseif (is_string($info->type) && $t = Util::nestedValue(static::$dataTypeAlias, strtolower($info->type))) { if (is_array($t)) { - list($info->type, $object->format) = $t; + $object->type = $t[0]; + $object->format = $t[1]; } else { - $info->type = $t; + $object->type = $t; } } else { - $info->type = 'string'; + $object->type = 'string'; } - $object->type = $info->type; $has64bit = PHP_INT_MAX > 2147483647; - if ($object->type == 'integer') { - $object->format = $has64bit - ? 'int64' - : 'int32'; - } elseif ($object->type == 'number') { - $object->format = $has64bit - ? 'double' - : 'float'; + if (isset($object->type)) { + if ($object->type == 'integer') { + $object->format = $has64bit + ? 'int64' + : 'int32'; + } elseif ($object->type == 'number') { + $object->format = $has64bit + ? 'double' + : 'float'; + } } } - private function nickname(array $route) + private function operationId(array $route) { static $hash = array(); + $id = $route['httpMethod'] . ' ' . $route['url']; + if (isset($hash[$id])) { + return $hash[$id]; + } + $class = Util::getShortName($route['className']); $method = $route['methodName']; + if (isset(static::$prefixes[$method])) { - $method = static::$prefixes[$method]; + $method = static::$prefixes[$method] . $class; } else { $method = str_replace( array_keys(static::$prefixes), array_values(static::$prefixes), $method ); + $method = lcfirst($class) . ucfirst($method); } - while (isset($hash[$method]) && $route['url'] != $hash[$method]) { - //create another one - $method .= '_'; - } - $hash[$method] = $route['url']; + $hash[$id] = $method; + return $method; } - private function nameModel(array $route) + private function modelName(array $route) { - static $hash = array(); - $count = 1; - //$name = str_replace('/', '-', $route['url']) . 'Model'; - $name = $route['className'] . 'Model'; - while (isset($hash[$name . $count])) { - //create another one - $count++; - } - $name .= $count; - $hash[$name] = $route['url']; - return $name; + return $this->operationId($route) . 'Model'; } - private function authorizations() + private function securityDefinitions() { $r = new stdClass(); - $r->apiKey = (object)array( + $r->api_key = (object)array( 'type' => 'apiKey', - 'passAs' => 'query', - 'keyname' => 'api_key', + 'name' => 'api_key', + 'in' => 'query', ); + return $r; } diff --git a/htdocs/includes/restler/framework/Luracast/Restler/ExplorerInfo.php b/htdocs/includes/restler/framework/Luracast/Restler/ExplorerInfo.php index 41d969f65d9..b55c5943fed 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/ExplorerInfo.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/ExplorerInfo.php @@ -2,16 +2,22 @@ /** * Class ExplorerInfo - * @package Luracast\Restler - * + * @package Luracast\Restler + * * @version 3.0.0rc6 */ class ExplorerInfo { public static $title = 'Restler API Explorer'; public static $description = 'Live API Documentation'; - public static $termsOfServiceUrl = null; - public static $contact = 'arul@luracast.com'; - public static $license = 'LGPL-2.1'; - public static $licenseUrl = 'https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html'; + public static $termsOfService = null; + public static $contact = array( + 'name' => 'Restler Support', + 'url' => 'luracast.com/products/restler', + 'email' => 'arul@luracast.com', + ); + public static $license = array( + 'name' => 'LGPL-2.1', + 'url' => 'https://www.gnu.org/licenses/old-licenses/lgpl-2.1.html', + ); } \ No newline at end of file diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Format/CsvFormat.php b/htdocs/includes/restler/framework/Luracast/Restler/Format/CsvFormat.php index d6cdb63a943..4bed88251c8 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Format/CsvFormat.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Format/CsvFormat.php @@ -2,7 +2,7 @@ namespace Luracast\Restler\Format; -use Luracast\Restler\Data\Object; +use Luracast\Restler\Data\Obj; use Luracast\Restler\RestException; /** @@ -44,10 +44,10 @@ class CsvFormat extends Format implements iDecodeStream */ public function encode($data, $humanReadable = false) { - $char = Object::$separatorChar; - Object::$separatorChar = false; - $data = Object::toArray($data); - Object::$separatorChar = $char; + $char = Obj::$separatorChar; + Obj::$separatorChar = false; + $data = Obj::toArray($data); + Obj::$separatorChar = $char; if (is_array($data) && array_values($data) == $data) { //if indexed array $lines = array(); @@ -109,10 +109,10 @@ class CsvFormat extends Format implements iDecodeStream while (($row = static::getRow(array_shift($lines), $keys)) !== FALSE) $decoded [] = $row; - $char = Object::$separatorChar; - Object::$separatorChar = false; - $decoded = Object::toArray($decoded); - Object::$separatorChar = $char; + $char = Obj::$separatorChar; + Obj::$separatorChar = false; + $decoded = Obj::toArray($decoded); + Obj::$separatorChar = $char; return $decoded; } @@ -172,10 +172,10 @@ class CsvFormat extends Format implements iDecodeStream while (($row = static::getRow(stream_get_line($stream, 0, PHP_EOL), $keys)) !== FALSE) $decoded [] = $row; - $char = Object::$separatorChar; - Object::$separatorChar = false; - $decoded = Object::toArray($decoded); - Object::$separatorChar = $char; + $char = Obj::$separatorChar; + Obj::$separatorChar = false; + $decoded = Obj::toArray($decoded); + Obj::$separatorChar = $char; return $decoded; } } \ No newline at end of file diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Format/HtmlFormat.php b/htdocs/includes/restler/framework/Luracast/Restler/Format/HtmlFormat.php index 6e7d4b7303e..e871186c446 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Format/HtmlFormat.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Format/HtmlFormat.php @@ -11,7 +11,7 @@ use Illuminate\View\Engines\EngineResolver; use Illuminate\View\Factory; use Illuminate\View\FileViewFinder; use Illuminate\View\View; -use Luracast\Restler\Data\Object; +use Luracast\Restler\Data\Obj; use Luracast\Restler\Defaults; use Luracast\Restler\RestException; use Luracast\Restler\Restler; @@ -315,7 +315,7 @@ class HtmlFormat extends DependentFormat $error = $success ? null : $exception->getMessage(); $data = array( 'response' => static::$convertResponseToArray - ? Object::toArray($data) + ? Obj::toArray($data) : $data, 'stages' => $this->restler->getEvents(), 'success' => $success, diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Format/JsonFormat.php b/htdocs/includes/restler/framework/Luracast/Restler/Format/JsonFormat.php index 6986ce65c90..28dfd560969 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Format/JsonFormat.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Format/JsonFormat.php @@ -1,7 +1,7 @@ handleJsonError(); return $result; } - $result = json_encode(Object::toArray($data, true)); + $result = json_encode(Obj::toArray($data, true)); $this->handleJsonError(); if ($humanReadable) { @@ -116,6 +127,10 @@ class JsonFormat extends Format public function decode($data) { + if(empty($data)){ + return null; + } + $options = 0; if (self::$bigIntAsString) { if ((PHP_MAJOR_VERSION == 5 && PHP_MINOR_VERSION >= 4) // PHP >= 5.4 @@ -142,7 +157,7 @@ class JsonFormat extends Format throw new RestException(400, 'Error parsing JSON'); } - return Object::toArray($decoded); + return Obj::toArray($decoded); } /** @@ -259,4 +274,4 @@ class JsonFormat extends Format throw new \RuntimeException('Error encoding/decoding JSON: '. $message); } } -} \ No newline at end of file +} diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Format/PlistFormat.php b/htdocs/includes/restler/framework/Luracast/Restler/Format/PlistFormat.php index 2f4faa0769f..cc07066a33c 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Format/PlistFormat.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Format/PlistFormat.php @@ -1,7 +1,7 @@ toCFType( - Object::toArray($data) + Obj::toArray($data) ); $plist->add($guessedStructure); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Format/UploadFormat.php b/htdocs/includes/restler/framework/Luracast/Restler/Format/UploadFormat.php index f785beeaa02..de41bf98c71 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Format/UploadFormat.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Format/UploadFormat.php @@ -25,7 +25,9 @@ class UploadFormat extends Format 2 => "The uploaded file exceeds the maximum allowed size", 3 => "The uploaded file was only partially uploaded", 4 => "No file was uploaded", - 6 => "Missing a temporary folder" + 6 => "Missing a temporary folder", + 7 => "Failed to write file to disk", + 8 => "A PHP extension stopped the file upload" ); /** * use it if you need to restrict uploads based on file type diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Format/XmlFormat.php b/htdocs/includes/restler/framework/Luracast/Restler/Format/XmlFormat.php index b006409e800..b51fa707a53 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Format/XmlFormat.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Format/XmlFormat.php @@ -1,7 +1,7 @@ openMemory(); $xml->startDocument('1.0', $this->charset); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Format/YamlFormat.php b/htdocs/includes/restler/framework/Luracast/Restler/Format/YamlFormat.php index 0cb1564f4ed..07baae88b6f 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Format/YamlFormat.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Format/YamlFormat.php @@ -2,7 +2,7 @@ namespace Luracast\Restler\Format; use Symfony\Component\Yaml\Yaml; -use Luracast\Restler\Data\Object; +use Luracast\Restler\Data\Obj; /** * YAML Format for Restler Framework @@ -26,7 +26,7 @@ class YamlFormat extends DependentFormat public function encode($data, $humanReadable = false) { - return @Yaml::dump(Object::toArray($data), $humanReadable ? 10 : 4); + return @Yaml::dump(Obj::toArray($data), $humanReadable ? 10 : 4); } public function decode($data) diff --git a/htdocs/includes/restler/framework/Luracast/Restler/PassThrough.php b/htdocs/includes/restler/framework/Luracast/Restler/PassThrough.php index e1fc21eae6b..a77e533b722 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/PassThrough.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/PassThrough.php @@ -34,7 +34,6 @@ class PassThrough * @param bool $isPublic cache control, is it public or private * * @throws RestException - * @internal param string $pragma * */ public static function file($filename, $forceDownload = false, $expires = 0, $isPublic = true) diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Restler.php b/htdocs/includes/restler/framework/Luracast/Restler/Restler.php index 0cef46a7e41..c2e9b1acb73 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Restler.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Restler.php @@ -538,7 +538,7 @@ class Restler extends EventDispatcher if ($version && $version <= $this->apiVersion) { $this->requestedApiVersion = $version; $path = explode('/', $path, 2); - $path = $path[1]; + $path = count($path) == 2 ? $path[1] : ''; } } else { $this->requestedApiVersion = $this->apiMinimumVersion; @@ -718,7 +718,8 @@ class Restler extends EventDispatcher . $_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']); header('Access-Control-Allow-Origin: ' . - (Defaults::$accessControlAllowOrigin == '*' ? $_SERVER['HTTP_ORIGIN'] : Defaults::$accessControlAllowOrigin)); + ((Defaults::$accessControlAllowOrigin == '*' && isset($_SERVER['HTTP_ORIGIN'])) + ? $_SERVER['HTTP_ORIGIN'] : Defaults::$accessControlAllowOrigin)); header('Access-Control-Allow-Credentials: true'); exit(0); @@ -1195,7 +1196,7 @@ class Restler extends EventDispatcher foreach ($this->errorClasses as $className) { if (method_exists($className, $method)) { $obj = Scope::get($className); - if ($obj->$method()) + if ($obj->$method($exception)) $handled = true; } } @@ -1397,6 +1398,135 @@ class Restler extends EventDispatcher $this->errorClasses[] = $className; } + /** + * protected methods will need at least one authentication class to be set + * in order to allow that method to be executed. When multiple authentication + * classes are in use, this function provides better performance by setting + * all auth classes through a single function call. + * + * @param array $classNames array of associative arrays containing + * the authentication class name & optional + * url prefix for mapping. + */ + public function setAuthClasses(array $classNames) + { + $this->authClasses = array_merge($this->authClasses, array_values($classNames)); + } + + /** + * Add multiple api classes through this method. + * + * This method provides better performance when large number + * of API classes are in use as it processes them all at once, + * as opposed to hundreds (or more) addAPIClass calls. + * + * + * All the public methods that do not start with _ (underscore) + * will be will be exposed as the public api by default. + * + * All the protected methods that do not start with _ (underscore) + * will exposed as protected api which will require authentication + * + * @param array $map array of associative arrays containing + * the class name & optional url prefix + * for mapping. + * + * @return null + * + * @throws Exception when supplied with invalid class name + */ + public function mapAPIClasses(array $map) + { + try { + if ($this->productionMode && is_null($this->cached)) { + $routes = $this->cache->get('routes'); + if (isset($routes) && is_array($routes)) { + $this->apiVersionMap = $routes['apiVersionMap']; + unset($routes['apiVersionMap']); + Routes::fromArray($routes); + $this->cached = true; + } else { + $this->cached = false; + } + } + $maxVersionMethod = '__getMaximumSupportedVersion'; + if (!$this->productionMode || !$this->cached) { + foreach ($map as $className => $resourcePath) { + if (is_numeric($className)) { + $className = $resourcePath; + $resourcePath = null; + } + if (isset(Scope::$classAliases[$className])) { + $className = Scope::$classAliases[$className]; + } + if (class_exists($className)) { + if (method_exists($className, $maxVersionMethod)) { + $max = $className::$maxVersionMethod(); + for ($i = 1; $i <= $max; $i++) { + $this->apiVersionMap[$className][$i] = $className; + } + } else { + $this->apiVersionMap[$className][1] = $className; + } + } + //versioned api + if (false !== ($index = strrpos($className, '\\'))) { + $name = substr($className, 0, $index) + . '\\v{$version}' . substr($className, $index); + } else { + if (false !== ($index = strrpos($className, '_'))) { + $name = substr($className, 0, $index) + . '_v{$version}' . substr($className, $index); + } else { + $name = 'v{$version}\\' . $className; + } + } + + for ($version = $this->apiMinimumVersion; + $version <= $this->apiVersion; + $version++) { + + $versionedClassName = str_replace('{$version}', $version, + $name); + if (class_exists($versionedClassName)) { + Routes::addAPIClass($versionedClassName, + Util::getResourcePath( + $className, + $resourcePath + ), + $version + ); + if (method_exists($versionedClassName, $maxVersionMethod)) { + $max = $versionedClassName::$maxVersionMethod(); + for ($i = $version; $i <= $max; $i++) { + $this->apiVersionMap[$className][$i] = $versionedClassName; + } + } else { + $this->apiVersionMap[$className][$version] = $versionedClassName; + } + } elseif (isset($this->apiVersionMap[$className][$version])) { + Routes::addAPIClass($this->apiVersionMap[$className][$version], + Util::getResourcePath( + $className, + $resourcePath + ), + $version + ); + } + } + } + } + } catch (Exception $e) { + $e = new Exception( + "mapAPIClasses failed. " . $e->getMessage(), + $e->getCode(), + $e + ); + $this->setSupportedFormats('JsonFormat'); + $this->message($e); + } + } + /** * Associated array that maps formats to their respective format class name * @@ -1484,6 +1614,19 @@ class Restler extends EventDispatcher public function __destruct() { if ($this->productionMode && !$this->cached) { + if (empty($this->url) && empty($this->requestMethod)) { + // url and requestMethod is NOT set: + // This can only happen, when an exception was thrown outside of restler, so that the method Restler::handle was NOT called. + // In this case, the routes can now be corrupt/incomplete, because we don't know, if all API-classes could be registered + // before the exception was thrown. So, don't cache the routes, because the routes can now be corrupt/incomplete! + return; + } + if ($this->exception instanceof RestException && $this->exception->getStage() === 'setup') { + // An exception has occured during configuration of restler. Maybe we could not add all API-classes correctly! + // So, don't cache the routes, because the routes can now be corrupt/incomplete! + return; + } + $this->cache->set( 'routes', Routes::toArray() + diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Routes.php b/htdocs/includes/restler/framework/Luracast/Restler/Routes.php index 067603a0f58..73e78dc0039 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Routes.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Routes.php @@ -293,8 +293,6 @@ class Routes } $url = empty($methodUrl) ? rtrim($resourcePath, '/') : $resourcePath . $methodUrl; - $lastPathParam = array_keys($pathParams); - $lastPathParam = end($lastPathParam); for ($position = 0; $position < count($params); $position++) { $from = $metadata['param'][$position][$dataName]['from']; if ($from == 'body' && ($httpMethod == 'GET' || @@ -307,6 +305,7 @@ class Routes if (empty($pathParams) || $allowAmbiguity) { static::addPath($url, $call, $httpMethod, $version); } + $lastPathParam = end($pathParams); foreach ($pathParams as $position) { if (!empty($url)) $url .= '/'; diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Scope.php b/htdocs/includes/restler/framework/Luracast/Restler/Scope.php index 91eea3ef6a1..fd4b41ff98d 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Scope.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Scope.php @@ -52,7 +52,7 @@ class Scope 'MemcacheCache' => 'Luracast\Restler\MemcacheCache', //Utility classes - 'Object' => 'Luracast\Restler\Data\Object', + 'Obj' => 'Luracast\Restler\Data\Obj', 'Text' => 'Luracast\Restler\Data\Text', 'Arr' => 'Luracast\Restler\Data\Arr', @@ -194,6 +194,11 @@ class Scope { if (empty($className) || !is_string($className)) return false; + + if (self::isPrimitiveDataType($className)) { + return false; + } + $divider = '\\'; $qualified = false; if ($className{0} == $divider) { @@ -212,4 +217,14 @@ class Scope } return false; } + + /** + * @param string $stringName + * @return boolean + */ + private static function isPrimitiveDataType($stringName) + { + $primitiveDataTypes = array('Array', 'array', 'bool', 'boolean', 'float', 'int', 'integer', 'string'); + return in_array($stringName, $primitiveDataTypes); + } } diff --git a/htdocs/includes/restler/framework/Luracast/Restler/Util.php b/htdocs/includes/restler/framework/Luracast/Restler/Util.php index e1c6f60c317..e7324a3a620 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/Util.php +++ b/htdocs/includes/restler/framework/Luracast/Restler/Util.php @@ -226,6 +226,10 @@ class Util public static function getShortName($className) { + // @CHANGE LDR + if (! is_string($className)) return ''; + //var_dump($className); + $className = explode('\\', $className); return end($className); } diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/print.css b/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/print.css new file mode 100644 index 00000000000..2e6b310300b --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/print.css @@ -0,0 +1,1187 @@ +/* Original style from softwaremaniacs.org (c) Ivan Sagalaev */ +.swagger-section pre code { + display: block; + padding: 0.5em; + background: #F0F0F0; +} +.swagger-section pre code, +.swagger-section pre .subst, +.swagger-section pre .tag .title, +.swagger-section pre .lisp .title, +.swagger-section pre .clojure .built_in, +.swagger-section pre .nginx .title { + color: black; +} +.swagger-section pre .string, +.swagger-section pre .title, +.swagger-section pre .constant, +.swagger-section pre .parent, +.swagger-section pre .tag .value, +.swagger-section pre .rules .value, +.swagger-section pre .rules .value .number, +.swagger-section pre .preprocessor, +.swagger-section pre .ruby .symbol, +.swagger-section pre .ruby .symbol .string, +.swagger-section pre .aggregate, +.swagger-section pre .template_tag, +.swagger-section pre .django .variable, +.swagger-section pre .smalltalk .class, +.swagger-section pre .addition, +.swagger-section pre .flow, +.swagger-section pre .stream, +.swagger-section pre .bash .variable, +.swagger-section pre .apache .tag, +.swagger-section pre .apache .cbracket, +.swagger-section pre .tex .command, +.swagger-section pre .tex .special, +.swagger-section pre .erlang_repl .function_or_atom, +.swagger-section pre .markdown .header { + color: #800; +} +.swagger-section pre .comment, +.swagger-section pre .annotation, +.swagger-section pre .template_comment, +.swagger-section pre .diff .header, +.swagger-section pre .chunk, +.swagger-section pre .markdown .blockquote { + color: #888; +} +.swagger-section pre .number, +.swagger-section pre .date, +.swagger-section pre .regexp, +.swagger-section pre .literal, +.swagger-section pre .smalltalk .symbol, +.swagger-section pre .smalltalk .char, +.swagger-section pre .go .constant, +.swagger-section pre .change, +.swagger-section pre .markdown .bullet, +.swagger-section pre .markdown .link_url { + color: #080; +} +.swagger-section pre .label, +.swagger-section pre .javadoc, +.swagger-section pre .ruby .string, +.swagger-section pre .decorator, +.swagger-section pre .filter .argument, +.swagger-section pre .localvars, +.swagger-section pre .array, +.swagger-section pre .attr_selector, +.swagger-section pre .important, +.swagger-section pre .pseudo, +.swagger-section pre .pi, +.swagger-section pre .doctype, +.swagger-section pre .deletion, +.swagger-section pre .envvar, +.swagger-section pre .shebang, +.swagger-section pre .apache .sqbracket, +.swagger-section pre .nginx .built_in, +.swagger-section pre .tex .formula, +.swagger-section pre .erlang_repl .reserved, +.swagger-section pre .prompt, +.swagger-section pre .markdown .link_label, +.swagger-section pre .vhdl .attribute, +.swagger-section pre .clojure .attribute, +.swagger-section pre .coffeescript .property { + color: #8888ff; +} +.swagger-section pre .keyword, +.swagger-section pre .id, +.swagger-section pre .phpdoc, +.swagger-section pre .title, +.swagger-section pre .built_in, +.swagger-section pre .aggregate, +.swagger-section pre .css .tag, +.swagger-section pre .javadoctag, +.swagger-section pre .phpdoc, +.swagger-section pre .yardoctag, +.swagger-section pre .smalltalk .class, +.swagger-section pre .winutils, +.swagger-section pre .bash .variable, +.swagger-section pre .apache .tag, +.swagger-section pre .go .typename, +.swagger-section pre .tex .command, +.swagger-section pre .markdown .strong, +.swagger-section pre .request, +.swagger-section pre .status { + font-weight: bold; +} +.swagger-section pre .markdown .emphasis { + font-style: italic; +} +.swagger-section pre .nginx .built_in { + font-weight: normal; +} +.swagger-section pre .coffeescript .javascript, +.swagger-section pre .javascript .xml, +.swagger-section pre .tex .formula, +.swagger-section pre .xml .javascript, +.swagger-section pre .xml .vbscript, +.swagger-section pre .xml .css, +.swagger-section pre .xml .cdata { + opacity: 0.5; +} +.swagger-section .swagger-ui-wrap { + line-height: 1; + font-family: "Droid Sans", sans-serif; + max-width: 960px; + margin-left: auto; + margin-right: auto; + /* JSONEditor specific styling */ +} +.swagger-section .swagger-ui-wrap b, +.swagger-section .swagger-ui-wrap strong { + font-family: "Droid Sans", sans-serif; + font-weight: bold; +} +.swagger-section .swagger-ui-wrap q, +.swagger-section .swagger-ui-wrap blockquote { + quotes: none; +} +.swagger-section .swagger-ui-wrap p { + line-height: 1.4em; + padding: 0 0 10px; + color: #333333; +} +.swagger-section .swagger-ui-wrap q:before, +.swagger-section .swagger-ui-wrap q:after, +.swagger-section .swagger-ui-wrap blockquote:before, +.swagger-section .swagger-ui-wrap blockquote:after { + content: none; +} +.swagger-section .swagger-ui-wrap .heading_with_menu h1, +.swagger-section .swagger-ui-wrap .heading_with_menu h2, +.swagger-section .swagger-ui-wrap .heading_with_menu h3, +.swagger-section .swagger-ui-wrap .heading_with_menu h4, +.swagger-section .swagger-ui-wrap .heading_with_menu h5, +.swagger-section .swagger-ui-wrap .heading_with_menu h6 { + display: block; + clear: none; + float: left; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + width: 60%; +} +.swagger-section .swagger-ui-wrap table { + border-collapse: collapse; + border-spacing: 0; +} +.swagger-section .swagger-ui-wrap table thead tr th { + padding: 5px; + font-size: 0.9em; + color: #666666; + border-bottom: 1px solid #999999; +} +.swagger-section .swagger-ui-wrap table tbody tr:last-child td { + border-bottom: none; +} +.swagger-section .swagger-ui-wrap table tbody tr.offset { + background-color: #f0f0f0; +} +.swagger-section .swagger-ui-wrap table tbody tr td { + padding: 6px; + font-size: 0.9em; + border-bottom: 1px solid #cccccc; + vertical-align: top; + line-height: 1.3em; +} +.swagger-section .swagger-ui-wrap ol { + margin: 0px 0 10px; + padding: 0 0 0 18px; + list-style-type: decimal; +} +.swagger-section .swagger-ui-wrap ol li { + padding: 5px 0px; + font-size: 0.9em; + color: #333333; +} +.swagger-section .swagger-ui-wrap ol, +.swagger-section .swagger-ui-wrap ul { + list-style: none; +} +.swagger-section .swagger-ui-wrap h1 a, +.swagger-section .swagger-ui-wrap h2 a, +.swagger-section .swagger-ui-wrap h3 a, +.swagger-section .swagger-ui-wrap h4 a, +.swagger-section .swagger-ui-wrap h5 a, +.swagger-section .swagger-ui-wrap h6 a { + text-decoration: none; +} +.swagger-section .swagger-ui-wrap h1 a:hover, +.swagger-section .swagger-ui-wrap h2 a:hover, +.swagger-section .swagger-ui-wrap h3 a:hover, +.swagger-section .swagger-ui-wrap h4 a:hover, +.swagger-section .swagger-ui-wrap h5 a:hover, +.swagger-section .swagger-ui-wrap h6 a:hover { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap h1 span.divider, +.swagger-section .swagger-ui-wrap h2 span.divider, +.swagger-section .swagger-ui-wrap h3 span.divider, +.swagger-section .swagger-ui-wrap h4 span.divider, +.swagger-section .swagger-ui-wrap h5 span.divider, +.swagger-section .swagger-ui-wrap h6 span.divider { + color: #aaaaaa; +} +.swagger-section .swagger-ui-wrap a { + color: #547f00; +} +.swagger-section .swagger-ui-wrap a img { + border: none; +} +.swagger-section .swagger-ui-wrap article, +.swagger-section .swagger-ui-wrap aside, +.swagger-section .swagger-ui-wrap details, +.swagger-section .swagger-ui-wrap figcaption, +.swagger-section .swagger-ui-wrap figure, +.swagger-section .swagger-ui-wrap footer, +.swagger-section .swagger-ui-wrap header, +.swagger-section .swagger-ui-wrap hgroup, +.swagger-section .swagger-ui-wrap menu, +.swagger-section .swagger-ui-wrap nav, +.swagger-section .swagger-ui-wrap section, +.swagger-section .swagger-ui-wrap summary { + display: block; +} +.swagger-section .swagger-ui-wrap pre { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + background-color: #fcf6db; + border: 1px solid #e5e0c6; + padding: 10px; +} +.swagger-section .swagger-ui-wrap pre code { + line-height: 1.6em; + background: none; +} +.swagger-section .swagger-ui-wrap .content > .content-type > div > label { + clear: both; + display: block; + color: #0F6AB4; + font-size: 1.1em; + margin: 0; + padding: 15px 0 5px; +} +.swagger-section .swagger-ui-wrap .content pre { + font-size: 12px; + margin-top: 5px; + padding: 5px; +} +.swagger-section .swagger-ui-wrap .icon-btn { + cursor: pointer; +} +.swagger-section .swagger-ui-wrap .info_title { + padding-bottom: 10px; + font-weight: bold; + font-size: 25px; +} +.swagger-section .swagger-ui-wrap .footer { + margin-top: 20px; +} +.swagger-section .swagger-ui-wrap p.big, +.swagger-section .swagger-ui-wrap div.big p { + font-size: 1em; + margin-bottom: 10px; +} +.swagger-section .swagger-ui-wrap form.fullwidth ol li.string input, +.swagger-section .swagger-ui-wrap form.fullwidth ol li.url input, +.swagger-section .swagger-ui-wrap form.fullwidth ol li.text textarea, +.swagger-section .swagger-ui-wrap form.fullwidth ol li.numeric input { + width: 500px !important; +} +.swagger-section .swagger-ui-wrap .info_license { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_tos { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .message-fail { + color: #cc0000; +} +.swagger-section .swagger-ui-wrap .info_url { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_email { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_name { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_description { + padding-bottom: 10px; + font-size: 15px; +} +.swagger-section .swagger-ui-wrap .markdown ol li, +.swagger-section .swagger-ui-wrap .markdown ul li { + padding: 3px 0px; + line-height: 1.4em; + color: #333333; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input { + display: block; + padding: 4px; + width: auto; + clear: both; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.string input.title, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.url input.title, +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.numeric input.title { + font-size: 1.3em; +} +.swagger-section .swagger-ui-wrap table.fullwidth { + width: 100%; +} +.swagger-section .swagger-ui-wrap .model-signature { + font-family: "Droid Sans", sans-serif; + font-size: 1em; + line-height: 1.5em; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-nav a { + text-decoration: none; + color: #AAA; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-nav a:hover { + text-decoration: underline; + color: black; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-nav .selected { + color: black; + text-decoration: none; +} +.swagger-section .swagger-ui-wrap .model-signature .propType { + color: #5555aa; +} +.swagger-section .swagger-ui-wrap .model-signature pre:hover { + background-color: #ffffdd; +} +.swagger-section .swagger-ui-wrap .model-signature pre { + font-size: .85em; + line-height: 1.2em; + overflow: auto; + max-height: 200px; + cursor: pointer; +} +.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav { + display: block; + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li:last-child { + padding-right: 0; + border-right: none; +} +.swagger-section .swagger-ui-wrap .model-signature ul.signature-nav li { + float: left; + margin: 0 5px 5px 0; + padding: 2px 5px 2px 0; + border-right: 1px solid #ddd; +} +.swagger-section .swagger-ui-wrap .model-signature .propOpt { + color: #555; +} +.swagger-section .swagger-ui-wrap .model-signature .snippet small { + font-size: 0.75em; +} +.swagger-section .swagger-ui-wrap .model-signature .propOptKey { + font-style: italic; +} +.swagger-section .swagger-ui-wrap .model-signature .description .strong { + font-weight: bold; + color: #000; + font-size: .9em; +} +.swagger-section .swagger-ui-wrap .model-signature .description div { + font-size: 0.9em; + line-height: 1.5em; + margin-left: 1em; +} +.swagger-section .swagger-ui-wrap .model-signature .description .stronger { + font-weight: bold; + color: #000; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper { + border-spacing: 0; + position: absolute; + background-color: #ffffff; + border: 1px solid #bbbbbb; + display: none; + font-size: 11px; + max-width: 400px; + line-height: 30px; + color: black; + padding: 5px; + margin-left: 10px; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper th { + text-align: center; + background-color: #eeeeee; + border: 1px solid #bbbbbb; + font-size: 11px; + color: #666666; + font-weight: bold; + padding: 5px; + line-height: 15px; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:first-child, +.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:last-child { + display: inline; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:not(:first-child):before { + display: block; + content: ''; +} +.swagger-section .swagger-ui-wrap .model-signature .description span:last-of-type.propDesc.markdown > p:only-child { + margin-right: -3px; +} +.swagger-section .swagger-ui-wrap .model-signature .propName { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .model-signature .signature-container { + clear: both; +} +.swagger-section .swagger-ui-wrap .body-textarea { + width: 300px; + height: 100px; + border: 1px solid #aaa; +} +.swagger-section .swagger-ui-wrap .markdown p code, +.swagger-section .swagger-ui-wrap .markdown li code { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + background-color: #f0f0f0; + color: black; + padding: 1px 3px; +} +.swagger-section .swagger-ui-wrap .required { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .editor_holder { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap .editor_holder label { + font-weight: normal!important; + /* JSONEditor uses bold by default for all labels, we revert that back to normal to not give the impression that by default fields are required */ +} +.swagger-section .swagger-ui-wrap .editor_holder label.required { + font-weight: bold!important; +} +.swagger-section .swagger-ui-wrap input.parameter { + width: 300px; + border: 1px solid #aaa; +} +.swagger-section .swagger-ui-wrap h1 { + color: black; + font-size: 1.5em; + line-height: 1.3em; + padding: 10px 0 10px 0; + font-family: "Droid Sans", sans-serif; + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .heading_with_menu { + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap .heading_with_menu ul { + display: block; + clear: none; + float: right; + -moz-box-sizing: border-box; + -webkit-box-sizing: border-box; + -ms-box-sizing: border-box; + box-sizing: border-box; + margin-top: 10px; +} +.swagger-section .swagger-ui-wrap h2 { + color: black; + font-size: 1.3em; + padding: 10px 0 10px 0; +} +.swagger-section .swagger-ui-wrap h2 a { + color: black; +} +.swagger-section .swagger-ui-wrap h2 span.sub { + font-size: 0.7em; + color: #999999; + font-style: italic; +} +.swagger-section .swagger-ui-wrap h2 span.sub a { + color: #777777; +} +.swagger-section .swagger-ui-wrap span.weak { + color: #666666; +} +.swagger-section .swagger-ui-wrap .message-success { + color: #89BF04; +} +.swagger-section .swagger-ui-wrap caption, +.swagger-section .swagger-ui-wrap th, +.swagger-section .swagger-ui-wrap td { + text-align: left; + font-weight: normal; + vertical-align: middle; +} +.swagger-section .swagger-ui-wrap .code { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.text textarea { + font-family: "Droid Sans", sans-serif; + height: 250px; + padding: 4px; + display: block; + clear: both; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.select select { + display: block; + clear: both; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean { + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean label { + display: block; + float: left; + clear: none; + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.boolean input { + display: block; + float: left; + clear: none; + margin: 0 5px 0 0; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li.required label { + color: black; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label { + display: block; + clear: both; + width: auto; + padding: 0 0 3px; + color: #666666; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li label abbr { + padding-left: 3px; + color: #888888; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.inputs ol li p.inline-hints { + margin-left: 0; + font-style: italic; + font-size: 0.9em; + margin: 0; +} +.swagger-section .swagger-ui-wrap form.formtastic fieldset.buttons { + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap span.blank, +.swagger-section .swagger-ui-wrap span.empty { + color: #888888; + font-style: italic; +} +.swagger-section .swagger-ui-wrap .markdown h3 { + color: #547f00; +} +.swagger-section .swagger-ui-wrap .markdown h4 { + color: #666666; +} +.swagger-section .swagger-ui-wrap .markdown pre { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + background-color: #fcf6db; + border: 1px solid #e5e0c6; + padding: 10px; + margin: 0 0 10px 0; +} +.swagger-section .swagger-ui-wrap .markdown pre code { + line-height: 1.6em; +} +.swagger-section .swagger-ui-wrap div.gist { + margin: 20px 0 25px 0 !important; +} +.swagger-section .swagger-ui-wrap ul#resources { + font-family: "Droid Sans", sans-serif; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource { + border-bottom: 1px solid #dddddd; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading h2 a, +.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading h2 a { + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource:hover div.heading ul.options li a, +.swagger-section .swagger-ui-wrap ul#resources li.resource.active div.heading ul.options li a { + color: #555555; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource:last-child { + border-bottom: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading { + border: 1px solid transparent; + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options { + overflow: hidden; + padding: 0; + display: block; + clear: none; + float: right; + margin: 14px 10px 0 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li { + float: left; + clear: none; + margin: 0; + padding: 2px 10px; + border-right: 1px solid #dddddd; + color: #666666; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a { + color: #aaaaaa; + text-decoration: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover { + text-decoration: underline; + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:hover, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a:active, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li a.active { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options li.last { + padding-right: 0; + border-right: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 { + color: #999999; + padding-left: 0; + display: block; + clear: none; + float: left; + font-family: "Droid Sans", sans-serif; + font-weight: bold; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a { + color: #999999; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover { + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation { + float: none; + clear: both; + overflow: hidden; + display: block; + margin: 0 0 10px; + padding: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading { + float: none; + clear: both; + overflow: hidden; + display: block; + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 { + display: block; + clear: none; + float: left; + width: auto; + margin: 0; + padding: 0; + line-height: 1.1em; + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path { + padding-left: 10px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a { + color: black; + text-decoration: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.path a:hover { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span.http_method a { + text-transform: uppercase; + text-decoration: none; + color: white; + display: inline-block; + width: 50px; + font-size: 0.7em; + text-align: center; + padding: 7px 0 4px; + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + -o-border-radius: 2px; + -ms-border-radius: 2px; + -khtml-border-radius: 2px; + border-radius: 2px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading h3 span { + margin: 0; + padding: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options { + overflow: hidden; + padding: 0; + display: block; + clear: none; + float: right; + margin: 6px 10px 0 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li { + float: left; + clear: none; + margin: 0; + padding: 2px 10px; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li a { + text-decoration: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.heading ul.options li.access { + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content { + border-top: none; + padding: 10px; + -moz-border-radius-bottomleft: 6px; + -webkit-border-bottom-left-radius: 6px; + -o-border-bottom-left-radius: 6px; + -ms-border-bottom-left-radius: 6px; + -khtml-border-bottom-left-radius: 6px; + border-bottom-left-radius: 6px; + -moz-border-radius-bottomright: 6px; + -webkit-border-bottom-right-radius: 6px; + -o-border-bottom-right-radius: 6px; + -ms-border-bottom-right-radius: 6px; + -khtml-border-bottom-right-radius: 6px; + border-bottom-right-radius: 6px; + margin: 0 0 20px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content h4 { + font-size: 1.1em; + margin: 0; + padding: 15px 0 5px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header { + float: none; + clear: both; + overflow: hidden; + display: block; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header a { + padding: 4px 0 0 10px; + display: inline-block; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header input.submit { + display: block; + clear: none; + float: left; + padding: 6px 8px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.sandbox_header span.response_throbber { + background-image: url('../images/throbber.gif'); + width: 128px; + height: 16px; + display: block; + clear: none; + float: right; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form input[type='text'].error { + outline: 2px solid black; + outline-color: #cc0000; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form select[name='parameterContentType'] { + max-width: 300px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + padding: 10px; + font-size: 0.9em; + max-height: 400px; + overflow-y: auto; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading { + background-color: #f9f2e9; + border: 1px solid #f0e0ca; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading h3 span.http_method a { + background-color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #f0e0ca; + color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li a { + color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content { + background-color: #faf5ee; + border: 1px solid #f0e0ca; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content h4 { + color: #c5862b; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content div.sandbox_header a { + color: #dcb67f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading { + background-color: #fcffcd; + border: 1px solid black; + border-color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading h3 span.http_method a { + text-transform: uppercase; + background-color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #ffd20f; + color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li a { + color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content { + background-color: #fcffcd; + border: 1px solid black; + border-color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content h4 { + color: #ffd20f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content div.sandbox_header a { + color: #6fc992; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading { + background-color: #f5e8e8; + border: 1px solid #e8c6c7; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading h3 span.http_method a { + text-transform: uppercase; + background-color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #e8c6c7; + color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li a { + color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content { + background-color: #f7eded; + border: 1px solid #e8c6c7; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content h4 { + color: #a41e22; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content div.sandbox_header a { + color: #c8787a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading { + background-color: #e7f6ec; + border: 1px solid #c3e8d1; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading h3 span.http_method a { + background-color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #c3e8d1; + color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li a { + color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content { + background-color: #ebf7f0; + border: 1px solid #c3e8d1; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content h4 { + color: #10a54a; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content div.sandbox_header a { + color: #6fc992; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading { + background-color: #FCE9E3; + border: 1px solid #F5D5C3; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading h3 span.http_method a { + background-color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #f0cecb; + color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li a { + color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content { + background-color: #faf0ef; + border: 1px solid #f0cecb; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content h4 { + color: #D38042; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content div.sandbox_header a { + color: #dcb67f; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading { + background-color: #e7f0f7; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading h3 span.http_method a { + background-color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #c3d9ec; + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li a { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content { + background-color: #ebf3f9; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content h4 { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content div.sandbox_header a { + color: #6fa5d2; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading { + background-color: #e7f0f7; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading h3 span.http_method a { + background-color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li { + border-right: 1px solid #dddddd; + border-right-color: #c3d9ec; + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.heading ul.options li a { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content { + background-color: #ebf3f9; + border: 1px solid #c3d9ec; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content h4 { + color: #0f6ab4; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.options div.content div.sandbox_header a { + color: #6fa5d2; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.content, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.content { + border-top: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li:last-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.get div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.post div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.head div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.put div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.patch div.heading ul.options li.last, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation.delete div.heading ul.options li.last { + padding-right: 0; + border-right: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:hover, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a:active, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li a.active { + text-decoration: underline; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations ul.options li.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations:first-child, +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations.first { + padding-left: 0; +} +.swagger-section .swagger-ui-wrap p#colophon { + margin: 0 15px 40px 15px; + padding: 10px 0; + font-size: 0.8em; + border-top: 1px solid #dddddd; + font-family: "Droid Sans", sans-serif; + color: #999999; + font-style: italic; +} +.swagger-section .swagger-ui-wrap p#colophon a { + text-decoration: none; + color: #547f00; +} +.swagger-section .swagger-ui-wrap h3 { + color: black; + font-size: 1.1em; + padding: 10px 0 10px 0; +} +.swagger-section .swagger-ui-wrap .markdown ol, +.swagger-section .swagger-ui-wrap .markdown ul { + font-family: "Droid Sans", sans-serif; + margin: 5px 0 10px; + padding: 0 0 0 18px; + list-style-type: disc; +} +.swagger-section .swagger-ui-wrap form.form_box { + background-color: #ebf3f9; + border: 1px solid #c3d9ec; + padding: 10px; +} +.swagger-section .swagger-ui-wrap form.form_box label { + color: #0f6ab4 !important; +} +.swagger-section .swagger-ui-wrap form.form_box input[type=submit] { + display: block; + padding: 10px; +} +.swagger-section .swagger-ui-wrap form.form_box p.weak { + font-size: 0.8em; +} +.swagger-section .swagger-ui-wrap form.form_box p { + font-size: 0.9em; + padding: 0 0 15px; + color: #7e7b6d; +} +.swagger-section .swagger-ui-wrap form.form_box p a { + color: #646257; +} +.swagger-section .swagger-ui-wrap form.form_box p strong { + color: black; +} +.swagger-section .swagger-ui-wrap .operation-status td.markdown > p:last-child { + padding-bottom: 0; +} +.swagger-section .title { + font-style: bold; +} +.swagger-section .secondary_form { + display: none; +} +.swagger-section .main_image { + display: block; + margin-left: auto; + margin-right: auto; +} +.swagger-section .oauth_body { + margin-left: 100px; + margin-right: 100px; +} +.swagger-section .oauth_submit { + text-align: center; +} +.swagger-section .api-popup-dialog { + z-index: 10000; + position: absolute; + width: 500px; + background: #FFF; + padding: 20px; + border: 1px solid #ccc; + border-radius: 5px; + display: none; + font-size: 13px; + color: #777; +} +.swagger-section .api-popup-dialog .api-popup-title { + font-size: 24px; + padding: 10px 0; +} +.swagger-section .api-popup-dialog .api-popup-title { + font-size: 24px; + padding: 10px 0; +} +.swagger-section .api-popup-dialog .error-msg { + padding-left: 5px; + padding-bottom: 5px; +} +.swagger-section .api-popup-dialog .api-popup-authbtn { + height: 30px; +} +.swagger-section .api-popup-dialog .api-popup-cancel { + height: 30px; +} +.swagger-section .api-popup-scopes { + padding: 10px 20px; +} +.swagger-section .api-popup-scopes li { + padding: 5px 0; + line-height: 20px; +} +.swagger-section .api-popup-scopes li input { + position: relative; + top: 2px; +} +.swagger-section .api-popup-scopes .api-scope-desc { + padding-left: 20px; + font-style: italic; +} +.swagger-section .api-popup-actions { + padding-top: 10px; +} +#header { + display: none; +} +.swagger-section .swagger-ui-wrap .model-signature pre { + max-height: none; +} +.swagger-section .swagger-ui-wrap .body-textarea { + width: 100px; +} +.swagger-section .swagger-ui-wrap input.parameter { + width: 100px; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading ul.options { + display: none; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints { + display: block !important; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content { + display: block !important; +} diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/screen.css b/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/screen.css index 478b99837d7..dc02468fdc0 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/screen.css +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/screen.css @@ -126,6 +126,7 @@ max-width: 960px; margin-left: auto; margin-right: auto; + /* JSONEditor specific styling */ } .swagger-section .swagger-ui-wrap b, .swagger-section .swagger-ui-wrap strong { @@ -274,6 +275,9 @@ font-weight: bold; font-size: 25px; } +.swagger-section .swagger-ui-wrap .footer { + margin-top: 20px; +} .swagger-section .swagger-ui-wrap p.big, .swagger-section .swagger-ui-wrap div.big p { font-size: 1em; @@ -294,7 +298,13 @@ .swagger-section .swagger-ui-wrap .message-fail { color: #cc0000; } -.swagger-section .swagger-ui-wrap .info_contact { +.swagger-section .swagger-ui-wrap .info_url { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_email { + padding-bottom: 5px; +} +.swagger-section .swagger-ui-wrap .info_name { padding-bottom: 5px; } .swagger-section .swagger-ui-wrap .info_description { @@ -350,7 +360,7 @@ font-size: .85em; line-height: 1.2em; overflow: auto; - max-height: 200px; + max-height: 400px; cursor: pointer; } .swagger-section .swagger-ui-wrap .model-signature ul.signature-nav { @@ -391,6 +401,43 @@ font-weight: bold; color: #000; } +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper { + border-spacing: 0; + position: absolute; + background-color: #ffffff; + border: 1px solid #bbbbbb; + display: none; + font-size: 11px; + max-width: 400px; + line-height: 30px; + color: black; + padding: 5px; + margin-left: 10px; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper th { + text-align: center; + background-color: #eeeeee; + border: 1px solid #bbbbbb; + font-size: 11px; + color: #666666; + font-weight: bold; + padding: 5px; + line-height: 15px; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propWrap .optionsWrapper .optionName { + font-weight: bold; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:first-child, +.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:last-child { + display: inline; +} +.swagger-section .swagger-ui-wrap .model-signature .description .propDesc.markdown > p:not(:first-child):before { + display: block; + content: ''; +} +.swagger-section .swagger-ui-wrap .model-signature .description span:last-of-type.propDesc.markdown > p:only-child { + margin-right: -3px; +} .swagger-section .swagger-ui-wrap .model-signature .propName { font-weight: bold; } @@ -412,6 +459,17 @@ .swagger-section .swagger-ui-wrap .required { font-weight: bold; } +.swagger-section .swagger-ui-wrap .editor_holder { + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + font-size: 0.9em; +} +.swagger-section .swagger-ui-wrap .editor_holder label { + font-weight: normal!important; + /* JSONEditor uses bold by default for all labels, we revert that back to normal to not give the impression that by default fields are required */ +} +.swagger-section .swagger-ui-wrap .editor_holder label.required { + font-weight: bold!important; +} .swagger-section .swagger-ui-wrap input.parameter { width: 300px; border: 1px solid #aaa; @@ -761,6 +819,9 @@ outline: 2px solid black; outline-color: #cc0000; } +.swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content form select[name='parameterContentType'] { + max-width: 300px; +} .swagger-section .swagger-ui-wrap ul#resources li.resource ul.endpoints li.endpoint ul.operations li.operation div.content div.response div.block pre { font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; padding: 10px; @@ -1034,6 +1095,9 @@ .swagger-section .swagger-ui-wrap form.form_box p strong { color: black; } +.swagger-section .swagger-ui-wrap .operation-status td.markdown > p:last-child { + padding-bottom: 0; +} .swagger-section .title { font-style: bold; } @@ -1072,14 +1136,14 @@ font-size: 24px; padding: 10px 0; } -.swagger-section .api-popup-dialog p.error-msg { +.swagger-section .api-popup-dialog .error-msg { padding-left: 5px; padding-bottom: 5px; } -.swagger-section .api-popup-dialog button.api-popup-authbtn { +.swagger-section .api-popup-dialog .api-popup-authbtn { height: 30px; } -.swagger-section .api-popup-dialog button.api-popup-cancel { +.swagger-section .api-popup-dialog .api-popup-cancel { height: 30px; } .swagger-section .api-popup-scopes { @@ -1089,14 +1153,14 @@ padding: 5px 0; line-height: 20px; } -.swagger-section .api-popup-scopes .api-scope-desc { - padding-left: 20px; - font-style: italic; -} .swagger-section .api-popup-scopes li input { position: relative; top: 2px; } +.swagger-section .api-popup-scopes .api-scope-desc { + padding-left: 20px; + font-style: italic; +} .swagger-section .api-popup-actions { padding-top: 10px; } @@ -1106,8 +1170,16 @@ .swagger-section .auth { float: right; } -.swagger-section #api_information_panel { - position: absolute; +.swagger-section .api-ic { + height: 18px; + vertical-align: middle; + display: inline-block; + background: url(../images/explorer_icons.png) no-repeat; +} +.swagger-section .api-ic .api_information_panel { + position: relative; + margin-top: 20px; + margin-left: -5px; background: #FFF; border: 1px solid #ccc; border-radius: 5px; @@ -1118,34 +1190,32 @@ color: black; padding: 5px; } -.swagger-section #api_information_panel p .api-msg-enabled { +.swagger-section .api-ic .api_information_panel p .api-msg-enabled { color: green; } -.swagger-section #api_information_panel p .api-msg-disabled { +.swagger-section .api-ic .api_information_panel p .api-msg-disabled { color: red; } -.swagger-section .api-ic { - height: 18px; - vertical-align: middle; - display: inline-block; - background: url(../images/explorer_icons.png) no-repeat; +.swagger-section .api-ic:hover .api_information_panel { + position: absolute; + display: block; } .swagger-section .ic-info { background-position: 0 0; width: 18px; - margin-top: -7px; + margin-top: -6px; margin-left: 4px; } .swagger-section .ic-warning { background-position: -60px 0; width: 18px; - margin-top: -7px; + margin-top: -6px; margin-left: 4px; } .swagger-section .ic-error { background-position: -30px 0; width: 18px; - margin-top: -7px; + margin-top: -6px; margin-left: 4px; } .swagger-section .ic-off { @@ -1161,42 +1231,39 @@ cursor: pointer; } .swagger-section #header { - background-color: #89bf04; + background-color: #646257; padding: 14px; } -.swagger-section #header a#logo { - font-size: 1.5em; - font-weight: bold; - text-decoration: none; - background: transparent url(../images/logo_small.png) no-repeat left center; - padding: 20px 0 20px 40px; - color: white; +.swagger-section #input_baseUrl { + width: 400px; } -.swagger-section #header form#api_selector { +.swagger-section #api_selector { display: block; clear: none; float: right; } -.swagger-section #header form#api_selector .input { +.swagger-section #api_selector .input { display: block; clear: none; float: left; margin: 0 10px 0 0; } -.swagger-section #header form#api_selector .input input#input_apiKey { +.swagger-section #api_selector input { + font-size: 0.9em; + padding: 3px; + margin: 0; +} +.swagger-section #input_apiKey { width: 200px; } -.swagger-section #header form#api_selector .input input#input_baseUrl { - width: 400px; -} -.swagger-section #header form#api_selector .input a#explore { +.swagger-section #explore { display: block; text-decoration: none; font-weight: bold; padding: 6px 8px; font-size: 0.9em; color: white; - background-color: #547f00; + background-color: #000000; -moz-border-radius: 4px; -webkit-border-radius: 4px; -o-border-radius: 4px; @@ -1204,13 +1271,16 @@ -khtml-border-radius: 4px; border-radius: 4px; } -.swagger-section #header form#api_selector .input a#explore:hover { - background-color: #547f00; +.swagger-section #explore:hover { + background-color: #a41e22; } -.swagger-section #header form#api_selector .input input { - font-size: 0.9em; - padding: 3px; - margin: 0; +.swagger-section #header #logo { + font-size: 1.5em; + font-weight: bold; + text-decoration: none; + background: transparent url(../images/logo_small.png) no-repeat left center; + padding: 20px 0 20px 40px; + color: white; } .swagger-section #content_message { margin: 10px 15px; @@ -1222,3 +1292,13 @@ text-align: center; padding-top: 10px; } +.swagger-section .swagger-collapse:before { + content: "-"; +} +.swagger-section .swagger-expand:before { + content: "+"; +} + +#input_baseUrl { + display: none; +} diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/style.css b/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/style.css new file mode 100644 index 00000000000..fc21a31db54 --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/style.css @@ -0,0 +1,250 @@ +.swagger-section #header a#logo { + font-size: 1.5em; + font-weight: bold; + text-decoration: none; + background: transparent url(../images/logo.png) no-repeat left center; + padding: 20px 0 20px 40px; +} +#text-head { + font-size: 80px; + font-family: 'Roboto', sans-serif; + color: #ffffff; + float: right; + margin-right: 20%; +} +.navbar-fixed-top .navbar-nav { + height: auto; +} +.navbar-fixed-top .navbar-brand { + height: auto; +} +.navbar-header { + height: auto; +} +.navbar-inverse { + background-color: #000; + border-color: #000; +} +#navbar-brand { + margin-left: 20%; +} +.navtext { + font-size: 10px; +} +.h1, +h1 { + font-size: 60px; +} +.navbar-default .navbar-header .navbar-brand { + color: #a2dfee; +} +/* tag titles */ +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a { + color: #393939; + font-family: 'Arvo', serif; + font-size: 1.5em; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 a:hover { + color: black; +} +.swagger-section .swagger-ui-wrap ul#resources li.resource div.heading h2 { + color: #525252; + padding-left: 0px; + display: block; + clear: none; + float: left; + font-family: 'Arvo', serif; + font-weight: bold; +} +.navbar-default .navbar-collapse, +.navbar-default .navbar-form { + border-color: #0A0A0A; +} +.container1 { + width: 1500px; + margin: auto; + margin-top: 0; + background-image: url('../images/shield.png'); + background-repeat: no-repeat; + background-position: -40px -20px; + margin-bottom: 210px; +} +.container-inner { + width: 1200px; + margin: auto; + background-color: rgba(223, 227, 228, 0.75); + padding-bottom: 40px; + padding-top: 40px; + border-radius: 15px; +} +.header-content { + padding: 0; + width: 1000px; +} +.title1 { + font-size: 80px; + font-family: 'Vollkorn', serif; + color: #404040; + text-align: center; + padding-top: 40px; + padding-bottom: 100px; +} +#icon { + margin-top: -18px; +} +.subtext { + font-size: 25px; + font-style: italic; + color: #08b; + text-align: right; + padding-right: 250px; +} +.bg-primary { + background-color: #00468b; +} +.navbar-default .nav > li > a, +.navbar-default .nav > li > a:focus { + color: #08b; +} +.navbar-default .nav > li > a, +.navbar-default .nav > li > a:hover { + color: #08b; +} +.navbar-default .nav > li > a, +.navbar-default .nav > li > a:focus:hover { + color: #08b; +} +.text-faded { + font-size: 25px; + font-family: 'Vollkorn', serif; +} +.section-heading { + font-family: 'Vollkorn', serif; + font-size: 45px; + padding-bottom: 10px; +} +hr { + border-color: #00468b; + padding-bottom: 10px; +} +.description { + margin-top: 20px; + padding-bottom: 200px; +} +.description li { + font-family: 'Vollkorn', serif; + font-size: 25px; + color: #525252; + margin-left: 28%; + padding-top: 5px; +} +.gap { + margin-top: 200px; +} +.troubleshootingtext { + color: rgba(255, 255, 255, 0.7); + padding-left: 30%; +} +.troubleshootingtext li { + list-style-type: circle; + font-size: 25px; + padding-bottom: 5px; +} +.overlay { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + z-index: 1000; +} +.block.response_body.json:hover { + cursor: pointer; +} +.backdrop { + color: blue; +} +#myModal { + height: 100%; +} +.modal-backdrop { + bottom: 0; + position: fixed; +} +.curl { + padding: 10px; + font-family: "Anonymous Pro", "Menlo", "Consolas", "Bitstream Vera Sans Mono", "Courier New", monospace; + font-size: 0.9em; + max-height: 400px; + margin-top: 5px; + overflow-y: auto; + background-color: #fcf6db; + border: 1px solid #e5e0c6; + border-radius: 4px; +} +.curl_title { + font-size: 1.1em; + margin: 0; + padding: 15px 0 5px; + font-family: 'Open Sans', 'Helvetica Neue', Arial, sans-serif; + font-weight: 500; + line-height: 1.1; +} +.footer { + display: none; +} +.swagger-section .swagger-ui-wrap h2 { + padding: 0; +} +h2 { + margin: 0; + margin-bottom: 5px; +} +.markdown p { + font-size: 15px; + font-family: 'Arvo', serif; +} +.swagger-section .swagger-ui-wrap .code { + font-size: 15px; + font-family: 'Arvo', serif; +} +.swagger-section .swagger-ui-wrap b { + font-family: 'Arvo', serif; +} +#signin:hover { + cursor: pointer; +} +.dropdown-menu { + padding: 15px; +} +.navbar-right .dropdown-menu { + left: 0; + right: auto; +} +#signinbutton { + width: 100%; + height: 32px; + font-size: 13px; + font-weight: bold; + color: #08b; +} +.navbar-default .nav > li .details { + color: #000000; + text-transform: none; + font-size: 15px; + font-weight: normal; + font-family: 'Open Sans', sans-serif; + font-style: italic; + line-height: 20px; + top: -2px; +} +.navbar-default .nav > li .details:hover { + color: black; +} +#signout { + width: 100%; + height: 32px; + font-size: 13px; + font-weight: bold; + color: #08b; +} diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/typography.css b/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/typography.css new file mode 100644 index 00000000000..3235edd9503 --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/css/typography.css @@ -0,0 +1,14 @@ +/* Google Font's Droid Sans */ +@font-face { + font-family: 'Droid Sans'; + font-style: normal; + font-weight: 400; + src: local('Droid Sans'), local('DroidSans'), url('../fonts/DroidSans.ttf') format('truetype'); +} +/* Google Font's Droid Sans Bold */ +@font-face { + font-family: 'Droid Sans'; + font-style: normal; + font-weight: 700; + src: local('Droid Sans Bold'), local('DroidSans-Bold'), url('../fonts/DroidSans-Bold.ttf') format('truetype'); +} diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/fonts/DroidSans-Bold.ttf b/htdocs/includes/restler/framework/Luracast/Restler/explorer/fonts/DroidSans-Bold.ttf new file mode 100644 index 00000000000..942bbf5ba3a Binary files /dev/null and b/htdocs/includes/restler/framework/Luracast/Restler/explorer/fonts/DroidSans-Bold.ttf differ diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/fonts/DroidSans.ttf b/htdocs/includes/restler/framework/Luracast/Restler/explorer/fonts/DroidSans.ttf new file mode 100644 index 00000000000..efd1f8bbd88 Binary files /dev/null and b/htdocs/includes/restler/framework/Luracast/Restler/explorer/fonts/DroidSans.ttf differ diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/images/collapse.gif b/htdocs/includes/restler/framework/Luracast/Restler/explorer/images/collapse.gif new file mode 100644 index 00000000000..8843e8ce5a4 Binary files /dev/null and b/htdocs/includes/restler/framework/Luracast/Restler/explorer/images/collapse.gif differ diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/images/expand.gif b/htdocs/includes/restler/framework/Luracast/Restler/explorer/images/expand.gif new file mode 100644 index 00000000000..477bf13718d Binary files /dev/null and b/htdocs/includes/restler/framework/Luracast/Restler/explorer/images/expand.gif differ diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/images/logo_small.png b/htdocs/includes/restler/framework/Luracast/Restler/explorer/images/logo_small.png index 5496a65579a..2ed3cf64be7 100644 Binary files a/htdocs/includes/restler/framework/Luracast/Restler/explorer/images/logo_small.png and b/htdocs/includes/restler/framework/Luracast/Restler/explorer/images/logo_small.png differ diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/images/pet_store_api.png b/htdocs/includes/restler/framework/Luracast/Restler/explorer/images/pet_store_api.png deleted file mode 100644 index f9f9cd4aeb3..00000000000 Binary files a/htdocs/includes/restler/framework/Luracast/Restler/explorer/images/pet_store_api.png and /dev/null differ diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/images/wordnik_api.png b/htdocs/includes/restler/framework/Luracast/Restler/explorer/images/wordnik_api.png deleted file mode 100644 index dca4f1455ac..00000000000 Binary files a/htdocs/includes/restler/framework/Luracast/Restler/explorer/images/wordnik_api.png and /dev/null differ diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/index.html b/htdocs/includes/restler/framework/Luracast/Restler/explorer/index.html index 0d73f19447e..c73f1981cc9 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/explorer/index.html +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/index.html @@ -1,85 +1,126 @@ + + Api Explorer - + - - + + - + - - - + + + + + + + + @@ -87,22 +128,14 @@ -
     
    +
     
    diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/en.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/en.js new file mode 100644 index 00000000000..9ccd65ad1d7 --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/en.js @@ -0,0 +1,55 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Warning: Deprecated", + "Implementation Notes":"Implementation Notes", + "Response Class":"Response Class", + "Status":"Status", + "Parameters":"Parameters", + "Parameter":"Parameter", + "Value":"Value", + "Description":"Description", + "Parameter Type":"Parameter Type", + "Data Type":"Data Type", + "Response Messages":"Response Messages", + "HTTP Status Code":"HTTP Status Code", + "Reason":"Reason", + "Response Model":"Response Model", + "Request URL":"Request URL", + "Response Body":"Response Body", + "Response Code":"Response Code", + "Response Headers":"Response Headers", + "Hide Response":"Hide Response", + "Headers":"Headers", + "Try it out!":"Try it out!", + "Show/Hide":"Show/Hide", + "List Operations":"List Operations", + "Expand Operations":"Expand Operations", + "Raw":"Raw", + "can't parse JSON. Raw result":"can't parse JSON. Raw result", + "Model Schema":"Model Schema", + "Model":"Model", + "Click to set as parameter value":"Click to set as parameter value", + "apply":"apply", + "Username":"Username", + "Password":"Password", + "Terms of service":"Terms of service", + "Created by":"Created by", + "See more at":"See more at", + "Contact the developer":"Contact the developer", + "api version":"api version", + "Response Content Type":"Response Content Type", + "Parameter content type:":"Parameter content type:", + "fetching resource":"fetching resource", + "fetching resource list":"fetching resource list", + "Explore":"Explore", + "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Can't read from server. It may not have the appropriate access-control-origin settings.", + "Please specify the protocol for":"Please specify the protocol for", + "Can't read swagger JSON from":"Can't read swagger JSON from", + "Finished Loading Resource Information. Rendering Swagger UI":"Finished Loading Resource Information. Rendering Swagger UI", + "Unable to read api":"Unable to read api", + "from path":"from path", + "server returned":"server returned" +}); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/es.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/es.js new file mode 100644 index 00000000000..a8dff60b6a9 --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/es.js @@ -0,0 +1,52 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Advertencia: Obsoleto", + "Implementation Notes":"Notas de implementación", + "Response Class":"Clase de la Respuesta", + "Status":"Status", + "Parameters":"Parámetros", + "Parameter":"Parámetro", + "Value":"Valor", + "Description":"Descripción", + "Parameter Type":"Tipo del Parámetro", + "Data Type":"Tipo del Dato", + "Response Messages":"Mensajes de la Respuesta", + "HTTP Status Code":"Código de Status HTTP", + "Reason":"Razón", + "Response Model":"Modelo de la Respuesta", + "Request URL":"URL de la Solicitud", + "Response Body":"Cuerpo de la Respuesta", + "Response Code":"Código de la Respuesta", + "Response Headers":"Encabezados de la Respuesta", + "Hide Response":"Ocultar Respuesta", + "Try it out!":"Pruébalo!", + "Show/Hide":"Mostrar/Ocultar", + "List Operations":"Listar Operaciones", + "Expand Operations":"Expandir Operaciones", + "Raw":"Crudo", + "can't parse JSON. Raw result":"no puede parsear el JSON. Resultado crudo", + "Model Schema":"Esquema del Modelo", + "Model":"Modelo", + "apply":"aplicar", + "Username":"Nombre de usuario", + "Password":"Contraseña", + "Terms of service":"Términos de Servicio", + "Created by":"Creado por", + "See more at":"Ver más en", + "Contact the developer":"Contactar al desarrollador", + "api version":"versión de la api", + "Response Content Type":"Tipo de Contenido (Content Type) de la Respuesta", + "fetching resource":"buscando recurso", + "fetching resource list":"buscando lista del recurso", + "Explore":"Explorar", + "Show Swagger Petstore Example Apis":"Mostrar Api Ejemplo de Swagger Petstore", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"No se puede leer del servidor. Tal vez no tiene la configuración de control de acceso de origen (access-control-origin) apropiado.", + "Please specify the protocol for":"Por favor, especificar el protocola para", + "Can't read swagger JSON from":"No se puede leer el JSON de swagger desde", + "Finished Loading Resource Information. Rendering Swagger UI":"Finalizada la carga del recurso de Información. Mostrando Swagger UI", + "Unable to read api":"No se puede leer la api", + "from path":"desde ruta", + "server returned":"el servidor retornó" +}); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/fr.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/fr.js new file mode 100644 index 00000000000..2e095ad0948 --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/fr.js @@ -0,0 +1,53 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Avertissement : Obsolète", + "Implementation Notes":"Notes d'implementation", + "Response Class":"Classe de la réponse", + "Status":"Statut", + "Parameters":"Paramètres", + "Parameter":"Paramètre", + "Value":"Valeur", + "Description":"Description", + "Parameter Type":"Type du paramètre", + "Data Type":"Type de données", + "Response Messages":"Messages de la réponse", + "HTTP Status Code":"Code de statut HTTP", + "Reason":"Raison", + "Response Model":"Modèle de réponse", + "Request URL":"URL appelée", + "Response Body":"Corps de la réponse", + "Response Code":"Code de la réponse", + "Response Headers":"En-têtes de la réponse", + "Hide Response":"Cacher la réponse", + "Headers":"En-têtes", + "Try it out!":"Testez !", + "Show/Hide":"Afficher/Masquer", + "List Operations":"Liste des opérations", + "Expand Operations":"Développer les opérations", + "Raw":"Brut", + "can't parse JSON. Raw result":"impossible de décoder le JSON. Résultat brut", + "Model Schema":"Définition du modèle", + "Model":"Modèle", + "apply":"appliquer", + "Username":"Nom d'utilisateur", + "Password":"Mot de passe", + "Terms of service":"Conditions de service", + "Created by":"Créé par", + "See more at":"Voir plus sur", + "Contact the developer":"Contacter le développeur", + "api version":"version de l'api", + "Response Content Type":"Content Type de la réponse", + "fetching resource":"récupération de la ressource", + "fetching resource list":"récupération de la liste de ressources", + "Explore":"Explorer", + "Show Swagger Petstore Example Apis":"Montrer les Apis de l'exemple Petstore de Swagger", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Impossible de lire à partir du serveur. Il se peut que les réglages access-control-origin ne soient pas appropriés.", + "Please specify the protocol for":"Veuillez spécifier un protocole pour", + "Can't read swagger JSON from":"Impossible de lire le JSON swagger à partir de", + "Finished Loading Resource Information. Rendering Swagger UI":"Chargement des informations terminé. Affichage de Swagger UI", + "Unable to read api":"Impossible de lire l'api", + "from path":"à partir du chemin", + "server returned":"réponse du serveur" +}); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/it.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/it.js new file mode 100644 index 00000000000..8529c2a90bc --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/it.js @@ -0,0 +1,52 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Attenzione: Deprecato", + "Implementation Notes":"Note di implementazione", + "Response Class":"Classe della risposta", + "Status":"Stato", + "Parameters":"Parametri", + "Parameter":"Parametro", + "Value":"Valore", + "Description":"Descrizione", + "Parameter Type":"Tipo di parametro", + "Data Type":"Tipo di dato", + "Response Messages":"Messaggi della risposta", + "HTTP Status Code":"Codice stato HTTP", + "Reason":"Motivo", + "Response Model":"Modello di risposta", + "Request URL":"URL della richiesta", + "Response Body":"Corpo della risposta", + "Response Code":"Oggetto della risposta", + "Response Headers":"Intestazioni della risposta", + "Hide Response":"Nascondi risposta", + "Try it out!":"Provalo!", + "Show/Hide":"Mostra/Nascondi", + "List Operations":"Mostra operazioni", + "Expand Operations":"Espandi operazioni", + "Raw":"Grezzo (raw)", + "can't parse JSON. Raw result":"non è possibile parsare il JSON. Risultato grezzo (raw).", + "Model Schema":"Schema del modello", + "Model":"Modello", + "apply":"applica", + "Username":"Nome utente", + "Password":"Password", + "Terms of service":"Condizioni del servizio", + "Created by":"Creato da", + "See more at":"Informazioni aggiuntive:", + "Contact the developer":"Contatta lo sviluppatore", + "api version":"versione api", + "Response Content Type":"Tipo di contenuto (content type) della risposta", + "fetching resource":"recuperando la risorsa", + "fetching resource list":"recuperando lista risorse", + "Explore":"Esplora", + "Show Swagger Petstore Example Apis":"Mostra le api di esempio di Swagger Petstore", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Non è possibile leggere dal server. Potrebbe non avere le impostazioni di controllo accesso origine (access-control-origin) appropriate.", + "Please specify the protocol for":"Si prega di specificare il protocollo per", + "Can't read swagger JSON from":"Impossibile leggere JSON swagger da:", + "Finished Loading Resource Information. Rendering Swagger UI":"Lettura informazioni risorse termianta. Swagger UI viene mostrata", + "Unable to read api":"Impossibile leggere la api", + "from path":"da cartella", + "server returned":"il server ha restituito" +}); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/ja.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/ja.js new file mode 100644 index 00000000000..3207bfc0baf --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/ja.js @@ -0,0 +1,53 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"警告: 廃止予定", + "Implementation Notes":"実装メモ", + "Response Class":"レスポンスクラス", + "Status":"ステータス", + "Parameters":"パラメータ群", + "Parameter":"パラメータ", + "Value":"値", + "Description":"説明", + "Parameter Type":"パラメータタイプ", + "Data Type":"データタイプ", + "Response Messages":"レスポンスメッセージ", + "HTTP Status Code":"HTTPステータスコード", + "Reason":"理由", + "Response Model":"レスポンスモデル", + "Request URL":"リクエストURL", + "Response Body":"レスポンスボディ", + "Response Code":"レスポンスコード", + "Response Headers":"レスポンスヘッダ", + "Hide Response":"レスポンスを隠す", + "Headers":"ヘッダ", + "Try it out!":"実際に実行!", + "Show/Hide":"表示/非表示", + "List Operations":"操作一覧", + "Expand Operations":"操作の展開", + "Raw":"Raw", + "can't parse JSON. Raw result":"JSONへ解釈できません. 未加工の結果", + "Model Schema":"モデルスキーマ", + "Model":"モデル", + "apply":"実行", + "Username":"ユーザ名", + "Password":"パスワード", + "Terms of service":"サービス利用規約", + "Created by":"Created by", + "See more at":"See more at", + "Contact the developer":"開発者に連絡", + "api version":"APIバージョン", + "Response Content Type":"レスポンス コンテンツタイプ", + "fetching resource":"リソースの取得", + "fetching resource list":"リソース一覧の取得", + "Explore":"Explore", + "Show Swagger Petstore Example Apis":"SwaggerペットストアAPIの表示", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"サーバから読み込めません. 適切なaccess-control-origin設定を持っていない可能性があります.", + "Please specify the protocol for":"プロトコルを指定してください", + "Can't read swagger JSON from":"次からswagger JSONを読み込めません", + "Finished Loading Resource Information. Rendering Swagger UI":"リソース情報の読み込みが完了しました. Swagger UIを描画しています", + "Unable to read api":"APIを読み込めません", + "from path":"次のパスから", + "server returned":"サーバからの返答" +}); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/pl.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/pl.js new file mode 100644 index 00000000000..ce41e91799d --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/pl.js @@ -0,0 +1,53 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Uwaga: Wycofane", + "Implementation Notes":"Uwagi Implementacji", + "Response Class":"Klasa Odpowiedzi", + "Status":"Status", + "Parameters":"Parametry", + "Parameter":"Parametr", + "Value":"Wartość", + "Description":"Opis", + "Parameter Type":"Typ Parametru", + "Data Type":"Typ Danych", + "Response Messages":"Wiadomości Odpowiedzi", + "HTTP Status Code":"Kod Statusu HTTP", + "Reason":"Przyczyna", + "Response Model":"Model Odpowiedzi", + "Request URL":"URL Wywołania", + "Response Body":"Treść Odpowiedzi", + "Response Code":"Kod Odpowiedzi", + "Response Headers":"Nagłówki Odpowiedzi", + "Hide Response":"Ukryj Odpowiedź", + "Headers":"Nagłówki", + "Try it out!":"Wypróbuj!", + "Show/Hide":"Pokaż/Ukryj", + "List Operations":"Lista Operacji", + "Expand Operations":"Rozwiń Operacje", + "Raw":"Nieprzetworzone", + "can't parse JSON. Raw result":"nie można przetworzyć pliku JSON. Nieprzetworzone dane", + "Model Schema":"Schemat Modelu", + "Model":"Model", + "apply":"użyj", + "Username":"Nazwa użytkownika", + "Password":"Hasło", + "Terms of service":"Warunki używania", + "Created by":"Utworzone przez", + "See more at":"Zobacz więcej na", + "Contact the developer":"Kontakt z deweloperem", + "api version":"wersja api", + "Response Content Type":"Typ Zasobu Odpowiedzi", + "fetching resource":"ładowanie zasobu", + "fetching resource list":"ładowanie listy zasobów", + "Explore":"Eksploruj", + "Show Swagger Petstore Example Apis":"Pokaż Przykładowe Api Swagger Petstore", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Brak połączenia z serwerem. Może on nie mieć odpowiednich ustawień access-control-origin.", + "Please specify the protocol for":"Proszę podać protokół dla", + "Can't read swagger JSON from":"Nie można odczytać swagger JSON z", + "Finished Loading Resource Information. Rendering Swagger UI":"Ukończono Ładowanie Informacji o Zasobie. Renderowanie Swagger UI", + "Unable to read api":"Nie można odczytać api", + "from path":"ze ścieżki", + "server returned":"serwer zwrócił" +}); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/pt.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/pt.js new file mode 100644 index 00000000000..f2e7c13d413 --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/pt.js @@ -0,0 +1,53 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Aviso: Depreciado", + "Implementation Notes":"Notas de Implementação", + "Response Class":"Classe de resposta", + "Status":"Status", + "Parameters":"Parâmetros", + "Parameter":"Parâmetro", + "Value":"Valor", + "Description":"Descrição", + "Parameter Type":"Tipo de parâmetro", + "Data Type":"Tipo de dados", + "Response Messages":"Mensagens de resposta", + "HTTP Status Code":"Código de status HTTP", + "Reason":"Razão", + "Response Model":"Modelo resposta", + "Request URL":"URL requisição", + "Response Body":"Corpo da resposta", + "Response Code":"Código da resposta", + "Response Headers":"Cabeçalho da resposta", + "Headers":"Cabeçalhos", + "Hide Response":"Esconder resposta", + "Try it out!":"Tente agora!", + "Show/Hide":"Mostrar/Esconder", + "List Operations":"Listar operações", + "Expand Operations":"Expandir operações", + "Raw":"Cru", + "can't parse JSON. Raw result":"Falha ao analisar JSON. Resulto cru", + "Model Schema":"Modelo esquema", + "Model":"Modelo", + "apply":"Aplicar", + "Username":"Usuário", + "Password":"Senha", + "Terms of service":"Termos do serviço", + "Created by":"Criado por", + "See more at":"Veja mais em", + "Contact the developer":"Contate o desenvolvedor", + "api version":"Versão api", + "Response Content Type":"Tipo de conteúdo da resposta", + "fetching resource":"busca recurso", + "fetching resource list":"buscando lista de recursos", + "Explore":"Explorar", + "Show Swagger Petstore Example Apis":"Show Swagger Petstore Example Apis", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Não é possível ler do servidor. Pode não ter as apropriadas configurações access-control-origin", + "Please specify the protocol for":"Por favor especifique o protocolo", + "Can't read swagger JSON from":"Não é possível ler o JSON Swagger de", + "Finished Loading Resource Information. Rendering Swagger UI":"Carregar informação de recurso finalizada. Renderizando Swagger UI", + "Unable to read api":"Não foi possível ler api", + "from path":"do caminho", + "server returned":"servidor retornou" +}); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/ru.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/ru.js new file mode 100644 index 00000000000..381f1b3fd0d --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/ru.js @@ -0,0 +1,55 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Предупреждение: Устарело", + "Implementation Notes":"Заметки", + "Response Class":"Пример ответа", + "Status":"Статус", + "Parameters":"Параметры", + "Parameter":"Параметр", + "Value":"Значение", + "Description":"Описание", + "Parameter Type":"Тип параметра", + "Data Type":"Тип данных", + "HTTP Status Code":"HTTP код", + "Reason":"Причина", + "Response Model":"Структура ответа", + "Request URL":"URL запроса", + "Response Body":"Тело ответа", + "Response Code":"HTTP код ответа", + "Response Headers":"Заголовки ответа", + "Hide Response":"Спрятать ответ", + "Headers":"Заголовки", + "Response Messages":"Что может прийти в ответ", + "Try it out!":"Попробовать!", + "Show/Hide":"Показать/Скрыть", + "List Operations":"Операции кратко", + "Expand Operations":"Операции подробно", + "Raw":"В сыром виде", + "can't parse JSON. Raw result":"Не удается распарсить ответ:", + "Model Schema":"Структура", + "Model":"Описание", + "Click to set as parameter value":"Нажмите, чтобы испльзовать в качестве значения параметра", + "apply":"применить", + "Username":"Имя пользователя", + "Password":"Пароль", + "Terms of service":"Условия использования", + "Created by":"Разработано", + "See more at":"Еще тут", + "Contact the developer":"Связаться с разработчиком", + "api version":"Версия API", + "Response Content Type":"Content Type ответа", + "Parameter content type:":"Content Type параметра:", + "fetching resource":"Получение ресурса", + "fetching resource list":"Получение ресурсов", + "Explore":"Показать", + "Show Swagger Petstore Example Apis":"Показать примеры АПИ", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Не удается получить ответ от сервера. Возможно, проблема с настройками доступа", + "Please specify the protocol for":"Пожалуйста, укажите протокол для", + "Can't read swagger JSON from":"Не получается прочитать swagger json из", + "Finished Loading Resource Information. Rendering Swagger UI":"Загрузка информации о ресурсах завершена. Рендерим", + "Unable to read api":"Не удалось прочитать api", + "from path":"по адресу", + "server returned":"сервер сказал" +}); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/tr.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/tr.js new file mode 100644 index 00000000000..16426a9c34b --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/tr.js @@ -0,0 +1,53 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"Uyarı: Deprecated", + "Implementation Notes":"Gerçekleştirim Notları", + "Response Class":"Dönen Sınıf", + "Status":"Statü", + "Parameters":"Parametreler", + "Parameter":"Parametre", + "Value":"Değer", + "Description":"Açıklama", + "Parameter Type":"Parametre Tipi", + "Data Type":"Veri Tipi", + "Response Messages":"Dönüş Mesajı", + "HTTP Status Code":"HTTP Statü Kodu", + "Reason":"Gerekçe", + "Response Model":"Dönüş Modeli", + "Request URL":"İstek URL", + "Response Body":"Dönüş İçeriği", + "Response Code":"Dönüş Kodu", + "Response Headers":"Dönüş Üst Bilgileri", + "Hide Response":"Dönüşü Gizle", + "Headers":"Üst Bilgiler", + "Try it out!":"Dene!", + "Show/Hide":"Göster/Gizle", + "List Operations":"Operasyonları Listele", + "Expand Operations":"Operasyonları Aç", + "Raw":"Ham", + "can't parse JSON. Raw result":"JSON çözümlenemiyor. Ham sonuç", + "Model Schema":"Model Şema", + "Model":"Model", + "apply":"uygula", + "Username":"Kullanıcı Adı", + "Password":"Parola", + "Terms of service":"Servis şartları", + "Created by":"Oluşturan", + "See more at":"Daha fazlası için", + "Contact the developer":"Geliştirici ile İletişime Geçin", + "api version":"api versiyon", + "Response Content Type":"Dönüş İçerik Tipi", + "fetching resource":"kaynak getiriliyor", + "fetching resource list":"kaynak listesi getiriliyor", + "Explore":"Keşfet", + "Show Swagger Petstore Example Apis":"Swagger Petstore Örnek Api'yi Gör", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"Sunucudan okuma yapılamıyor. Sunucu access-control-origin ayarlarınızı kontrol edin.", + "Please specify the protocol for":"Lütfen istenen adres için protokol belirtiniz", + "Can't read swagger JSON from":"Swagger JSON bu kaynaktan okunamıyor", + "Finished Loading Resource Information. Rendering Swagger UI":"Kaynak baglantısı tamamlandı. Swagger UI gösterime hazırlanıyor", + "Unable to read api":"api okunamadı", + "from path":"yoldan", + "server returned":"sunucuya dönüldü" +}); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/translator.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/translator.js new file mode 100644 index 00000000000..591f6d40943 --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/translator.js @@ -0,0 +1,39 @@ +'use strict'; + +/** + * Translator for documentation pages. + * + * To enable translation you should include one of language-files in your index.html + * after . + * For example - + * + * If you wish to translate some new texsts you should do two things: + * 1. Add a new phrase pair ("New Phrase": "New Translation") into your language file (for example lang/ru.js). It will be great if you add it in other language files too. + * 2. Mark that text it templates this way New Phrase or . + * The main thing here is attribute data-sw-translate. Only inner html, title-attribute and value-attribute are going to translate. + * + */ +window.SwaggerTranslator = { + + _words:[], + + translate: function(sel) { + var $this = this; + sel = sel || '[data-sw-translate]'; + + $(sel).each(function() { + $(this).html($this._tryTranslate($(this).html())); + + $(this).val($this._tryTranslate($(this).val())); + $(this).attr('title', $this._tryTranslate($(this).attr('title'))); + }); + }, + + _tryTranslate: function(word) { + return this._words[$.trim(word)] !== undefined ? this._words[$.trim(word)] : word; + }, + + learn: function(wordsMap) { + this._words = wordsMap; + } +}; diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/zh-cn.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/zh-cn.js new file mode 100644 index 00000000000..570319ba156 --- /dev/null +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lang/zh-cn.js @@ -0,0 +1,53 @@ +'use strict'; + +/* jshint quotmark: double */ +window.SwaggerTranslator.learn({ + "Warning: Deprecated":"警告:已过时", + "Implementation Notes":"实现备注", + "Response Class":"响应类", + "Status":"状态", + "Parameters":"参数", + "Parameter":"参数", + "Value":"值", + "Description":"描述", + "Parameter Type":"参数类型", + "Data Type":"数据类型", + "Response Messages":"响应消息", + "HTTP Status Code":"HTTP状态码", + "Reason":"原因", + "Response Model":"响应模型", + "Request URL":"请求URL", + "Response Body":"响应体", + "Response Code":"响应码", + "Response Headers":"响应头", + "Hide Response":"隐藏响应", + "Headers":"头", + "Try it out!":"试一下!", + "Show/Hide":"显示/隐藏", + "List Operations":"显示操作", + "Expand Operations":"展开操作", + "Raw":"原始", + "can't parse JSON. Raw result":"无法解析JSON. 原始结果", + "Model Schema":"模型架构", + "Model":"模型", + "apply":"应用", + "Username":"用户名", + "Password":"密码", + "Terms of service":"服务条款", + "Created by":"创建者", + "See more at":"查看更多:", + "Contact the developer":"联系开发者", + "api version":"api版本", + "Response Content Type":"响应Content Type", + "fetching resource":"正在获取资源", + "fetching resource list":"正在获取资源列表", + "Explore":"浏览", + "Show Swagger Petstore Example Apis":"显示 Swagger Petstore 示例 Apis", + "Can't read from server. It may not have the appropriate access-control-origin settings.":"无法从服务器读取。可能没有正确设置access-control-origin。", + "Please specify the protocol for":"请指定协议:", + "Can't read swagger JSON from":"无法读取swagger JSON于", + "Finished Loading Resource Information. Rendering Swagger UI":"已加载资源信息。正在渲染Swagger UI", + "Unable to read api":"无法读取api", + "from path":"从路径", + "server returned":"服务器返回" +}); diff --git a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/backbone-min.js b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/backbone-min.js index c1c0d4fff28..a3f544be6d9 100644 --- a/htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/backbone-min.js +++ b/htdocs/includes/restler/framework/Luracast/Restler/explorer/lib/backbone-min.js @@ -1,38 +1,15 @@ -// Backbone.js 0.9.2 +// Backbone.js 1.1.2 -// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc. -// Backbone may be freely distributed under the MIT license. -// For all details and documentation: -// http://backbonejs.org -(function(){var l=this,y=l.Backbone,z=Array.prototype.slice,A=Array.prototype.splice,g;g="undefined"!==typeof exports?exports:l.Backbone={};g.VERSION="0.9.2";var f=l._;!f&&"undefined"!==typeof require&&(f=require("underscore"));var i=l.jQuery||l.Zepto||l.ender;g.setDomLibrary=function(a){i=a};g.noConflict=function(){l.Backbone=y;return this};g.emulateHTTP=!1;g.emulateJSON=!1;var p=/\s+/,k=g.Events={on:function(a,b,c){var d,e,f,g,j;if(!b)return this;a=a.split(p);for(d=this._callbacks||(this._callbacks= -{});e=a.shift();)f=(j=d[e])?j.tail:{},f.next=g={},f.context=c,f.callback=b,d[e]={tail:g,next:j?j.next:f};return this},off:function(a,b,c){var d,e,h,g,j,q;if(e=this._callbacks){if(!a&&!b&&!c)return delete this._callbacks,this;for(a=a?a.split(p):f.keys(e);d=a.shift();)if(h=e[d],delete e[d],h&&(b||c))for(g=h.tail;(h=h.next)!==g;)if(j=h.callback,q=h.context,b&&j!==b||c&&q!==c)this.on(d,j,q);return this}},trigger:function(a){var b,c,d,e,f,g;if(!(d=this._callbacks))return this;f=d.all;a=a.split(p);for(g= -z.call(arguments,1);b=a.shift();){if(c=d[b])for(e=c.tail;(c=c.next)!==e;)c.callback.apply(c.context||this,g);if(c=f){e=c.tail;for(b=[b].concat(g);(c=c.next)!==e;)c.callback.apply(c.context||this,b)}}return this}};k.bind=k.on;k.unbind=k.off;var o=g.Model=function(a,b){var c;a||(a={});b&&b.parse&&(a=this.parse(a));if(c=n(this,"defaults"))a=f.extend({},c,a);b&&b.collection&&(this.collection=b.collection);this.attributes={};this._escapedAttributes={};this.cid=f.uniqueId("c");this.changed={};this._silent= -{};this._pending={};this.set(a,{silent:!0});this.changed={};this._silent={};this._pending={};this._previousAttributes=f.clone(this.attributes);this.initialize.apply(this,arguments)};f.extend(o.prototype,k,{changed:null,_silent:null,_pending:null,idAttribute:"id",initialize:function(){},toJSON:function(){return f.clone(this.attributes)},get:function(a){return this.attributes[a]},escape:function(a){var b;if(b=this._escapedAttributes[a])return b;b=this.get(a);return this._escapedAttributes[a]=f.escape(null== -b?"":""+b)},has:function(a){return null!=this.get(a)},set:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c||(c={});if(!d)return this;d instanceof o&&(d=d.attributes);if(c.unset)for(e in d)d[e]=void 0;if(!this._validate(d,c))return!1;this.idAttribute in d&&(this.id=d[this.idAttribute]);var b=c.changes={},h=this.attributes,g=this._escapedAttributes,j=this._previousAttributes||{};for(e in d){a=d[e];if(!f.isEqual(h[e],a)||c.unset&&f.has(h,e))delete g[e],(c.silent?this._silent: -b)[e]=!0;c.unset?delete h[e]:h[e]=a;!f.isEqual(j[e],a)||f.has(h,e)!=f.has(j,e)?(this.changed[e]=a,c.silent||(this._pending[e]=!0)):(delete this.changed[e],delete this._pending[e])}c.silent||this.change(c);return this},unset:function(a,b){(b||(b={})).unset=!0;return this.set(a,null,b)},clear:function(a){(a||(a={})).unset=!0;return this.set(f.clone(this.attributes),a)},fetch:function(a){var a=a?f.clone(a):{},b=this,c=a.success;a.success=function(d,e,f){if(!b.set(b.parse(d,f),a))return!1;c&&c(b,d)}; -a.error=g.wrapError(a.error,b,a);return(this.sync||g.sync).call(this,"read",this,a)},save:function(a,b,c){var d,e;f.isObject(a)||null==a?(d=a,c=b):(d={},d[a]=b);c=c?f.clone(c):{};if(c.wait){if(!this._validate(d,c))return!1;e=f.clone(this.attributes)}a=f.extend({},c,{silent:!0});if(d&&!this.set(d,c.wait?a:c))return!1;var h=this,i=c.success;c.success=function(a,b,e){b=h.parse(a,e);if(c.wait){delete c.wait;b=f.extend(d||{},b)}if(!h.set(b,c))return false;i?i(h,a):h.trigger("sync",h,a,c)};c.error=g.wrapError(c.error, -h,c);b=this.isNew()?"create":"update";b=(this.sync||g.sync).call(this,b,this,c);c.wait&&this.set(e,a);return b},destroy:function(a){var a=a?f.clone(a):{},b=this,c=a.success,d=function(){b.trigger("destroy",b,b.collection,a)};if(this.isNew())return d(),!1;a.success=function(e){a.wait&&d();c?c(b,e):b.trigger("sync",b,e,a)};a.error=g.wrapError(a.error,b,a);var e=(this.sync||g.sync).call(this,"delete",this,a);a.wait||d();return e},url:function(){var a=n(this,"urlRoot")||n(this.collection,"url")||t(); -return this.isNew()?a:a+("/"==a.charAt(a.length-1)?"":"/")+encodeURIComponent(this.id)},parse:function(a){return a},clone:function(){return new this.constructor(this.attributes)},isNew:function(){return null==this.id},change:function(a){a||(a={});var b=this._changing;this._changing=!0;for(var c in this._silent)this._pending[c]=!0;var d=f.extend({},a.changes,this._silent);this._silent={};for(c in d)this.trigger("change:"+c,this,this.get(c),a);if(b)return this;for(;!f.isEmpty(this._pending);){this._pending= -{};this.trigger("change",this,a);for(c in this.changed)!this._pending[c]&&!this._silent[c]&&delete this.changed[c];this._previousAttributes=f.clone(this.attributes)}this._changing=!1;return this},hasChanged:function(a){return!arguments.length?!f.isEmpty(this.changed):f.has(this.changed,a)},changedAttributes:function(a){if(!a)return this.hasChanged()?f.clone(this.changed):!1;var b,c=!1,d=this._previousAttributes,e;for(e in a)if(!f.isEqual(d[e],b=a[e]))(c||(c={}))[e]=b;return c},previous:function(a){return!arguments.length|| -!this._previousAttributes?null:this._previousAttributes[a]},previousAttributes:function(){return f.clone(this._previousAttributes)},isValid:function(){return!this.validate(this.attributes)},_validate:function(a,b){if(b.silent||!this.validate)return!0;var a=f.extend({},this.attributes,a),c=this.validate(a,b);if(!c)return!0;b&&b.error?b.error(this,c,b):this.trigger("error",this,c,b);return!1}});var r=g.Collection=function(a,b){b||(b={});b.model&&(this.model=b.model);b.comparator&&(this.comparator=b.comparator); -this._reset();this.initialize.apply(this,arguments);a&&this.reset(a,{silent:!0,parse:b.parse})};f.extend(r.prototype,k,{model:o,initialize:function(){},toJSON:function(a){return this.map(function(b){return b.toJSON(a)})},add:function(a,b){var c,d,e,g,i,j={},k={},l=[];b||(b={});a=f.isArray(a)?a.slice():[a];c=0;for(d=a.length;c=b))this.iframe=i('
    '.$langs->trans('DateDebCP').' ('.$langs->trans("FirstDayOfHoliday").')'.dol_print_date($object->date_debut,'day'); print '     '; - print $langs->trans($listhalfday[$starthalfday]); + print ''.$langs->trans($listhalfday[$starthalfday]).''; print '
    '.$langs->trans('DateFinCP').' ('.$langs->trans("LastDayOfHoliday").')'.dol_print_date($object->date_fin,'day'); print '     '; - print $langs->trans($listhalfday[$endhalfday]); + print ''.$langs->trans($listhalfday[$endhalfday]).''; print '
    '; - $holidaystatic->id=$infos_CP['rowid']; - $holidaystatic->ref=$infos_CP['rowid']; print $holidaystatic->getNomUrl(1); print ''.dol_print_date($date,'day').''.dol_print_date($infos_CP['date_debut'],'day').''.dol_print_date($infos_CP['date_fin'],'day').''; + print dol_print_date($infos_CP['date_debut'],'day'); + print ' ('.$langs->trans($listhalfday[$starthalfday]).')'; + print ''; + print dol_print_date($infos_CP['date_fin'],'day'); + print ' ('.$langs->trans($listhalfday[$endhalfday]).')'; + print ''.$holidaystatic->LibStatut($infos_CP['statut'],5).'