diff --git a/.travis.yml b/.travis.yml index 5bc5f49b2e5..54d937625ba 100644 --- a/.travis.yml +++ b/.travis.yml @@ -23,7 +23,7 @@ php: - 5.5 - 5.6 - 7.0 - + matrix: allow_failures: - php: 7.0 @@ -130,6 +130,8 @@ script: - php upgrade.php 3.7.0 3.8.0 ignoredbversion > upgrade370380.log # - cat upgrade370380.log - php upgrade2.php 3.7.0 3.8.0 ignoredbversion > upgrade370380-2.log + - php upgrade.php 3.8.0 3.9.0 ignoredbversion > upgrade380390.log + - php upgrade2.php 3.8.0 3.9.0 ignoredbversion > upgrade380390-2.log # - cat upgrade370380-2.log - cd ../.. - date diff --git a/COPYRIGHT b/COPYRIGHT index 40822059ab0..c38873a2f07 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -13,8 +13,9 @@ Component Version License GPL Compatible ------------------------------------------------------------------------------------- PHP libraries: AdoDb-Date 0.33 Modified BSD License Yes Date convertion (not into rpm package) -ChromePHP 4.3.3 Apache Software License 2.0 Yes Return server log to chrome browser console +ChromePHP 4.1.0 Apache Software License 2.0 Yes Return server log to chrome browser console CKEditor 4.3.3 LGPL-2.1+ Yes Editor WYSIWYG +EvalMath 1.0 BSD Yes Safe math expressions evaluation FPDI 1.5.2 Apache Software License 2.0 Yes PDF templates management GeoIP 1.4 LGPL-2.1+ Yes Sample code to make geoip convert (not into deb package) Mobiledetect 2.8.3 MIT License Yes Detect mobile devices browsers @@ -22,11 +23,12 @@ NuSoap 0.9.5 LGPL 2.1+ Yes PEAR Mail_MIME 1.8.9 BSD Yes NuSoap dependency odtPHP 1.0.1 GPL-2+ b Yes Library to build/edit ODT files PHPExcel 1.8.0 LGPL-2.1+ Yes Read/Write XLS files, read ODS files -php-iban 1.4.6 LGPL-3+ Yes Parse and validate IBAN (and IIBAN) bank account information in PHP +php-iban 1.4.7 LGPL-3+ Yes Parse and validate IBAN (and IIBAN) bank account information in PHP PHPPrintIPP 1.3 GPL-2+ Yes Library to send print IPP requests +Raven-php 0.12.1 MIT License Yes Used for server-side error logging with Sentry logger Restler 3.0 LGPL-3+ Yes Library to develop REST Web services TCPDF 6.2.6 LGPL-3+ Yes PDF generation -EvalMath 1.0 BSD Yes Safe math expressions evaluation +TCPDI 1.0.0 LGPL-3+ / Apache 2.0 Yes FPDI replacement JS libraries: jQuery 1.11.3 MIT License Yes JS library @@ -49,7 +51,8 @@ jQuery TableDnD 0.6 GPL and MIT License Yes jQuery Timepicker 1.1.0 GPL and MIT License Yes JS library Timepicker addon for Datepicker jQuery Tiptip 1.3 GPL and MIT License Yes JS library for tooltips jsGantt 1.2 BSD License Yes JS library (to build Gantt reports) -JsTimezoneDetect 1.0.4 MIT Licence Yes JS library to detect user timezone +JsTimezoneDetect 1.0.4 MIT License Yes JS library to detect user timezone +Raven.js 1.1.19 MIT License Yes Used for client-side error logging with Sentry logger For licenses compatibility informations: http://www.fsf.org/licensing/licenses/index_html diff --git a/ChangeLog b/ChangeLog index 960bc09756b..ff8a5763008 100644 --- a/ChangeLog +++ b/ChangeLog @@ -224,7 +224,7 @@ Dolibarr better: hook afterLogin or afterLoginFailed instead. - The trigger USER_CREATE_FROM_CONTACT has been replace with USER_CREATE and property context is now filled to make difference between creation from contact or not. - +- Function get_exdir require now 6 parameters. This is to prepare a future feature. ***** ChangeLog for 3.7.2 compared to 3.7.1 ***** FIX [ bug #2855 ] Wrong translation key in localtax report page @@ -238,6 +238,13 @@ FIX: Not showing delivery date on rouget pdf FIX: Not showing task extrafields when creating from left menu FIX [ bug #3288 ] Tasks box is not properly drawn FIX [ bug #3211 ] Outstading bill amount of a client showed wrong amounts +FIX [ bug #3321 ] Users with certain permissions were shown a "forbidden access" page even if they had the rights +FIX [ bug #3426 ] Unable to create an invoice from a contract with extrafields +FIX [ bug #3431 ] Invoice bank account is not respected +FIX [ bug #3432 ] Spaces should be removed from IBAN when formatting it +FIX [ bug #3358 ] Tasks box does not work with PostgreSQL +FIX [ bug #3383 ] Company name is overlapped with company direction in PDF models +FIX [ bug #3460 ] Bank account is not saved when creating a customer invoice and facing an error message NEW: Created new ContratLigne::insert function diff --git a/build.xml b/build.xml index 570821a7c7b..c6995ce95f3 100644 --- a/build.xml +++ b/build.xml @@ -1,6 +1,6 @@ + -fdfds diff --git a/build/debian/README.howto b/build/debian/README.howto index 6140412b831..92397130a3a 100644 --- a/build/debian/README.howto +++ b/build/debian/README.howto @@ -117,7 +117,7 @@ http://bugs.debian.org/package severity 123 xxx -##### Update but tracker system +##### Update bug tracker system To set status of a bug to "pending" > bts --smtp-host=yoursmtpserver tag 999999 +pending @@ -195,7 +195,7 @@ If script fails with error Bad certificate, you can set "export PERL_LWP_SSL_VER * Some files are removed from archive by the get-orig-source.sh * Staying into git root directory, run -> git-import-orig -vv ../tcpdf_x.y.z+dfsg.orig.tar.xz +> git-import-orig -vv ../tcpdf_x.y.z+dfsg.orig.tar.xz --debian-branch=[master|jessie] --upstream-branch=[upstream|upstream-3.5.x] Note: If there was errors solved manually, you may need to make a git commit @@ -208,11 +208,15 @@ Warning: Date must have format reported by "date -R" Warning: Name and email must match value into debian/control file (Entry added here is used by next step). * We try to build package -> rm -fr ../build-area; git-buildpackage -us -uc +> rm -fr ../build-area; +> git-buildpackage -us -uc --git-debian-branch=[master|jessie] --git-upstream-branch=[upstream|upstream-3.5.x] +Note: To build an old version, do: git checkout oldtagname -b newbranchname; git-buildpackage -us -uc --git-debian-branch=newbranchname --git-upstream-branch=[upstream|upstream-3.5.x] Note: You can use git-buildpackage -us -uc --git-ignore-new if you want to test build with uncommited file Note: You can use git-buildpackage -us -uc -d if you want to test build when dependencies does not match Note: Package is built into directory ../build-area +Note: To compare 2 packages: debdiff package1.dsc package2.dsc + * If package .deb is ok: Note: If there was errors managed manually, you may need to make a git commit but do not use option "amend" previous commit @@ -220,7 +224,7 @@ Note: If there was errors managed manually, you may need to make a git commit bu * If ok, you can tag. > Edit debian/changelog to replace "UNRELEASED" into "unstable", then push -> git-buildpackage --git-tag-only --git-retag +> git-buildpackage --git-tag-only --git-retag --git-debian-branch=[master|jessie] --git-upstream-branch=[upstream|upstream-3.5.x] > git push --tags * Compilation is then done by a debian developer and sent @@ -249,7 +253,7 @@ from git clone dir and make link to git. * If local branch upstream and pristine-tar does not exists, create it from origin/upstream and origin/pristine. -* If new upstream is available onto sourceforge, launch: +* When new upstream is available onto sourceforge, launch: > debian/get-orig-source.sh If script fails with error Bad certificate, you can set "export PERL_LWP_SSL_VERIFY_HOSTNAME=0" to solve this. @@ -263,7 +267,7 @@ dolibarr-x.y.z+dfsgw.tgz (x.y.z = version, w start from 1 and is increased for each new git-import-orig already done) * Staying into git root directory, run -> git-import-orig -vv ../dolibarr-x.y.z+dfsgw.tgz +> git-import-orig -vv ../dolibarr-x.y.z+dfsgw.tgz --debian-branch=[master|jessie] --upstream-branch=[upstream|upstream-3.5.x] and enter version when requested with format x.y.z+dfsgw (x.y.z = version, w start from 1 and is increased for each new import) @@ -273,8 +277,8 @@ Note: If there was errors solved manually after get-orig-sources.sh, you may nee * Fix debian/* files used to build package. Add an entry into debian/changelog > dch -v x.y.z+dfsgw-v "My comment" will add entry. -For example: dch -v x.y.z+dfsgw-1 "New upstream release." for a new version (x.y.z = version, w start from 1 and increaed for each new import) -Then modify changelog to replace "version" or "unstable" with "UNRELEASED". +For example: dch -v x.y.z+dfsgw-1 "New upstream release." for a new version (x.y.z = version, w start from 1 and increased for each new import) +Then check/modify changelog to replace "version" or "unstable" with "UNRELEASED". Then check/modify also the user/date signature: - Date must have format reported by "date -R" - Name and email must match value into debian/control file (Entry added here is used by next step). @@ -289,21 +293,24 @@ To update dolibarr debian package when only files into debian has changed Once files has been prepared, it's time to test: * Try to build package -> rm -fr ../build-area; git-buildpackage -us -uc +> rm -fr ../build-area; +> git-buildpackage -us -uc --git-debian-branch=[master|jessie] --git-upstream-branch=[upstream|upstream-3.5.x] +Note: To build an old version, do: git checkout oldtagname -b newbranchname; git-buildpackage -us -uc --git-debian-branch=newbranchname --git-upstream-branch=[upstream|upstream-3.5.x] Note: You can use git-buildpackage -us -uc --git-ignore-new if you want to test build with uncommited file Note: You can use git-buildpackage -us -uc -d if you want to test build when dependencies does not match Note: Package is built into directory ../build-area +Note: To compare 2 packages: debdiff package1.dsc package2.dsc * Test package (see dedicated chapter to test it with debian unstable env) * If package .deb is ok: Note: If there was errors managed manually, you may need to make a git commit but do not use option "amend" previous commit -> git push --all ou git push origin --all +> git push --all * If ok, you can tag. > Edit debian/changelog to replace "UNRELEASED" into "unstable", then push -> git-buildpackage --git-tag-only --git-retag +> git-buildpackage --git-tag-only --git-retag --git-debian-branch=[master|jessie] --git-upstream-branch=[upstream|upstream-3.5.x] > git push --tags @@ -321,15 +328,42 @@ http://packages.qa.debian.org ##### Send an unblock request + Use this to move from unstable to testing. -reportbug -B debian + +reportbug -B debian --smtphost=smtp.gmail.com:587 --smtpuser=xxxx --smtppasswd=yyyy --tls Choose package "release.debian.org" Then "unblock" Then name of package "dolibarr" Fill message, for example: "Please unblock package dolibarr -A security error CVE-2014-7137 was reported and is fixed into package 3.5.5. -Note that package 3.5.5 was prepared before the CVE was reported and include other fixes, but they are all related to stability or security (other se$ +A security error CVE-2015-3935 was reported and is fixed into package 3.5.7. +Note that package 3.5.7 contains not only fixed for bugs reported to debian. It includes other fixes, but they are all related to stability or security, +so it is a better solution to validate this maintenance release than applying a patch of the only CVE-2015-3935. After discussion with ..., it appears that security holes are enough to request this unblock request." +Use this to request an update of a stable package + +reportbug -B debian --smtphost=smtp.gmail.com:587 --smtpuser=xxxx --smtppasswd=yyyy --tls +Choose package "release.debian.org" +Then "unblock" +Then name of package "dolibarr" +Fill message, for example: +" +A security error CVE-2015-3935 was reported for Dolibarr ERP CRM package. This bug is fixed into official package 3.5.7 of Dolibarr. +Package 3.5.7 is a maintenance release compared to 3.5.5 and contains only fixes. But not only bugs reported to debian, it includes also other fixes (but they are all related to stability or security). +I think it is a better solution to validate this maintenance release based on the new upstream version of Dolibarr than applying a patch of the only CVE-2015-3935. +Pro are: +- It fixes all debian reported bugs (including security one) +- It fixes also stability bugs +- Patches were already tested because deployed and used by several thousands of users. +- It is easier for package maintener to include this official set of fixes than applying one patch after one patch for each debian report or backported each patch into a dedicated version. +- Debian maintenance version matches with official project maintenance version (better when all fixes are not related to the way the software is packaged) +Cons are: +- The patch include more than the only one security reported fxes + +So I just need to know if it's ok to push such a version 3.5.7 (fixes for 3.5.* branch) instead of only one fix for only the few (the only) reported debian bugs, +since it provides more stability and is or me a more secured process. +" + diff --git a/composer.json b/composer.json index ed75d3ca61d..cddc166bb42 100644 --- a/composer.json +++ b/composer.json @@ -6,27 +6,39 @@ "homepage": "http://www.dolibarr.org", "license": "GPL-3.0+", "support": { - "issues": "https://doliforge.org/projects/dolibarr", + "issues": "https://github.com/Dolibarr/dolibarr/issues", "forum": "http://www.dolibarr.org/forum", - "wiki": "http://wiki.dolibarr.org" + "wiki": "http://wiki.dolibarr.org", + "irc": "irc://chat.freenode.net/dolibarr", + "source": "https://github.com/Dolibarr/dolibarr" }, "require": { "php": ">=5.3.0", - "ext-gd": "*", "ext-curl": "*", - "restler/framework": "3.0.*" + "ccampbell/chromephp": "^4.1", + "ckeditor/ckeditor": "4.3.3", + "mobiledetect/mobiledetectlib": "2.8.3", + "phpoffice/phpexcel": "1.8.0", + "restler/framework": "^3.0", + "tecnick.com/tcpdf": "6.2.6", + "raven/raven": "^0.12.0" }, "suggest": { - "ext-mysqli": "*", - "ext-pgsql": "*", - "ext-mssql": "*", - "ext-pdo_sqlite": "*", - "ext-imagick": "*", - "ext-mcrypt": "*", - "ext-openssl": "*", - "ext-mbstring": "*", - "ext-soap": "*", - "ext-zip": "*", - "ext-xml": "*" + "ext-mysqlnd": "To use with MySQL or MariaDB", + "ext-mysqli": "To use with MySQL or MariaDB", + "ext-pgsql": "To use with PostgreSQL", + "ext-mssql": "To use with MSSQL (experimental)", + "ext-pdo_sqlite": "To use with SQLite (experimental)", + "ext-gd": "Image manipulation (Required but maybe built-in PHP)", + "ext-imagick": "Image manipulation (TCPDF)", + "ext-mcrypt": "(Required but maybe built-in PHP)", + "ext-openssl": "Secure connections (Emails, SOAP…)", + "ext-mbstring": "Handle non UTF-8 databases", + "ext-soap": "Native SOAP", + "ext-zip": "ODT and Excel support", + "ext-xml": "Excel support" + }, + "config": { + "vendor-dir": "htdocs/includes" } } diff --git a/composer.lock b/composer.lock new file mode 100644 index 00000000000..81c767d5e9b --- /dev/null +++ b/composer.lock @@ -0,0 +1,405 @@ +{ + "_readme": [ + "This file locks the dependencies of your project to a known state", + "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", + "This file is @generated automatically" + ], + "hash": "2ab34d0ff69b48500c20621330c1bfd7", + "packages": [ + { + "name": "ccampbell/chromephp", + "version": "4.1.0", + "source": { + "type": "git", + "url": "https://github.com/ccampbell/chromephp.git", + "reference": "c3c297615d48ae5b2a86a82311152d1ed095fcef" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ccampbell/chromephp/zipball/c3c297615d48ae5b2a86a82311152d1ed095fcef", + "reference": "c3c297615d48ae5b2a86a82311152d1ed095fcef", + "shasum": "" + }, + "require": { + "php": ">=5.0.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "ChromePhp": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "Apache-2.0" + ], + "authors": [ + { + "name": "Craig Campbell", + "email": "iamcraigcampbell@gmail.com", + "homepage": "http://craig.is", + "role": "Developer" + } + ], + "description": "Log variables to the Chrome console (via Chrome Logger Google Chrome extension).", + "homepage": "http://github.com/ccampbell/chromephp", + "keywords": [ + "log", + "logging" + ], + "time": "2013-06-26 03:44:33" + }, + { + "name": "ckeditor/ckeditor", + "version": "4.3.3", + "source": { + "type": "git", + "url": "https://github.com/ckeditor/ckeditor-releases.git", + "reference": "0068dd540ce8bf1815abb7b5455c55354bc56334" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/ckeditor/ckeditor-releases/zipball/0068dd540ce8bf1815abb7b5455c55354bc56334", + "reference": "0068dd540ce8bf1815abb7b5455c55354bc56334", + "shasum": "" + }, + "type": "library", + "notification-url": "https://packagist.org/downloads/", + "license": [ + "GPL-2.0+", + "LGPL-2.1+", + "MPL-1.1+" + ], + "authors": [ + { + "name": "CKSource - Frederico Knabben", + "homepage": "http://cksource.com" + } + ], + "description": "JavaScript WYSIWYG web text editor.", + "homepage": "http://ckeditor.com", + "keywords": [ + "CKEditor", + "editor", + "fckeditor", + "html", + "javascript", + "richtext", + "text", + "wysiwyg" + ], + "time": "2014-02-26 15:34:37" + }, + { + "name": "mobiledetect/mobiledetectlib", + "version": "2.8.3", + "source": { + "type": "git", + "url": "https://github.com/serbanghita/Mobile-Detect.git", + "reference": "f5753e4b90daffe50c902e99df5ce3c58fca3fee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/serbanghita/Mobile-Detect/zipball/f5753e4b90daffe50c902e99df5ce3c58fca3fee", + "reference": "f5753e4b90daffe50c902e99df5ce3c58fca3fee", + "shasum": "" + }, + "require": { + "php": ">=5.0.0" + }, + "require-dev": { + "phpunit/phpunit": "*" + }, + "type": "library", + "autoload": { + "classmap": [ + "Mobile_Detect.php" + ], + "psr-0": { + "Detection": "namespaced/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Serban Ghita", + "email": "serbanghita@gmail.com", + "homepage": "http://ghita.org", + "role": "Developer" + } + ], + "description": "Mobile_Detect is a lightweight PHP class for detecting mobile devices. It uses the User-Agent string combined with specific HTTP headers to detect the mobile environment.", + "homepage": "https://github.com/serbanghita/Mobile-Detect", + "keywords": [ + "detect mobile devices", + "mobile", + "mobile detect", + "mobile detector", + "php mobile detect" + ], + "time": "2014-07-10 20:00:25" + }, + { + "name": "phpoffice/phpexcel", + "version": "1.8.0", + "source": { + "type": "git", + "url": "https://github.com/PHPOffice/PHPExcel.git", + "reference": "e69a5e4d0ffa7fb6f171859e0a04346e580df30b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/PHPOffice/PHPExcel/zipball/e69a5e4d0ffa7fb6f171859e0a04346e580df30b", + "reference": "e69a5e4d0ffa7fb6f171859e0a04346e580df30b", + "shasum": "" + }, + "require": { + "ext-xml": "*", + "ext-xmlwriter": "*", + "php": ">=5.2.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "PHPExcel": "Classes/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL" + ], + "authors": [ + { + "name": "Maarten Balliauw", + "homepage": "http://blog.maartenballiauw.be" + }, + { + "name": "Mark Baker" + }, + { + "name": "Franck Lefevre", + "homepage": "http://blog.rootslabs.net" + }, + { + "name": "Erik Tilt" + } + ], + "description": "PHPExcel - OpenXML - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine", + "homepage": "http://phpexcel.codeplex.com", + "keywords": [ + "OpenXML", + "excel", + "php", + "spreadsheet", + "xls", + "xlsx" + ], + "time": "2014-03-02 15:22:49" + }, + { + "name": "raven/raven", + "version": "0.12.1", + "source": { + "type": "git", + "url": "https://github.com/getsentry/raven-php.git", + "reference": "b325984c792ff89f985b73da9a3ad8ed8b520bca" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/getsentry/raven-php/zipball/b325984c792ff89f985b73da9a3ad8ed8b520bca", + "reference": "b325984c792ff89f985b73da9a3ad8ed8b520bca", + "shasum": "" + }, + "require": { + "ext-curl": "*", + "php": ">=5.2.4" + }, + "require-dev": { + "fabpot/php-cs-fixer": "^1.8.0", + "phpunit/phpunit": "^4.6.6" + }, + "bin": [ + "bin/raven" + ], + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.12.x-dev" + } + }, + "autoload": { + "psr-0": { + "Raven_": "lib/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD" + ], + "authors": [ + { + "name": "David Cramer", + "email": "dcramer@gmail.com" + } + ], + "description": "A PHP client for Sentry (http://getsentry.com)", + "homepage": "http://getsentry.com", + "keywords": [ + "log", + "logging" + ], + "time": "2015-08-25 22:38:46" + }, + { + "name": "restler/framework", + "version": "3.0.0", + "target-dir": "Luracast/Restler", + "source": { + "type": "git", + "url": "https://github.com/Luracast/Restler-Framework.git", + "reference": "6ee10b3e5dbc6376916fed55ec2340a37cce436b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Luracast/Restler-Framework/zipball/6ee10b3e5dbc6376916fed55ec2340a37cce436b", + "reference": "6ee10b3e5dbc6376916fed55ec2340a37cce436b", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "replace": { + "luracast/restler": "3.*" + }, + "require-dev": { + "bshaffer/oauth2-server-php": "v1.0", + "luracast/explorer": "*", + "mustache/mustache": "dev-master", + "rodneyrehm/plist": "dev-master", + "symfony/yaml": "*", + "twig/twig": "v1.13.0", + "zendframework/zendamf": "dev-master" + }, + "suggest": { + "bshaffer/oauth2-server-php": "Restler can provide OAuth2 authentication using this library (see require-dev for details)", + "luracast/explorer": "Restler's very own api explorer (see require-dev for details)", + "mustache/mustache": "Restler can render HtmlView using mustache/handlebar templates (see require-dev for details)", + "rodneyrehm/plist": "Restler supports tho Apple plist xml format (see require-dev for details)", + "symfony/yaml": "Restler can produce content in yaml format as well (see require-dev for details)", + "twig/twig": "Restler can render HtmlView using twig templates (see require-dev for details)", + "zendframework/zendamf": "Support for the amf document format (see require-dev for details)" + }, + "type": "library", + "extra": { + "branch-alias": { + "master": "v3.0.x-dev" + } + }, + "autoload": { + "psr-0": { + "Luracast\\Restler": "" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPL-2.1" + ], + "authors": [ + { + "name": "Luracast", + "email": "arul@luracast.com" + }, + { + "name": "Nick nickl- Lombard", + "email": "github@jigsoft.co.za" + } + ], + "description": "Just the Restler Framework without the tests and examples", + "homepage": "http://luracast.com/products/restler/", + "keywords": [ + "api", + "framework", + "rest", + "server" + ], + "time": "2015-08-04 07:52:49" + }, + { + "name": "tecnick.com/tcpdf", + "version": "6.2.6", + "source": { + "type": "git", + "url": "https://github.com/tecnickcom/TCPDF.git", + "reference": "a2e8f5b505a7a14a4ed960313c4baf699fd1f4bb" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/tecnickcom/TCPDF/zipball/a2e8f5b505a7a14a4ed960313c4baf699fd1f4bb", + "reference": "a2e8f5b505a7a14a4ed960313c4baf699fd1f4bb", + "shasum": "" + }, + "require": { + "php": ">=5.3.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "fonts", + "config", + "include", + "tcpdf.php", + "tcpdf_parser.php", + "tcpdf_import.php", + "tcpdf_barcodes_1d.php", + "tcpdf_barcodes_2d.php", + "include/tcpdf_colors.php", + "include/tcpdf_filters.php", + "include/tcpdf_font_data.php", + "include/tcpdf_fonts.php", + "include/tcpdf_images.php", + "include/tcpdf_static.php", + "include/barcodes/datamatrix.php", + "include/barcodes/pdf417.php", + "include/barcodes/qrcode.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "LGPLv3" + ], + "authors": [ + { + "name": "Nicola Asuni", + "email": "info@tecnick.com", + "homepage": "http://nicolaasuni.tecnick.com" + } + ], + "description": "TCPDF is a PHP class for generating PDF documents and barcodes.", + "homepage": "http://www.tcpdf.org/", + "keywords": [ + "PDFD32000-2008", + "TCPDF", + "barcodes", + "datamatrix", + "pdf", + "pdf417", + "qrcode" + ], + "time": "2015-01-28 18:51:40" + } + ], + "packages-dev": [], + "aliases": [], + "minimum-stability": "stable", + "stability-flags": [], + "prefer-stable": false, + "prefer-lowest": false, + "platform": { + "php": ">=5.3.0", + "ext-curl": "*" + }, + "platform-dev": [] +} diff --git a/dev/dolibarr_changes.txt b/dev/dolibarr_changes.txt index bf68293d369..9d449070a5f 100644 --- a/dev/dolibarr_changes.txt +++ b/dev/dolibarr_changes.txt @@ -69,7 +69,7 @@ Add tcpdi.php Add tcpdi_parser.php and replace: require_once(dirname(__FILE__).'/include/tcpdf_filters.php'); with: -require_once(dirname(__FILE__).'/../tcpdf/include/tcpdf_filters.php'); +require_once(dirname(__FILE__).'/../tecnick.com/tcpdf/include/tcpdf_filters.php'); diff --git a/dev/fixdosfiles.sh b/dev/fixdosfiles.sh index 75dde68dcae..f770e28537d 100755 --- a/dev/fixdosfiles.sh +++ b/dev/fixdosfiles.sh @@ -24,7 +24,7 @@ fi # To convert if [ "x$1" = "xfix" ] then - for fic in `find . \( -iname "*.md" -o -iname "*.html" -o -iname "*.htm" -o -iname "*.php" -o -iname "*.sh" -o -iname "*.cml" -o -iname "*.css" -o -iname "*.js" -o -iname "*.lang" -o -iname "*.pl" -o -iname "*.txt" -o -iname "*.xml"\) -exec file "{}" + | grep CRLF | awk -F':' '{ print $1 }' ` + for fic in `find . \( -iname "*.md" -o -iname "*.html" -o -iname "*.htm" -o -iname "*.php" -o -iname "*.sh" -o -iname "*.cml" -o -iname "*.css" -o -iname "*.js" -o -iname "*.lang" -o -iname "*.pl" -o -iname "*.txt" -o -iname "*.xml" \) -exec file "{}" + | grep CRLF | awk -F':' '{ print $1 }' ` do echo "Fix file $fic" dos2unix $fic diff --git a/dev/skeletons/build_class_from_table.php b/dev/skeletons/build_class_from_table.php index 43f29a17ad3..6dac857ac11 100755 --- a/dev/skeletons/build_class_from_table.php +++ b/dev/skeletons/build_class_from_table.php @@ -69,8 +69,9 @@ if ($db->type != 'mysql' && $db->type != 'mysqli') } // Show parameters -print 'Tablename='.$argv[1]."\n"; -print "Current dir is ".getcwd()."\n"; +print 'Tablename: '.$argv[1]."\n"; +print "Current dir: ".getcwd()."\n"; +print "Database name: ".$db->database_name."\n"; // Define array with list of properties @@ -304,10 +305,9 @@ foreach($property as $key => $prop) } else { - $varprop.=' \'.(! isset($this->'.$prop['field'].')?\'NULL\':"\'".'; + $varprop.='\'.(! isset($this->'.$prop['field'].')?\'NULL\':"\'".'; $varprop.="\$this->".$prop['field'].""; - $varprop.='.\').'; - + $varprop.='"\'")'; } if ($i < (count($property)-$no_output_field)) $varprop.=".','"; diff --git a/dev/skeletons/modMyModule.class.php b/dev/skeletons/modMyModule.class.php index 7eebdee8bcd..8c55edc3d1a 100644 --- a/dev/skeletons/modMyModule.class.php +++ b/dev/skeletons/modMyModule.class.php @@ -193,7 +193,7 @@ class modMyModule extends DolibarrModules // Add here entries to declare new menus // // Example to declare a new Top Menu entry and its Left menu entry: - // $this->menu[$r]=array( 'fk_menu'=>0, // Put 0 if this is a top menu + // $this->menu[$r]=array( 'fk_menu'=>'', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode // 'type'=>'top', // This is a Top menu entry // 'titre'=>'MyModule top menu', // 'mainmenu'=>'mymodule', @@ -208,7 +208,7 @@ class modMyModule extends DolibarrModules // $r++; // // Example to declare a Left Menu entry into an existing Top menu entry: - // $this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=xxx', // Use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode + // $this->menu[$r]=array( 'fk_menu'=>'fk_mainmenu=xxx', // '' if this is a top menu. For left menu, use 'fk_mainmenu=xxx' or 'fk_mainmenu=xxx,fk_leftmenu=yyy' where xxx is mainmenucode and yyy is a leftmenucode // 'type'=>'left', // This is a Left menu entry // 'titre'=>'MyModule left menu', // 'mainmenu'=>'xxx', diff --git a/dev/skeletons/skeleton_class.class.php b/dev/skeletons/skeleton_class.class.php index 854e4a4fb47..2f8c78556e1 100644 --- a/dev/skeletons/skeleton_class.class.php +++ b/dev/skeletons/skeleton_class.class.php @@ -38,11 +38,6 @@ require_once DOL_DOCUMENT_ROOT . '/core/class/commonobject.class.php'; */ class Skeleton_Class extends CommonObject { - /** - * @var DoliDb Database handler - */ - protected $db; - /** * @var string Error code (or message) * @deprecated diff --git a/dev/skeletons/skeleton_page.php b/dev/skeletons/skeleton_page.php index 7665ce9986a..a74088b3702 100644 --- a/dev/skeletons/skeleton_page.php +++ b/dev/skeletons/skeleton_page.php @@ -43,7 +43,7 @@ if (! $res && file_exists("../../../dolibarr/htdocs/main.inc.php")) $res=@includ if (! $res && file_exists("../../../../dolibarr/htdocs/main.inc.php")) $res=@include '../../../../dolibarr/htdocs/main.inc.php'; // Used on dev env only if (! $res) die("Include of main fails"); // Change this following line to use the correct relative path from htdocs -include_once(DOL_DOCUMENT_ROOT.'/core/class/formcompany.class.php'); +include_once(DOL_DOCUMENT_ROOT.'/core/class/html.formcompany.class.php'); dol_include_once('/module/class/skeleton_class.class.php'); // Load traductions files requiredby by page @@ -62,7 +62,7 @@ if ($user->societe_id > 0) //accessforbidden(); } -if (empty($action) && empty($id) && empty($ref)) $action='create'; +if (empty($action) && empty($id) && empty($ref)) $action='list'; // Load object if id or ref is provided as parameter $object=new Skeleton_Class($db); @@ -225,7 +225,7 @@ jQuery(document).ready(function() { // Part to show a list -if ($action == 'list' || empty($id)) +if ($action == 'list' || (empty($id) && $action != 'create')) { $sql = "SELECT"; $sql.= " t.rowid,"; @@ -243,7 +243,7 @@ if ($action == 'list' || empty($id)) $parameters=array(); $reshook=$hookmanager->executeHooks('printFieldListWhere',$parameters); // Note that $action and $object may have been modified by hook $sql.=$hookmanager->resPrint; - $sql.= " ORDER BY field1 ASC"; + $sql.=$db->order($sortfield, $sortorder); print '
'; @@ -329,7 +329,7 @@ if ($action == 'list' || empty($id)) // Part to create if ($action == 'create') { - print_fiche_titre($langs->trans("NewResidence")); + print_fiche_titre($langs->trans("NewSkeleton")); print ''; print ''; diff --git a/dev/test/testtcpdf.php b/dev/test/testtcpdf.php index 4b8b6f36d53..6b600c630d3 100755 --- a/dev/test/testtcpdf.php +++ b/dev/test/testtcpdf.php @@ -27,8 +27,8 @@ * @since 2008-03-04 */ -require_once('../../htdocs/includes/tcpdf/config/lang/eng.php'); -require_once('../../htdocs/includes/tcpdf/tcpdf.php'); +require_once('../../htdocs/includes/tecnick.com/tcpdf/config/tcpdf_config.php'); +require_once('../../htdocs/includes/tecnick.com/tcpdf/tcpdf.php'); // create new PDF document $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); diff --git a/dev/test/testutf.php b/dev/test/testutf.php index 5812b0c8639..f60f9d195a3 100644 --- a/dev/test/testutf.php +++ b/dev/test/testutf.php @@ -47,8 +47,8 @@ print 'Files has been created. Check its name from your explorer'."\n"; * @since 2008-09-15 */ -require_once('../../htdocs/includes/tcpdf/config/lang/eng.php'); -require_once('../../htdocs/includes/tcpdf/tcpdf.php'); +require_once('../../htdocs/includes/tecnick.com/tcpdf/config/tcpdf_config.php'); +require_once('../../htdocs/includes/tecnick.com/tcpdf/tcpdf.php'); // create new PDF document $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false); diff --git a/htdocs/.gitignore b/htdocs/.gitignore index e26ae1a0f45..0b4d7b82790 100644 --- a/htdocs/.gitignore +++ b/htdocs/.gitignore @@ -12,3 +12,4 @@ /test.php /ultimatepdf* /lead +/dolimed* diff --git a/htdocs/accountancy/admin/account.php b/htdocs/accountancy/admin/account.php index bff9dbe4265..a56701dada2 100644 --- a/htdocs/accountancy/admin/account.php +++ b/htdocs/accountancy/admin/account.php @@ -106,7 +106,7 @@ llxHeader('', $langs->trans("ListAccounts")); $pcgver = $conf->global->CHARTOFACCOUNTS; $sql = "SELECT aa.rowid, aa.fk_pcg_version, aa.pcg_type, aa.pcg_subtype, aa.account_number, aa.account_parent , aa.label, aa.active "; -$sql .= " FROM " . MAIN_DB_PREFIX . "accountingaccount as aa, " . MAIN_DB_PREFIX . "accounting_system as asy"; +$sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as aa, " . MAIN_DB_PREFIX . "accounting_system as asy"; $sql .= " WHERE aa.fk_pcg_version = asy.pcg_version"; $sql .= " AND asy.rowid = " . $pcgver; @@ -173,11 +173,12 @@ if ($result) { print ''; print ''; - $var = true; + $var = false; $accountstatic=new AccountingAccount($db); - while ( $i < min($num, $limit) ) { + while ( $i < min($num, $limit) ) + { $obj = $db->fetch_object($resql); $accountstatic->id=$obj->rowid; diff --git a/htdocs/accountancy/admin/export.php b/htdocs/accountancy/admin/export.php index 3da29bd9cc1..6ba6c05208a 100644 --- a/htdocs/accountancy/admin/export.php +++ b/htdocs/accountancy/admin/export.php @@ -4,7 +4,7 @@ * Copyright (C) 2014 Florian Henry * Copyright (C) 2014 Marcos García * Copyright (C) 2014 Juanjo Menent - * Copyright (C) 2015 Jean-François Ferry + * Copyright (C) 2015 Jean-François Ferry * * 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 @@ -43,8 +43,12 @@ if (!$user->admin) $action = GETPOST('action', 'alpha'); -// Other parameters ACCOUNTING_EXPORT_* -$list = array ( +// Parameters ACCOUNTING_EXPORT_* +$main_option = array ( + 'ACCOUNTING_EXPORT_PREFIX_SPEC' +); + +$model_option = array ( 'ACCOUNTING_EXPORT_SEPARATORCSV', 'ACCOUNTING_EXPORT_DATE', 'ACCOUNTING_EXPORT_PIECE', @@ -60,10 +64,18 @@ $list = array ( if ($action == 'update') { $error = 0; + $format = GETPOST('format', 'alpha'); $modelcsv = GETPOST('modelcsv', 'int'); + + if (! empty($format)) { + if (! dolibarr_set_const($db, 'ACCOUNTING_EXPORT_FORMAT', $format, 'chaine', 0, '', $conf->entity)) { + $error ++; + } + } else { + $error ++; + } if (! empty($modelcsv)) { - if (! dolibarr_set_const($db, 'ACCOUNTING_EXPORT_MODELCSV', $modelcsv, 'chaine', 0, '', $conf->entity)) { $error ++; } @@ -71,7 +83,15 @@ if ($action == 'update') { $error ++; } - foreach ( $list as $constname ) { + foreach ($main_option as $constname) { + $constvalue = GETPOST($constname, 'alpha'); + + if (! dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) { + $error ++; + } + } + + foreach ($model_option as $constname) { $constvalue = GETPOST($constname, 'alpha'); if (! dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) { @@ -99,15 +119,74 @@ print_fiche_titre($langs->trans('ConfigAccountingExpert'),$linkback,'title_setup $head = admin_accounting_prepare_head(); -dol_fiche_head($head, 'export', $langs->trans("Configuration"), 0, 'cron'); print ''; print ''; print ''; -print ''; +dol_fiche_head($head, 'export', $langs->trans("Configuration"), 0, 'cron'); + $var = true; +/* + * Main Options + */ +print '
'; +print ''; +print ''; +print "\n"; + +$var = ! $var; + +print ''; +print ''; +if (! $conf->use_javascript_ajax) +{ + print '"; +} +else +{ + print ''; +} +print ""; + +$num = count($main_option); +if ($num) +{ + foreach ($main_option as $key) { + $var = ! $var; + + print ''; + + // Param + $label = $langs->trans($key); + print ''; + + // Value + print ''; + } +} + +print "
' . $langs->trans('MainOptions') . '
' . $langs->trans("Selectformat") . ''; + print $langs->trans("NotAvailableWhenAjaxDisabled"); + print "'; + $listformat=array( + 'csv'=>$langs->trans("csv"), + 'txt'=>$langs->trans("txt") + ); + print $form->selectarray("format",$listformat,$conf->global->ACCOUNTING_EXPORT_FORMAT,0); + + print '
' . $label . ''; + print ''; + print '
\n"; + +print "
\n"; + +/* + * Export model + */ +print ''; + print ''; print ''; print ''; @@ -142,8 +221,8 @@ print "
\n"; * Parameters */ -$num = count($list); -if ($num) +$num2 = count($model_option); +if ($num2) { print '
' . $langs->trans("Modelcsv") . '
'; print ''; @@ -151,7 +230,7 @@ if ($num) print "\n"; if ($conf->global->ACCOUNTING_EXPORT_MODELCSV > 1) print ''; - foreach ( $list as $key ) { + foreach ($model_option as $key) { $var = ! $var; print ''; @@ -169,7 +248,9 @@ if ($num) print "
' . $langs->trans('OptionsDeactivatedForThisExportModel') . '
\n"; } -print '
'; +dol_fiche_end(); + +print '
'; print ''; diff --git a/htdocs/accountancy/admin/importaccounts.php b/htdocs/accountancy/admin/importaccounts.php index e81557d0522..61e86b7df19 100644 --- a/htdocs/accountancy/admin/importaccounts.php +++ b/htdocs/accountancy/admin/importaccounts.php @@ -124,7 +124,7 @@ if ($result) { print ''; print ''; - print ''; + print ''; print ''; print ''; print ''; diff --git a/htdocs/accountancy/admin/index.php b/htdocs/accountancy/admin/index.php index fc8994c4836..44b2268dc06 100644 --- a/htdocs/accountancy/admin/index.php +++ b/htdocs/accountancy/admin/index.php @@ -157,12 +157,13 @@ print_fiche_titre($langs->trans('ConfigAccountingExpert'),$linkback,'title_setup $head = admin_accounting_prepare_head($accounting); -dol_fiche_head($head, 'general', $langs->trans("Configuration"), 0, 'cron'); print ''; print ''; print ''; +dol_fiche_head($head, 'general', $langs->trans("Configuration"), 0, 'cron'); + print '
' . $langs->trans("accountingaccount") . '
' . $langs->trans("AccountAccouting") . '' . $langs->trans("label") . '' . $langs->trans("Accountparent") . '' . $langs->trans("Pcgtype") . '
'; // Cas du parametre ACCOUNTING_MODE @@ -291,7 +292,11 @@ print ''; print "
\n"; -print '

'; +dol_fiche_end(); + +print '
'; + print ''; + llxFooter(); $db->close(); diff --git a/htdocs/accountancy/admin/journal.php b/htdocs/accountancy/admin/journal.php new file mode 100644 index 00000000000..e1d4894788a --- /dev/null +++ b/htdocs/accountancy/admin/journal.php @@ -0,0 +1,174 @@ + + * Copyright (C) 2013-2015 Alexandre Spangaro + * Copyright (C) 2014 Florian Henry + * Copyright (C) 2014 Marcos García + * Copyright (C) 2014 Juanjo Menent + * Copyright (C) 2015 Jean-François Ferry + * + * 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/accountancy/admin/journal.php + * \ingroup Accounting Expert + * \brief Setup page to configure accounting expert module + */ + +require '../../main.inc.php'; + +// Class +require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php'; +require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; + +$langs->load("accountancy"); + +// Security check +if (!$user->admin) + accessforbidden(); + +$action = GETPOST('action', 'alpha'); + +// Other parameters ACCOUNTING_* +$list = array ( + 'ACCOUNTING_SELL_JOURNAL', + 'ACCOUNTING_PURCHASE_JOURNAL', + 'ACCOUNTING_SOCIAL_JOURNAL', + 'ACCOUNTING_MISCELLANEOUS_JOURNAL', + 'ACCOUNTING_EXPENSEREPORT_JOURNAL' +); + +/* + * Actions + */ + +if ($action == 'update') { + $error = 0; + + foreach ( $list as $constname ) { + $constvalue = GETPOST($constname, 'alpha'); + + if (! dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) { + $error ++; + } + } + + if (! $error) { + setEventMessage($langs->trans("SetupSaved")); + } else { + setEventMessage($langs->trans("Error"), 'errors'); + } +} + +/* + * View + */ + +llxHeader(); + +$form = new Form($db); + +$linkback=''.$langs->trans("BackToModuleList").''; +print_fiche_titre($langs->trans('ConfigAccountingExpert'),$linkback,'title_setup'); + +$head = admin_accounting_prepare_head(null); + +print '
'; +print ''; +print ''; + +dol_fiche_head($head, 'journal', $langs->trans("Configuration"), 0, 'cron'); + +print ''; +print ''; +print ''; +print "\n"; + +foreach ( $list as $key ) { + $var = ! $var; + + print ''; + + // Param + $label = $langs->trans($key); + print ''; + + // Value + print ''; +} + +print "
' . $langs->trans('Journaux') . '
'; + print ''; + print '
\n"; + + +print '
'; + + +print ''; +print ''; +print ''; +print "\n"; + +// Bank account +$sql = "SELECT rowid, label, accountancy_journal"; +$sql.= " FROM ".MAIN_DB_PREFIX."bank_account"; +$sql.= " WHERE entity = ".$conf->entity; +$sql.= " AND clos = 0"; +$sql.= " ORDER BY label"; + +$resql = $db->query($sql); +if ($resql) +{ + $numr = $db->num_rows($resql); + $i = 0; + + if ($numr > 0) + + while ($i < $numr) + { + $objp = $db->fetch_object($resql); + + $var = ! $var; + + print ''; + + // Param + print ''; + + // Value + print ''; + + $i++; + } +} +else dol_print_error($db); +$db->free($resql); + +print "
' . $langs->trans('JournalFinancial') . '
'; + print ''; + print '
\n"; + +dol_fiche_end(); + +print '
'; + +print '
'; + + +llxFooter(); +$db->close(); \ No newline at end of file diff --git a/htdocs/accountancy/admin/journaux.php b/htdocs/accountancy/admin/journaux.php deleted file mode 100644 index e2359ebd8ee..00000000000 --- a/htdocs/accountancy/admin/journaux.php +++ /dev/null @@ -1,172 +0,0 @@ - - * Copyright (C) 2013-2015 Alexandre Spangaro - * Copyright (C) 2014 Florian Henry - * Copyright (C) 2014 Marcos García - * Copyright (C) 2014 Juanjo Menent - * Copyright (C) 2015 Jean-François Ferry - * - * 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/accountancy/admin/journaux.php - * \ingroup Accounting Expert - * \brief Setup page to configure accounting expert module - */ - -require '../../main.inc.php'; - -// Class -require_once DOL_DOCUMENT_ROOT.'/core/lib/admin.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/accounting.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/core/lib/bank.lib.php'; -require_once DOL_DOCUMENT_ROOT.'/compta/bank/class/account.class.php'; - -$langs->load("accountancy"); - -// Security check -if (!$user->admin) - accessforbidden(); - -$action = GETPOST('action', 'alpha'); - -// Other parameters ACCOUNTING_* -$list = array ( - 'ACCOUNTING_SELL_JOURNAL', - 'ACCOUNTING_PURCHASE_JOURNAL', - 'ACCOUNTING_SOCIAL_JOURNAL', - 'ACCOUNTING_MISCELLANEOUS_JOURNAL', - 'ACCOUNTING_EXPENSEREPORT_JOURNAL' -); - -/* - * Actions - */ - -if ($action == 'update') { - $error = 0; - - foreach ( $list as $constname ) { - $constvalue = GETPOST($constname, 'alpha'); - - if (! dolibarr_set_const($db, $constname, $constvalue, 'chaine', 0, '', $conf->entity)) { - $error ++; - } - } - - if (! $error) { - setEventMessage($langs->trans("SetupSaved")); - } else { - setEventMessage($langs->trans("Error"), 'errors'); - } -} - -/* - * View - */ - -llxHeader(); - -$form = new Form($db); - -$linkback=''.$langs->trans("BackToModuleList").''; -print_fiche_titre($langs->trans('ConfigAccountingExpert'),$linkback,'title_setup'); - -$head = admin_accounting_prepare_head(null); - -dol_fiche_head($head, 'journal', $langs->trans("Configuration"), 0, 'cron'); - -print '
'; -print ''; -print ''; - -print ''; -print ''; -print ''; -print "\n"; - -foreach ( $list as $key ) { - $var = ! $var; - - print ''; - - // Param - $label = $langs->trans($key); - print ''; - - // Value - print ''; -} - -print "
' . $langs->trans('Journaux') . '
'; - print ''; - print '
\n"; - -print '
'; -print '
'; - -print '
'; - -print ''; -print ''; -print ''; -print "\n"; - -// Bank account -$sql = "SELECT rowid, label, accountancy_journal"; -$sql.= " FROM ".MAIN_DB_PREFIX."bank_account"; -$sql.= " WHERE entity = ".$conf->entity; -$sql.= " AND clos = 0"; -$sql.= " ORDER BY label"; - -$resql = $db->query($sql); -if ($resql) -{ - $numr = $db->num_rows($resql); - $i = 0; - - if ($numr > 0) - - while ($i < $numr) - { - $objp = $db->fetch_object($resql); - - $var = ! $var; - - print ''; - - // Param - print ''; - - // Value - print ''; - - $i++; - } -} -else dol_print_error($db); -$db->free($resql); - -print "
' . $langs->trans('JournalFinancial') . '
'; - print ''; - print '
\n"; - -print ''; - -print '
'; - -llxFooter(); -$db->close(); \ No newline at end of file diff --git a/htdocs/accountancy/admin/productaccount.php b/htdocs/accountancy/admin/productaccount.php index 315c9f55325..d79d14e74d1 100644 --- a/htdocs/accountancy/admin/productaccount.php +++ b/htdocs/accountancy/admin/productaccount.php @@ -212,11 +212,11 @@ $pcgver = $conf->global->CHARTOFACCOUNTS; IF ($accounting_product_mode == 'ACCOUNTANCY_BUY' ? ' checked' : '') { $sql .= " p.accountancy_code_buy ='' OR p.accountancy_code_buy IS NULL"; $sql .= " OR (p.accountancy_code_buy IS NOT NULL AND p.accountancy_code_buy != '' AND p.accountancy_code_buy NOT IN - (SELECT aa.account_number FROM " . MAIN_DB_PREFIX . "accountingaccount as aa , " . MAIN_DB_PREFIX . "accounting_system as asy WHERE fk_pcg_version = asy.pcg_version AND asy.rowid = " . $pcgver . "))"; + (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 = " . $pcgver . "))"; } else { $sql .= " p.accountancy_code_sell ='' OR p.accountancy_code_sell IS NULL "; $sql .= " OR (p.accountancy_code_sell IS NOT NULL AND p.accountancy_code_sell != '' AND p.accountancy_code_sell NOT IN - (SELECT aa.account_number FROM " . MAIN_DB_PREFIX . "accountingaccount as aa , " . MAIN_DB_PREFIX . "accounting_system as asy WHERE fk_pcg_version = asy.pcg_version AND asy.rowid = " . $pcgver . "))"; + (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 = " . $pcgver . "))"; } $sql .= ")"; @@ -287,8 +287,9 @@ if ($result) { print '' . $langs->trans("Accountancy_code_sell_suggest") . ''; } // print_liste_field_titre(''); - print '' . $langs->trans("Ventilate") . '
/' . ''; + print_liste_field_titre($langs->trans("Ventilate") . '
/ '); print ''; + print ''; print ''; print ''; @@ -359,7 +360,7 @@ if ($result) { // print '' . $compta_prodbuy . ''; // TODO: we shoul set a user defined value to adjust user square / wide screen size // $trunclenghform = defined('ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT') ? ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT : 50; - print ''; + print ''; print $form->select_account($compta_prodbuy_id, 'codeventil_'.$product_static->id, 1); print ''; } else { @@ -369,7 +370,7 @@ if ($result) { // TODO: replace by select // TODO: we shoul set a user defined value to adjust user square / wide screen size // $trunclenghform = defined('ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT') ? ACCOUNTING_LENGTH_DESCRIPTION_ACCOUNT : 50; - print ''; + print ''; print $form->select_account($compta_prodsell_id, 'codeventil_'.$product_static->id, 1); print ''; } diff --git a/htdocs/accountancy/class/accountingaccount.class.php b/htdocs/accountancy/class/accountingaccount.class.php index cb7787610f8..856306c3304 100644 --- a/htdocs/accountancy/class/accountingaccount.class.php +++ b/htdocs/accountancy/class/accountingaccount.class.php @@ -72,7 +72,7 @@ class AccountingAccount extends CommonObject if ($rowid || $account_number) { $sql = "SELECT rowid, datec, tms, fk_pcg_version, pcg_type, pcg_subtype, account_number, account_parent, label, fk_user_author, fk_user_modif, active"; - $sql.= " FROM " . MAIN_DB_PREFIX . "accountingaccount WHERE"; + $sql.= " FROM " . MAIN_DB_PREFIX . "accounting_account WHERE"; if ($rowid) { $sql .= " rowid = '" . $rowid . "'"; } elseif ($account_number) { @@ -114,7 +114,7 @@ class AccountingAccount extends CommonObject } /** - * Insert line in accountingaccount + * Insert line in accounting_account * * @param User $user Use making action * @param int $notrigger Disable triggers @@ -148,7 +148,7 @@ class AccountingAccount extends CommonObject // Put here code to add control on parameters values // Insert request - $sql = "INSERT INTO " . MAIN_DB_PREFIX . "accountingaccount("; + $sql = "INSERT INTO " . MAIN_DB_PREFIX . "accounting_account("; $sql .= "datec"; $sql .= ", entity"; @@ -186,7 +186,7 @@ class AccountingAccount extends CommonObject } if (! $error) { - $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "accountingaccount"); + $this->id = $this->db->last_insert_id(MAIN_DB_PREFIX . "accounting_account"); // if (! $notrigger) { // Uncomment this and change MYOBJECT to your own tag if you @@ -225,7 +225,7 @@ class AccountingAccount extends CommonObject { $this->db->begin(); - $sql = "UPDATE " . MAIN_DB_PREFIX . "accountingaccount "; + $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account "; $sql .= " SET fk_pcg_version = " . ($this->fk_pcg_version ? "'" . $this->db->escape($this->fk_pcg_version) . "'" : "null"); $sql .= " , pcg_type = " . ($this->pcg_type ? "'" . $this->db->escape($this->pcg_type) . "'" : "null"); $sql .= " , pcg_subtype = " . ($this->pcg_subtype ? "'" . $this->db->escape($this->pcg_subtype) . "'" : "null"); @@ -313,7 +313,7 @@ class AccountingAccount extends CommonObject // } if (! $error) { - $sql = "DELETE FROM " . MAIN_DB_PREFIX . "accountingaccount"; + $sql = "DELETE FROM " . MAIN_DB_PREFIX . "accounting_account"; $sql .= " WHERE rowid=" . $this->id; dol_syslog(get_class($this) . "::delete sql=" . $sql); @@ -375,7 +375,7 @@ class AccountingAccount extends CommonObject function info($id) { $sql = 'SELECT a.rowid, a.datec, a.fk_user_author, a.fk_user_modif, a.tms'; - $sql .= ' FROM ' . MAIN_DB_PREFIX . 'accountingaccount as a'; + $sql .= ' FROM ' . MAIN_DB_PREFIX . 'accounting_account as a'; $sql .= ' WHERE a.rowid = ' . $id; dol_syslog(get_class($this) . '::info sql=' . $sql); @@ -417,7 +417,7 @@ class AccountingAccount extends CommonObject if ($result > 0) { $this->db->begin(); - $sql = "UPDATE " . MAIN_DB_PREFIX . "accountingaccount "; + $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account "; $sql .= "SET active = '0'"; $sql .= " WHERE rowid = ".$this->db->escape($id); @@ -447,7 +447,7 @@ class AccountingAccount extends CommonObject { $this->db->begin(); - $sql = "UPDATE " . MAIN_DB_PREFIX . "accountingaccount "; + $sql = "UPDATE " . MAIN_DB_PREFIX . "accounting_account "; $sql .= "SET active = '1'"; $sql .= " WHERE rowid = ".$this->db->escape($id); diff --git a/htdocs/accountancy/class/html.formventilation.class.php b/htdocs/accountancy/class/html.formventilation.class.php index b86c0fdd2e2..de94d645c92 100644 --- a/htdocs/accountancy/class/html.formventilation.class.php +++ b/htdocs/accountancy/class/html.formventilation.class.php @@ -94,7 +94,7 @@ class FormVentilation extends Form * @param array $event Event options * @param int $select_in $selectid value is a aa.rowid (0 default) or aa.account_number (1) * @param int $select_out set value returned by select 0=rowid (default), 1=account_number - * @param int $aabase set accountingaccount base class to display empty=all or from 1 to 8 will display only account beginning by + * @param int $aabase set accounting_account base class to display empty=all or from 1 to 8 will display only account beginning by * * @return string String with HTML select */ @@ -105,7 +105,7 @@ class FormVentilation extends Form $out = ''; $sql = "SELECT DISTINCT aa.account_number, aa.label, aa.rowid, aa.fk_pcg_version"; - $sql .= " FROM " . MAIN_DB_PREFIX . "accountingaccount as aa"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as aa"; $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version"; $sql .= " AND asy.rowid = " . $conf->global->CHARTOFACCOUNTS; $sql .= " AND aa.active = 1"; @@ -132,7 +132,7 @@ class FormVentilation extends Form if ($select_in == 1 ) $select_value_in = $obj->account_number; if ($select_out == 0 ) $select_value_out = $obj->rowid; if ($select_out == 1 ) $select_value_out = $obj->account_number; - // Remember guy's we store in database llx_facturedet the rowid of accountingaccount and not the account_number + // Remember guy's we store in database llx_facturedet the rowid of accounting_account and not the account_number // Because same account_number can be share between different accounting_system and do have the same meaning if (($selectid != '') && $selectid == $select_value_in) { // $out .= ''; @@ -171,7 +171,7 @@ class FormVentilation extends Form $out = ''; $sql = "SELECT DISTINCT pcg_type "; - $sql .= " FROM " . MAIN_DB_PREFIX . "accountingaccount as aa"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as aa"; $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version"; $sql .= " AND asy.rowid = " . $conf->global->CHARTOFACCOUNTS; $sql .= " ORDER BY pcg_type"; @@ -227,7 +227,7 @@ class FormVentilation extends Form $out = ''; $sql = "SELECT DISTINCT pcg_subtype "; - $sql .= " FROM " . MAIN_DB_PREFIX . "accountingaccount as aa"; + $sql .= " FROM " . MAIN_DB_PREFIX . "accounting_account as aa"; $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "accounting_system as asy ON aa.fk_pcg_version = asy.pcg_version"; $sql .= " AND asy.rowid = " . $conf->global->CHARTOFACCOUNTS; $sql .= " ORDER BY pcg_subtype"; diff --git a/htdocs/accountancy/customer/card.php b/htdocs/accountancy/customer/card.php index 03f6b817101..74083cbb215 100644 --- a/htdocs/accountancy/customer/card.php +++ b/htdocs/accountancy/customer/card.php @@ -85,7 +85,7 @@ if (! empty($id)) { $sql .= " l.fk_code_ventilation, aa.account_number, aa.label"; $sql .= " FROM " . MAIN_DB_PREFIX . "facturedet as l"; $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "product as p ON p.rowid = l.fk_product"; - $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accountingaccount as aa ON l.fk_code_ventilation = aa.rowid"; + $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON l.fk_code_ventilation = aa.rowid"; $sql .= " INNER JOIN " . MAIN_DB_PREFIX . "facture as f ON f.rowid = l.fk_facture"; $sql .= " WHERE f.fk_statut > 0 AND l.rowid = " . $id; diff --git a/htdocs/accountancy/customer/index.php b/htdocs/accountancy/customer/index.php index 24c0e81587f..e4c6104fd1b 100644 --- a/htdocs/accountancy/customer/index.php +++ b/htdocs/accountancy/customer/index.php @@ -65,12 +65,12 @@ if ($action == 'validatehistory') { if ($db->type == 'pgsql') { $sql1 = "UPDATE " . MAIN_DB_PREFIX . "facturedet as fd"; $sql1 .= " SET fd.fk_code_ventilation = accnt.rowid"; - $sql1 .= " FROM " . MAIN_DB_PREFIX . "product as p, " . MAIN_DB_PREFIX . "accountingaccount as accnt , " . MAIN_DB_PREFIX . "accounting_system as syst"; + $sql1 .= " FROM " . MAIN_DB_PREFIX . "product as p, " . MAIN_DB_PREFIX . "accounting_account as accnt , " . MAIN_DB_PREFIX . "accounting_system as syst"; $sql1 .= " WHERE fd.fk_product = p.rowid AND accnt.fk_pcg_version = syst.pcg_version AND syst.rowid=" . $conf->global->CHARTOFACCOUNTS; $sql1 .= " AND accnt.active = 1 AND p.accountancy_code_sell=accnt.account_number"; $sql1 .= " AND fd.fk_code_ventilation = 0"; } else { - $sql1 = "UPDATE " . MAIN_DB_PREFIX . "facturedet as fd, " . MAIN_DB_PREFIX . "product as p, " . MAIN_DB_PREFIX . "accountingaccount as accnt , " . MAIN_DB_PREFIX . "accounting_system as syst"; + $sql1 = "UPDATE " . MAIN_DB_PREFIX . "facturedet as fd, " . MAIN_DB_PREFIX . "product as p, " . MAIN_DB_PREFIX . "accounting_account as accnt , " . MAIN_DB_PREFIX . "accounting_system as syst"; $sql1 .= " SET fd.fk_code_ventilation = accnt.rowid"; $sql1 .= " WHERE fd.fk_product = p.rowid AND accnt.fk_pcg_version = syst.pcg_version AND syst.rowid=" . $conf->global->CHARTOFACCOUNTS; $sql1 .= " AND accnt.active = 1 AND p.accountancy_code_sell=accnt.account_number"; @@ -154,7 +154,7 @@ $sql .= " ROUND(SUM(IF(MONTH(f.datef)=12,fd.total_ht,0)),2) AS 'Decembre',"; $sql .= " ROUND(SUM(fd.total_ht),2) as 'Total'"; $sql .= " FROM " . MAIN_DB_PREFIX . "facturedet as fd"; $sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "facture as f ON f.rowid = fd.fk_facture"; -$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accountingaccount as aa ON aa.rowid = fd.fk_code_ventilation"; +$sql .= " LEFT JOIN " . MAIN_DB_PREFIX . "accounting_account as aa ON aa.rowid = fd.fk_code_ventilation"; $sql .= " WHERE f.datef >= '" . $db->idate(dol_get_first_day($y, 1, false)) . "'"; $sql .= " AND f.datef <= '" . $db->idate(dol_get_last_day($y, 12, false)) . "'"; diff --git a/htdocs/accountancy/customer/lines.php b/htdocs/accountancy/customer/lines.php index ba7d35cee70..01f34e700cc 100644 --- a/htdocs/accountancy/customer/lines.php +++ b/htdocs/accountancy/customer/lines.php @@ -154,7 +154,7 @@ print ''."\n"; + } + + print '
'; print ''; print ''; - print_fiche_titre($langs->trans("NewVATPayment")); - + print '
'; + print '
'; + print $langs->trans("Type").':   '; + print '
'; + print ''; + print '   '; + print ''; + print '
'; + print "
\n"; + dol_fiche_head(); print ''; @@ -202,7 +242,12 @@ if ($action == 'create') print ''; // Label - print ''; + if ($refund == 1) { + $label = $langs->trans("VATRefund"); + } else { + $label = $langs->trans("VATPayment"); + } + print ''; // Amount print ''; diff --git a/htdocs/compta/tva/class/tva.class.php b/htdocs/compta/tva/class/tva.class.php index a938087c689..68aeeebc2c8 100644 --- a/htdocs/compta/tva/class/tva.class.php +++ b/htdocs/compta/tva/class/tva.class.php @@ -1,7 +1,7 @@ * Copyright (C) 2004-2008 Laurent Destailleur - * Copyright (C) 2011-2014 Alexandre Spangaro + * Copyright (C) 2011-2015 Alexandre Spangaro * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -508,7 +508,7 @@ class Tva extends CommonObject $this->error=$langs->trans("ErrorFieldRequired",$langs->transnoentities("Label")); return -3; } - if ($this->amount < 0 || $this->amount == '') + if ($this->amount == '') { $this->error=$langs->trans("ErrorFieldRequired",$langs->transnoentities("Amount")); return -4; @@ -577,8 +577,12 @@ class Tva extends CommonObject $result=$acc->fetch($this->accountid); if ($result <= 0) dol_print_error($this->db); - $bank_line_id = $acc->addline($this->datep, $this->type_payment, $this->label, -abs($this->amount), '', '', $user); - + if ($this->amount > 0) { + $bank_line_id = $acc->addline($this->datep, $this->type_payment, $this->label, -abs($this->amount), '', '', $user); + } else { + $bank_line_id = $acc->addline($this->datep, $this->type_payment, $this->label, abs($this->amount), '', '', $user); + } + // Update fk_bank into llx_tva. So we know vat line used to generate bank transaction if ($bank_line_id > 0) { diff --git a/htdocs/contact/card.php b/htdocs/contact/card.php index a45437b3a39..9778d0c8a71 100644 --- a/htdocs/contact/card.php +++ b/htdocs/contact/card.php @@ -646,7 +646,7 @@ else print ''; + print ''; } else { diff --git a/htdocs/contact/class/contact.class.php b/htdocs/contact/class/contact.class.php index ade96390a76..dc3c7fc3640 100644 --- a/htdocs/contact/class/contact.class.php +++ b/htdocs/contact/class/contact.class.php @@ -516,9 +516,10 @@ class Contact extends CommonObject */ function fetch($id, $user=0, $ref_ext='') { - dol_syslog(get_class($this)."::fetch ".$this->error, LOG_ERR); global $langs; + dol_syslog(get_class($this)."::fetch id=".$id, LOG_DEBUG); + if (empty($id) && empty($ref_ext)) { $this->error='BadParameter'; @@ -547,7 +548,6 @@ class Contact extends CommonObject if ($id) $sql.= " WHERE c.rowid = ". $id; elseif ($ref_ext) $sql .= " WHERE c.ref_ext = '".$this->db->escape($ref_ext)."'"; - dol_syslog(get_class($this)."::fetch", LOG_DEBUG); $resql=$this->db->query($sql); if ($resql) { diff --git a/htdocs/contact/list.php b/htdocs/contact/list.php index 85fdbc2870f..cf65c1c5456 100644 --- a/htdocs/contact/list.php +++ b/htdocs/contact/list.php @@ -269,7 +269,7 @@ if ($result) print ''; print ''; - print ''; + print ''; print ''; print ''; diff --git a/htdocs/contrat/card.php b/htdocs/contrat/card.php index 1d2e3355b24..429547ed602 100644 --- a/htdocs/contrat/card.php +++ b/htdocs/contrat/card.php @@ -97,34 +97,19 @@ $permissiondellink=$user->rights->contrat->creer; // Used by the include of acti * Actions */ -include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not includ_once - -include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once - -if ($action == 'confirm_active' && $confirm == 'yes' && $user->rights->contrat->activer) +$parameters = array('socid' => $socid); +$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'); +if (empty($reshook)) { - $result = $object->active_line($user, GETPOST('ligne'), GETPOST('date'), GETPOST('dateend'), GETPOST('comment')); - - if ($result > 0) - { - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; - } - else { - setEventMessage($object->error,'errors'); - } -} - -else if ($action == 'confirm_closeline' && $confirm == 'yes' && $user->rights->contrat->activer) -{ - if (! GETPOST('dateend')) + include DOL_DOCUMENT_ROOT.'/core/actions_setnotes.inc.php'; // Must be include, not includ_once + + include DOL_DOCUMENT_ROOT.'/core/actions_dellink.inc.php'; // Must be include, not include_once + + if ($action == 'confirm_active' && $confirm == 'yes' && $user->rights->contrat->activer) { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("DateEnd")),'errors'); - } - if (! $error) - { - $result = $object->close_line($user, GETPOST('ligne'), GETPOST('dateend'), urldecode(GETPOST('comment'))); + $result = $object->active_line($user, GETPOST('ligne'), GETPOST('date'), GETPOST('dateend'), GETPOST('comment')); + if ($result > 0) { header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); @@ -134,602 +119,604 @@ else if ($action == 'confirm_closeline' && $confirm == 'yes' && $user->rights->c setEventMessage($object->error,'errors'); } } -} - -// Si ajout champ produit predefini -if (GETPOST('mode')=='predefined') -{ - $date_start=''; - $date_end=''; - if (GETPOST('date_startmonth') && GETPOST('date_startday') && GETPOST('date_startyear')) - { - $date_start=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), 0, GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); - } - if (GETPOST('date_endmonth') && GETPOST('date_endday') && GETPOST('date_endyear')) - { - $date_end=dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), 0, GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); - } -} - -// Si ajout champ produit libre -if (GETPOST('mode')=='libre') -{ - $date_start_sl=''; - $date_end_sl=''; - if (GETPOST('date_start_slmonth') && GETPOST('date_start_slday') && GETPOST('date_start_slyear')) - { - $date_start_sl=dol_mktime(GETPOST('date_start_slhour'), GETPOST('date_start_slmin'), 0, GETPOST('date_start_slmonth'), GETPOST('date_start_slday'), GETPOST('date_start_slyear')); - } - if (GETPOST('date_end_slmonth') && GETPOST('date_end_slday') && GETPOST('date_end_slyear')) - { - $date_end_sl=dol_mktime(GETPOST('date_end_slhour'), GETPOST('date_end_slmin'), 0, GETPOST('date_end_slmonth'), GETPOST('date_end_slday'), GETPOST('date_end_slyear')); - } -} - -// Param dates -$date_contrat=''; -$date_start_update=''; -$date_end_update=''; -$date_start_real_update=''; -$date_end_real_update=''; -if (GETPOST('date_start_updatemonth') && GETPOST('date_start_updateday') && GETPOST('date_start_updateyear')) -{ - $date_start_update=dol_mktime(GETPOST('date_start_updatehour'), GETPOST('date_start_updatemin'), 0, GETPOST('date_start_updatemonth'), GETPOST('date_start_updateday'), GETPOST('date_start_updateyear')); -} -if (GETPOST('date_end_updatemonth') && GETPOST('date_end_updateday') && GETPOST('date_end_updateyear')) -{ - $date_end_update=dol_mktime(GETPOST('date_end_updatehour'), GETPOST('date_end_updatemin'), 0, GETPOST('date_end_updatemonth'), GETPOST('date_end_updateday'), GETPOST('date_end_updateyear')); -} -if (GETPOST('date_start_real_updatemonth') && GETPOST('date_start_real_updateday') && GETPOST('date_start_real_updateyear')) -{ - $date_start_real_update=dol_mktime(GETPOST('date_start_real_updatehour'), GETPOST('date_start_real_updatemin'), 0, GETPOST('date_start_real_updatemonth'), GETPOST('date_start_real_updateday'), GETPOST('date_start_real_updateyear')); -} -if (GETPOST('date_end_real_updatemonth') && GETPOST('date_end_real_updateday') && GETPOST('date_end_real_updateyear')) -{ - $date_end_real_update=dol_mktime(GETPOST('date_end_real_updatehour'), GETPOST('date_end_real_updatemin'), 0, GETPOST('date_end_real_updatemonth'), GETPOST('date_end_real_updateday'), GETPOST('date_end_real_updateyear')); -} -if (GETPOST('remonth') && GETPOST('reday') && GETPOST('reyear')) -{ - $datecontrat = dol_mktime(GETPOST('rehour'), GETPOST('remin'), 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); -} - -// Add contract -if ($action == 'add' && $user->rights->contrat->creer) -{ - // Check - if (empty($datecontrat)) + + else if ($action == 'confirm_closeline' && $confirm == 'yes' && $user->rights->contrat->activer) { - $error++; - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); - $action='create'; + if (! GETPOST('dateend')) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("DateEnd")),'errors'); + } + if (! $error) + { + $result = $object->close_line($user, GETPOST('ligne'), GETPOST('dateend'), urldecode(GETPOST('comment'))); + if ($result > 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else + { + setEventMessage($object->error,'errors'); + } + } } - - if ($socid<1) + + // Si ajout champ produit predefini + if (GETPOST('mode')=='predefined') { - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Customer")),'errors'); - $action='create'; - $error++; - } - - // Fill array 'array_options' with data from add form - $ret = $extrafields->setOptionalsFromPost($extralabels, $object); - if ($ret < 0) { - $error ++; - $action = 'create'; - } - - if (! $error) - { - $object->socid = $socid; - $object->date_contrat = $datecontrat; - - $object->commercial_suivi_id = GETPOST('commercial_suivi_id','int'); - $object->commercial_signature_id = GETPOST('commercial_signature_id','int'); - - $object->note_private = GETPOST('note_private','alpha'); - $object->note_public = GETPOST('note_public','alpha'); - $object->fk_project = GETPOST('projectid','int'); - $object->remise_percent = GETPOST('remise_percent','alpha'); - $object->ref = GETPOST('ref','alpha'); - $object->ref_supplier = GETPOST('ref_supplier','alpha'); - - // If creation from another object of another module (Example: origin=propal, originid=1) - if ($_POST['origin'] && $_POST['originid']) + $date_start=''; + $date_end=''; + if (GETPOST('date_startmonth') && GETPOST('date_startday') && GETPOST('date_startyear')) { - // Parse element/subelement (ex: project_task) - $element = $subelement = $_POST['origin']; - if (preg_match('/^([^_]+)_([^_]+)/i',$_POST['origin'],$regs)) - { - $element = $regs[1]; - $subelement = $regs[2]; - } - - // For compatibility - if ($element == 'order') { $element = $subelement = 'commande'; } - if ($element == 'propal') { $element = 'comm/propal'; $subelement = 'propal'; } - - $object->origin = $_POST['origin']; - $object->origin_id = $_POST['originid']; - - // Possibility to add external linked objects with hooks - $object->linked_objects[$object->origin] = $object->origin_id; - if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects'])) - { - $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']); - } - - $id = $object->create($user); - if ($id < 0) { - setEventMessage($object->error,'errors'); - } - - if ($id > 0) - { - dol_include_once('/'.$element.'/class/'.$subelement.'.class.php'); - - $classname = ucfirst($subelement); - $srcobject = new $classname($db); - - dol_syslog("Try to find source object origin=".$object->origin." originid=".$object->origin_id." to add lines"); - $result=$srcobject->fetch($object->origin_id); - if ($result > 0) - { - $srcobject->fetch_thirdparty(); - $lines = $srcobject->lines; - if (empty($lines) && method_exists($srcobject,'fetch_lines')) - { - $srcobject->fetch_lines(); - $lines = $srcobject->lines; - } - - $fk_parent_line=0; - $num=count($lines); - - for ($i=0;$i<$num;$i++) - { - $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0); - - if ($product_type == 1 || (! empty($conf->global->CONTRACT_SUPPORT_PRODUCTS) && in_array($product_type, array(0,1)))) { // TODO Exclude also deee - // service prédéfini - if ($lines[$i]->fk_product > 0) - { - $product_static = new Product($db); - - // Define output language - if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) + $date_start=dol_mktime(GETPOST('date_starthour'), GETPOST('date_startmin'), 0, GETPOST('date_startmonth'), GETPOST('date_startday'), GETPOST('date_startyear')); + } + if (GETPOST('date_endmonth') && GETPOST('date_endday') && GETPOST('date_endyear')) + { + $date_end=dol_mktime(GETPOST('date_endhour'), GETPOST('date_endmin'), 0, GETPOST('date_endmonth'), GETPOST('date_endday'), GETPOST('date_endyear')); + } + } + + // Si ajout champ produit libre + if (GETPOST('mode')=='libre') + { + $date_start_sl=''; + $date_end_sl=''; + if (GETPOST('date_start_slmonth') && GETPOST('date_start_slday') && GETPOST('date_start_slyear')) + { + $date_start_sl=dol_mktime(GETPOST('date_start_slhour'), GETPOST('date_start_slmin'), 0, GETPOST('date_start_slmonth'), GETPOST('date_start_slday'), GETPOST('date_start_slyear')); + } + if (GETPOST('date_end_slmonth') && GETPOST('date_end_slday') && GETPOST('date_end_slyear')) + { + $date_end_sl=dol_mktime(GETPOST('date_end_slhour'), GETPOST('date_end_slmin'), 0, GETPOST('date_end_slmonth'), GETPOST('date_end_slday'), GETPOST('date_end_slyear')); + } + } + + // Param dates + $date_contrat=''; + $date_start_update=''; + $date_end_update=''; + $date_start_real_update=''; + $date_end_real_update=''; + if (GETPOST('date_start_updatemonth') && GETPOST('date_start_updateday') && GETPOST('date_start_updateyear')) + { + $date_start_update=dol_mktime(GETPOST('date_start_updatehour'), GETPOST('date_start_updatemin'), 0, GETPOST('date_start_updatemonth'), GETPOST('date_start_updateday'), GETPOST('date_start_updateyear')); + } + if (GETPOST('date_end_updatemonth') && GETPOST('date_end_updateday') && GETPOST('date_end_updateyear')) + { + $date_end_update=dol_mktime(GETPOST('date_end_updatehour'), GETPOST('date_end_updatemin'), 0, GETPOST('date_end_updatemonth'), GETPOST('date_end_updateday'), GETPOST('date_end_updateyear')); + } + if (GETPOST('date_start_real_updatemonth') && GETPOST('date_start_real_updateday') && GETPOST('date_start_real_updateyear')) + { + $date_start_real_update=dol_mktime(GETPOST('date_start_real_updatehour'), GETPOST('date_start_real_updatemin'), 0, GETPOST('date_start_real_updatemonth'), GETPOST('date_start_real_updateday'), GETPOST('date_start_real_updateyear')); + } + if (GETPOST('date_end_real_updatemonth') && GETPOST('date_end_real_updateday') && GETPOST('date_end_real_updateyear')) + { + $date_end_real_update=dol_mktime(GETPOST('date_end_real_updatehour'), GETPOST('date_end_real_updatemin'), 0, GETPOST('date_end_real_updatemonth'), GETPOST('date_end_real_updateday'), GETPOST('date_end_real_updateyear')); + } + if (GETPOST('remonth') && GETPOST('reday') && GETPOST('reyear')) + { + $datecontrat = dol_mktime(GETPOST('rehour'), GETPOST('remin'), 0, GETPOST('remonth'), GETPOST('reday'), GETPOST('reyear')); + } + + // Add contract + if ($action == 'add' && $user->rights->contrat->creer) + { + // Check + if (empty($datecontrat)) + { + $error++; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Date")),'errors'); + $action='create'; + } + + if ($socid<1) + { + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentitiesnoconv("Customer")),'errors'); + $action='create'; + $error++; + } + + // Fill array 'array_options' with data from add form + $ret = $extrafields->setOptionalsFromPost($extralabels, $object); + if ($ret < 0) { + $error ++; + $action = 'create'; + } + + if (! $error) + { + $object->socid = $socid; + $object->date_contrat = $datecontrat; + + $object->commercial_suivi_id = GETPOST('commercial_suivi_id','int'); + $object->commercial_signature_id = GETPOST('commercial_signature_id','int'); + + $object->note_private = GETPOST('note_private','alpha'); + $object->note_public = GETPOST('note_public','alpha'); + $object->fk_project = GETPOST('projectid','int'); + $object->remise_percent = GETPOST('remise_percent','alpha'); + $object->ref = GETPOST('ref','alpha'); + $object->ref_supplier = GETPOST('ref_supplier','alpha'); + + // If creation from another object of another module (Example: origin=propal, originid=1) + if ($_POST['origin'] && $_POST['originid']) + { + // Parse element/subelement (ex: project_task) + $element = $subelement = $_POST['origin']; + if (preg_match('/^([^_]+)_([^_]+)/i',$_POST['origin'],$regs)) + { + $element = $regs[1]; + $subelement = $regs[2]; + } + + // For compatibility + if ($element == 'order') { $element = $subelement = 'commande'; } + if ($element == 'propal') { $element = 'comm/propal'; $subelement = 'propal'; } + + $object->origin = $_POST['origin']; + $object->origin_id = $_POST['originid']; + + // Possibility to add external linked objects with hooks + $object->linked_objects[$object->origin] = $object->origin_id; + if (is_array($_POST['other_linked_objects']) && ! empty($_POST['other_linked_objects'])) + { + $object->linked_objects = array_merge($object->linked_objects, $_POST['other_linked_objects']); + } + + $id = $object->create($user); + if ($id < 0) { + setEventMessage($object->error,'errors'); + } + + if ($id > 0) + { + dol_include_once('/'.$element.'/class/'.$subelement.'.class.php'); + + $classname = ucfirst($subelement); + $srcobject = new $classname($db); + + dol_syslog("Try to find source object origin=".$object->origin." originid=".$object->origin_id." to add lines"); + $result=$srcobject->fetch($object->origin_id); + if ($result > 0) + { + $srcobject->fetch_thirdparty(); + $lines = $srcobject->lines; + if (empty($lines) && method_exists($srcobject,'fetch_lines')) + { + $srcobject->fetch_lines(); + $lines = $srcobject->lines; + } + + $fk_parent_line=0; + $num=count($lines); + + for ($i=0;$i<$num;$i++) + { + $product_type=($lines[$i]->product_type?$lines[$i]->product_type:0); + + if ($product_type == 1 || (! empty($conf->global->CONTRACT_SUPPORT_PRODUCTS) && in_array($product_type, array(0,1)))) { // TODO Exclude also deee + // service prédéfini + if ($lines[$i]->fk_product > 0) { - $prod = new Product($db); - $prod->id=$lines[$i]->fk_product; - $prod->getMultiLangs(); - - $outputlangs = $langs; - $newlang=''; - if (empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id'); - if (empty($newlang)) $newlang=$srcobject->thirdparty->default_lang; - if (! empty($newlang)) + $product_static = new Product($db); + + // Define output language + if (! empty($conf->global->MAIN_MULTILANGS) && ! empty($conf->global->PRODUIT_TEXTS_IN_THIRDPARTY_LANGUAGE)) { - $outputlangs = new Translate("",$conf); - $outputlangs->setDefaultLang($newlang); + $prod = new Product($db); + $prod->id=$lines[$i]->fk_product; + $prod->getMultiLangs(); + + $outputlangs = $langs; + $newlang=''; + if (empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id'); + if (empty($newlang)) $newlang=$srcobject->thirdparty->default_lang; + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + + $label = (! empty($prod->multilangs[$outputlangs->defaultlang]["libelle"])) ? $prod->multilangs[$outputlangs->defaultlang]["libelle"] : $lines[$i]->product_label; } - - $label = (! empty($prod->multilangs[$outputlangs->defaultlang]["libelle"])) ? $prod->multilangs[$outputlangs->defaultlang]["libelle"] : $lines[$i]->product_label; + else + { + $label = $lines[$i]->product_label; + } + + if ($conf->global->PRODUIT_DESC_IN_FORM) + $desc .= ($lines[$i]->desc && $lines[$i]->desc!=$lines[$i]->libelle)?dol_htmlentitiesbr($lines[$i]->desc):''; } - else - { - $label = $lines[$i]->product_label; - } - - if ($conf->global->PRODUIT_DESC_IN_FORM) - $desc .= ($lines[$i]->desc && $lines[$i]->desc!=$lines[$i]->libelle)?dol_htmlentitiesbr($lines[$i]->desc):''; + else { + $desc = dol_htmlentitiesbr($lines[$i]->desc); + } + + $result = $object->addline( + $desc, + $lines[$i]->subprice, + $lines[$i]->qty, + $lines[$i]->tva_tx, + $lines[$i]->localtax1_tx, + $lines[$i]->localtax2_tx, + $lines[$i]->fk_product, + $lines[$i]->remise_percent, + $lines[$i]->date_start, + $lines[$i]->date_end, + 'HT', + 0, + $lines[$i]->info_bits, + $lines[$i]->fk_fournprice, + $lines[$i]->pa_ht, + array(), + $lines[$i]->fk_unit + ); + + if ($result < 0) + { + $error++; + break; + } + } - else { - $desc = dol_htmlentitiesbr($lines[$i]->desc); - } - - $result = $object->addline( - $desc, - $lines[$i]->subprice, - $lines[$i]->qty, - $lines[$i]->tva_tx, - $lines[$i]->localtax1_tx, - $lines[$i]->localtax2_tx, - $lines[$i]->fk_product, - $lines[$i]->remise_percent, - $lines[$i]->date_start, - $lines[$i]->date_end, - 'HT', - 0, - $lines[$i]->info_bits, - $lines[$i]->fk_fournprice, - $lines[$i]->pa_ht, - array(), - $lines[$i]->fk_unit - ); - - if ($result < 0) - { - $error++; - break; - } - + } + } + else + { + setEventMessage($srcobject->error,'errors'); + $error++; + } + } + else + { + setEventMessage($object->error,'errors'); + $error++; + } + } + else + { + $result = $object->create($user); + if ($result > 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else { + setEventMessage($object->error,'errors'); + } + $action='create'; + } + } + } + + else if ($action == 'classin' && $user->rights->contrat->creer) + { + $object->setProject(GETPOST('projectid')); + } + + // Add a new line + else if ($action == 'addline' && $user->rights->contrat->creer) + { + // Set if we used free entry or predefined product + $predef=''; + $product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):''); + if (GETPOST('prod_entry_mode') == 'free') + { + $idprod=0; + $price_ht = GETPOST('price_ht'); + $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); + } + else + { + $idprod=GETPOST('idprod', 'int'); + $price_ht = ''; + $tva_tx = ''; + } + + $qty = GETPOST('qty'.$predef); + $remise_percent=GETPOST('remise_percent'.$predef); + + if ($qty == '') + { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")),'errors'); + $error++; + } + if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) + { + setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Description")),'errors'); + $error++; + } + + // Extrafields + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); + $array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef); + // Unset extrafield + if (is_array($extralabelsline)) { + // Get extra fields + foreach ($extralabelsline as $key => $value) { + unset($_POST["options_" . $key]); + } + } + + if (! $error) + { + // Clean parameters + $date_start=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), GETPOST('date_start'.$predef.'sec'), GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year')); + $date_end=dol_mktime(GETPOST('date_end'.$predef.'hour'), GETPOST('date_end'.$predef.'min'), GETPOST('date_end'.$predef.'sec'), GETPOST('date_end'.$predef.'month'), GETPOST('date_end'.$predef.'day'), GETPOST('date_end'.$predef.'year')); + $price_base_type = (GETPOST('price_base_type', 'alpha')?GETPOST('price_base_type', 'alpha'):'HT'); + + // Ecrase $pu par celui du produit + // Ecrase $desc par celui du produit + // Ecrase $txtva par celui du produit + // Ecrase $base_price_type par celui du produit + if ($idprod > 0) + { + $prod = new Product($db); + $prod->fetch($idprod); + + $tva_tx = get_default_tva($mysoc,$object->thirdparty,$prod->id); + $tva_npr = get_default_npr($mysoc,$object->thirdparty,$prod->id); + $pu_ht = $prod->price; + $pu_ttc = $prod->price_ttc; + $price_min = $prod->price_min; + $price_base_type = $prod->price_base_type; + + // On defini prix unitaire + if ($conf->global->PRODUIT_MULTIPRICES && $object->thirdparty->price_level) + { + $pu_ht = $prod->multiprices[$object->thirdparty->price_level]; + $pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level]; + $price_min = $prod->multiprices_min[$object->thirdparty->price_level]; + $price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level]; + } + elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) + { + require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php'; + + $prodcustprice = new Productcustomerprice($db); + + $filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id); + + $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); + if ($result) { + if (count($prodcustprice->lines) > 0) { + $pu_ht = price($prodcustprice->lines [0]->price); + $pu_ttc = price($prodcustprice->lines [0]->price_ttc); + $price_base_type = $prodcustprice->lines [0]->price_base_type; + $prod->tva_tx = $prodcustprice->lines [0]->tva_tx; } + } + } + + // On reevalue prix selon taux tva car taux tva transaction peut etre different + // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). + if ($tva_tx != $prod->tva_tx) + { + if ($price_base_type != 'HT') + { + $pu_ht = price2num($pu_ttc / (1 + ($tva_tx/100)), 'MU'); + } + else + { + $pu_ttc = price2num($pu_ht * (1 + ($tva_tx/100)), 'MU'); } } - else - { - setEventMessage($srcobject->error,'errors'); - $error++; - } + + $desc=$prod->description; + $desc=dol_concatdesc($desc,$product_desc); + $fk_unit = $prod->fk_unit; + } + else + { + $pu_ht=GETPOST('price_ht'); + $price_base_type = 'HT'; + $tva_tx=GETPOST('tva_tx')?str_replace('*','',GETPOST('tva_tx')):0; // tva_tx field may be disabled, so we use vat rate 0 + $tva_npr=preg_match('/\*/',GETPOST('tva_tx'))?1:0; + $desc=$product_desc; + $fk_unit= GETPOST('units', 'alpha'); + } + + $localtax1_tx=get_localtax($tva_tx,1,$object->thirdparty); + $localtax2_tx=get_localtax($tva_tx,2,$object->thirdparty); + + // ajout prix achat + $fk_fournprice = $_POST['fournprice']; + if ( ! empty($_POST['buying_price']) ) + $pa_ht = $_POST['buying_price']; + else + $pa_ht = null; + + $info_bits=0; + if ($tva_npr) $info_bits |= 0x01; + + if($price_min && (price2num($pu_ht)*(1-price2num($remise_percent)/100) < price2num($price_min))) + { + $object->error = $langs->trans("CantBeLessThanMinPrice",price(price2num($price_min,'MU'),0,$langs,0,0,-1,$conf->currency)); + $result = -1 ; + } + else + { + // Insert line + $result = $object->addline( + $desc, + $pu_ht, + $qty, + $tva_tx, + $localtax1_tx, + $localtax2_tx, + $idprod, + $remise_percent, + $date_start, + $date_end, + $price_base_type, + $pu_ttc, + $info_bits, + $fk_fournprice, + $pa_ht, + $array_options, + $fk_unit + ); + } + + if ($result > 0) + { + // Define output language + if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) + { + $outputlangs = $langs; + $newlang = ''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; + if (! empty($newlang)) { + $outputlangs = new Translate("", $conf); + $outputlangs->setDefaultLang($newlang); + } + + $ret = $object->fetch($id); // Reload to get new records + + $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + } + + unset($_POST ['prod_entry_mode']); + + unset($_POST['qty']); + unset($_POST['type']); + unset($_POST['remise_percent']); + unset($_POST['price_ht']); + unset($_POST['price_ttc']); + unset($_POST['tva_tx']); + unset($_POST['product_ref']); + unset($_POST['product_label']); + unset($_POST['product_desc']); + unset($_POST['fournprice']); + unset($_POST['buying_price']); + unset($_POST ['np_marginRate']); + unset($_POST ['np_markRate']); + unset($_POST['dp_desc']); + unset($_POST['idprod']); + + unset($_POST['date_starthour']); + unset($_POST['date_startmin']); + unset($_POST['date_startsec']); + unset($_POST['date_startday']); + unset($_POST['date_startmonth']); + unset($_POST['date_startyear']); + unset($_POST['date_endhour']); + unset($_POST['date_endmin']); + unset($_POST['date_endsec']); + unset($_POST['date_endday']); + unset($_POST['date_endmonth']); + unset($_POST['date_endyear']); } else { - setEventMessage($object->error,'errors'); - $error++; + setEventMessage($object->error,'errors'); + } + } + } + + else if ($action == 'updateligne' && $user->rights->contrat->creer && ! GETPOST('cancel')) + { + $objectline = new ContratLigne($db); + if ($objectline->fetch(GETPOST('elrowid'))) + { + $db->begin(); + + if ($date_start_real_update == '') $date_start_real_update=$objectline->date_ouverture; + if ($date_end_real_update == '') $date_end_real_update=$objectline->date_cloture; + + $localtax1_tx=get_localtax(GETPOST('eltva_tx'),1,$object->thirdparty); + $localtax2_tx=get_localtax(GETPOST('eltva_tx'),2,$object->thirdparty); + + // ajout prix d'achat + $fk_fournprice = $_POST['fournprice']; + if ( ! empty($_POST['buying_price']) ) + $pa_ht = $_POST['buying_price']; + else + $pa_ht = null; + + $fk_unit = GETPOST('unit', 'alpha'); + + $objectline->description=GETPOST('product_desc'); + $objectline->price_ht=GETPOST('elprice'); + $objectline->subprice=GETPOST('elprice'); + $objectline->qty=GETPOST('elqty'); + $objectline->remise_percent=GETPOST('elremise_percent'); + $objectline->tva_tx=GETPOST('eltva_tx')?GETPOST('eltva_tx'):0; // Field may be disabled, so we use vat rate 0 + $objectline->localtax1_tx=$localtax1_tx; + $objectline->localtax2_tx=$localtax2_tx; + $objectline->date_ouverture_prevue=$date_start_update; + $objectline->date_ouverture=$date_start_real_update; + $objectline->date_fin_validite=$date_end_update; + $objectline->date_cloture=$date_end_real_update; + $objectline->fk_user_cloture=$user->id; + $objectline->fk_fournprice=$fk_fournprice; + $objectline->pa_ht=$pa_ht; + + if ($fk_unit > 0) { + $objectline->fk_unit = GETPOST('unit'); + } else { + $objectline->fk_unit = null; + } + + // Extrafields + $extrafieldsline = new ExtraFields($db); + $extralabelsline = $extrafieldsline->fetch_name_optionals_label($objectline->table_element); + $array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef); + $objectline->array_options=$array_options; + + // TODO verifier price_min si fk_product et multiprix + + $result=$objectline->update($user); + if ($result > 0) + { + $db->commit(); + } + else + { + setEventMessage($objectline->error,'errors'); + $db->rollback(); } } else { - $result = $object->create($user); - if ($result > 0) - { - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; - } - else { - setEventMessage($object->error,'errors'); - } - $action='create'; - } - } -} - -else if ($action == 'classin' && $user->rights->contrat->creer) -{ - $object->setProject(GETPOST('projectid')); -} - -// Add a new line -else if ($action == 'addline' && $user->rights->contrat->creer) -{ - // Set if we used free entry or predefined product - $predef=''; - $product_desc=(GETPOST('dp_desc')?GETPOST('dp_desc'):''); - if (GETPOST('prod_entry_mode') == 'free') - { - $idprod=0; - $price_ht = GETPOST('price_ht'); - $tva_tx = (GETPOST('tva_tx') ? GETPOST('tva_tx') : 0); - } - else - { - $idprod=GETPOST('idprod', 'int'); - $price_ht = ''; - $tva_tx = ''; - } - - $qty = GETPOST('qty'.$predef); - $remise_percent=GETPOST('remise_percent'.$predef); - - if ($qty == '') - { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Qty")),'errors'); - $error++; - } - if (GETPOST('prod_entry_mode') == 'free' && empty($idprod) && empty($product_desc)) - { - setEventMessage($langs->trans("ErrorFieldRequired", $langs->transnoentitiesnoconv("Description")),'errors'); - $error++; - } - - // Extrafields - $extrafieldsline = new ExtraFields($db); - $extralabelsline = $extrafieldsline->fetch_name_optionals_label($object->table_element_line); - $array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef); - // Unset extrafield - if (is_array($extralabelsline)) { - // Get extra fields - foreach ($extralabelsline as $key => $value) { - unset($_POST["options_" . $key]); - } - } - - if (! $error) - { - // Clean parameters - $date_start=dol_mktime(GETPOST('date_start'.$predef.'hour'), GETPOST('date_start'.$predef.'min'), GETPOST('date_start'.$predef.'sec'), GETPOST('date_start'.$predef.'month'), GETPOST('date_start'.$predef.'day'), GETPOST('date_start'.$predef.'year')); - $date_end=dol_mktime(GETPOST('date_end'.$predef.'hour'), GETPOST('date_end'.$predef.'min'), GETPOST('date_end'.$predef.'sec'), GETPOST('date_end'.$predef.'month'), GETPOST('date_end'.$predef.'day'), GETPOST('date_end'.$predef.'year')); - $price_base_type = (GETPOST('price_base_type', 'alpha')?GETPOST('price_base_type', 'alpha'):'HT'); - - // Ecrase $pu par celui du produit - // Ecrase $desc par celui du produit - // Ecrase $txtva par celui du produit - // Ecrase $base_price_type par celui du produit - if ($idprod > 0) - { - $prod = new Product($db); - $prod->fetch($idprod); - - $tva_tx = get_default_tva($mysoc,$object->thirdparty,$prod->id); - $tva_npr = get_default_npr($mysoc,$object->thirdparty,$prod->id); - $pu_ht = $prod->price; - $pu_ttc = $prod->price_ttc; - $price_min = $prod->price_min; - $price_base_type = $prod->price_base_type; - - // On defini prix unitaire - if ($conf->global->PRODUIT_MULTIPRICES && $object->thirdparty->price_level) - { - $pu_ht = $prod->multiprices[$object->thirdparty->price_level]; - $pu_ttc = $prod->multiprices_ttc[$object->thirdparty->price_level]; - $price_min = $prod->multiprices_min[$object->thirdparty->price_level]; - $price_base_type = $prod->multiprices_base_type[$object->thirdparty->price_level]; - } - elseif (! empty($conf->global->PRODUIT_CUSTOMER_PRICES)) - { - require_once DOL_DOCUMENT_ROOT . '/product/class/productcustomerprice.class.php'; - - $prodcustprice = new Productcustomerprice($db); - - $filter = array('t.fk_product' => $prod->id,'t.fk_soc' => $object->thirdparty->id); - - $result = $prodcustprice->fetch_all('', '', 0, 0, $filter); - if ($result) { - if (count($prodcustprice->lines) > 0) { - $pu_ht = price($prodcustprice->lines [0]->price); - $pu_ttc = price($prodcustprice->lines [0]->price_ttc); - $price_base_type = $prodcustprice->lines [0]->price_base_type; - $prod->tva_tx = $prodcustprice->lines [0]->tva_tx; - } - } - } - - // On reevalue prix selon taux tva car taux tva transaction peut etre different - // de ceux du produit par defaut (par exemple si pays different entre vendeur et acheteur). - if ($tva_tx != $prod->tva_tx) - { - if ($price_base_type != 'HT') - { - $pu_ht = price2num($pu_ttc / (1 + ($tva_tx/100)), 'MU'); - } - else - { - $pu_ttc = price2num($pu_ht * (1 + ($tva_tx/100)), 'MU'); - } - } - - $desc=$prod->description; - $desc=dol_concatdesc($desc,$product_desc); - $fk_unit = $prod->fk_unit; - } - else - { - $pu_ht=GETPOST('price_ht'); - $price_base_type = 'HT'; - $tva_tx=GETPOST('tva_tx')?str_replace('*','',GETPOST('tva_tx')):0; // tva_tx field may be disabled, so we use vat rate 0 - $tva_npr=preg_match('/\*/',GETPOST('tva_tx'))?1:0; - $desc=$product_desc; - $fk_unit= GETPOST('units', 'alpha'); - } - - $localtax1_tx=get_localtax($tva_tx,1,$object->thirdparty); - $localtax2_tx=get_localtax($tva_tx,2,$object->thirdparty); - - // ajout prix achat - $fk_fournprice = $_POST['fournprice']; - if ( ! empty($_POST['buying_price']) ) - $pa_ht = $_POST['buying_price']; - else - $pa_ht = null; - - $info_bits=0; - if ($tva_npr) $info_bits |= 0x01; - - if($price_min && (price2num($pu_ht)*(1-price2num($remise_percent)/100) < price2num($price_min))) - { - $object->error = $langs->trans("CantBeLessThanMinPrice",price(price2num($price_min,'MU'),0,$langs,0,0,-1,$conf->currency)); - $result = -1 ; - } - else - { - // Insert line - $result = $object->addline( - $desc, - $pu_ht, - $qty, - $tva_tx, - $localtax1_tx, - $localtax2_tx, - $idprod, - $remise_percent, - $date_start, - $date_end, - $price_base_type, - $pu_ttc, - $info_bits, - $fk_fournprice, - $pa_ht, - $array_options, - $fk_unit - ); - } - - if ($result > 0) - { - // Define output language - if (empty($conf->global->MAIN_DISABLE_PDF_AUTOUPDATE)) - { - $outputlangs = $langs; - $newlang = ''; - if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang = GETPOST('lang_id','alpha'); - if ($conf->global->MAIN_MULTILANGS && empty($newlang)) $newlang = $object->thirdparty->default_lang; - if (! empty($newlang)) { - $outputlangs = new Translate("", $conf); - $outputlangs->setDefaultLang($newlang); - } - - $ret = $object->fetch($id); // Reload to get new records - - $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - } - - unset($_POST ['prod_entry_mode']); - - unset($_POST['qty']); - unset($_POST['type']); - unset($_POST['remise_percent']); - unset($_POST['price_ht']); - unset($_POST['price_ttc']); - unset($_POST['tva_tx']); - unset($_POST['product_ref']); - unset($_POST['product_label']); - unset($_POST['product_desc']); - unset($_POST['fournprice']); - unset($_POST['buying_price']); - unset($_POST ['np_marginRate']); - unset($_POST ['np_markRate']); - unset($_POST['dp_desc']); - unset($_POST['idprod']); - - unset($_POST['date_starthour']); - unset($_POST['date_startmin']); - unset($_POST['date_startsec']); - unset($_POST['date_startday']); - unset($_POST['date_startmonth']); - unset($_POST['date_startyear']); - unset($_POST['date_endhour']); - unset($_POST['date_endmin']); - unset($_POST['date_endsec']); - unset($_POST['date_endday']); - unset($_POST['date_endmonth']); - unset($_POST['date_endyear']); - } - else - { - setEventMessage($object->error,'errors'); - } - } -} - -else if ($action == 'updateligne' && $user->rights->contrat->creer && ! GETPOST('cancel')) -{ - $objectline = new ContratLigne($db); - if ($objectline->fetch(GETPOST('elrowid'))) - { - $db->begin(); - - if ($date_start_real_update == '') $date_start_real_update=$objectline->date_ouverture; - if ($date_end_real_update == '') $date_end_real_update=$objectline->date_cloture; - - $localtax1_tx=get_localtax(GETPOST('eltva_tx'),1,$object->thirdparty); - $localtax2_tx=get_localtax(GETPOST('eltva_tx'),2,$object->thirdparty); - - // ajout prix d'achat - $fk_fournprice = $_POST['fournprice']; - if ( ! empty($_POST['buying_price']) ) - $pa_ht = $_POST['buying_price']; - else - $pa_ht = null; - - $fk_unit = GETPOST('unit', 'alpha'); - - $objectline->description=GETPOST('product_desc'); - $objectline->price_ht=GETPOST('elprice'); - $objectline->subprice=GETPOST('elprice'); - $objectline->qty=GETPOST('elqty'); - $objectline->remise_percent=GETPOST('elremise_percent'); - $objectline->tva_tx=GETPOST('eltva_tx')?GETPOST('eltva_tx'):0; // Field may be disabled, so we use vat rate 0 - $objectline->localtax1_tx=$localtax1_tx; - $objectline->localtax2_tx=$localtax2_tx; - $objectline->date_ouverture_prevue=$date_start_update; - $objectline->date_ouverture=$date_start_real_update; - $objectline->date_fin_validite=$date_end_update; - $objectline->date_cloture=$date_end_real_update; - $objectline->fk_user_cloture=$user->id; - $objectline->fk_fournprice=$fk_fournprice; - $objectline->pa_ht=$pa_ht; - - if ($fk_unit > 0) { - $objectline->fk_unit = GETPOST('unit'); - } else { - $objectline->fk_unit = null; + setEventMessage($objectline->error,'errors'); } - - // Extrafields - $extrafieldsline = new ExtraFields($db); - $extralabelsline = $extrafieldsline->fetch_name_optionals_label($objectline->table_element); - $array_options = $extrafieldsline->getOptionalsFromPost($extralabelsline, $predef); - $objectline->array_options=$array_options; - - // TODO verifier price_min si fk_product et multiprix - - $result=$objectline->update($user); - if ($result > 0) - { - $db->commit(); - } - else - { - setEventMessage($objectline->error,'errors'); - $db->rollback(); - } - } - else - { - setEventMessage($objectline->error,'errors'); - } -} - -else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->contrat->creer) -{ - $result = $object->deleteline(GETPOST('lineid'),$user); - - if ($result >= 0) - { - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; - } - else - { - setEventMessage($object->error,'errors'); - } -} - -else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->contrat->creer) -{ - $result = $object->validate($user); -} - -// Close all lines -else if ($action == 'confirm_close' && $confirm == 'yes' && $user->rights->contrat->creer) -{ - $object->cloture($user); -} - -else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->contrat->supprimer) -{ - $result=$object->delete($user); - if ($result >= 0) - { - header("Location: index.php"); - return; } - else + + else if ($action == 'confirm_deleteline' && $confirm == 'yes' && $user->rights->contrat->creer) { - setEventMessage($object->error,'errors'); + $result = $object->deleteline(GETPOST('lineid'),$user); + + if ($result >= 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else + { + setEventMessage($object->error,'errors'); + } } -} - -else if ($action == 'confirm_move' && $confirm == 'yes' && $user->rights->contrat->creer) -{ - if (GETPOST('newcid') > 0) + + else if ($action == 'confirm_valid' && $confirm == 'yes' && $user->rights->contrat->creer) { - $contractline = new ContratLigne($db); - $result=$contractline->fetch(GETPOST('lineid')); - $contractline->fk_contrat = GETPOST('newcid'); - $result=$contractline->update($user,1); + $result = $object->validate($user); + } + + // Close all lines + else if ($action == 'confirm_close' && $confirm == 'yes' && $user->rights->contrat->creer) + { + $object->cloture($user); + } + + else if ($action == 'confirm_delete' && $confirm == 'yes' && $user->rights->contrat->supprimer) + { + $result=$object->delete($user); if ($result >= 0) { - header("Location: ".$_SERVER['PHP_SELF']."?id=".$id); + header("Location: index.php"); return; } else @@ -737,162 +724,181 @@ else if ($action == 'confirm_move' && $confirm == 'yes' && $user->rights->contra setEventMessage($object->error,'errors'); } } - else + + else if ($action == 'confirm_move' && $confirm == 'yes' && $user->rights->contrat->creer) { - setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("RefNewContract")),'errors'); - } -} else if ($action == 'update_extras') { - // Fill array 'array_options' with data from update form - $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); - $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute')); - if ($ret < 0) - $error ++; - - if (! $error) { - - $result = $object->insertExtraFields(); - if ($result < 0) { - $error ++; - } - } else if ($reshook < 0) - $error ++; - - if ($error) { - $action = 'edit_extras'; - setEventMessage($object->error,'errors'); - } -} elseif ($action=='setref_supplier') { - $cancelbutton = GETPOST('cancel'); - - if (!$cancelbutton) { - - $result = $object->fetch($id); - if ($result < 0) { - setEventMessage($object->errors, 'errors'); - } - - $result = $object->setValueFrom('ref_supplier',GETPOST('ref_supplier','alpha')); - if ($result < 0) { - setEventMessage($object->errors, 'errors'); - $action = 'editref_supplier'; - } else { - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; - } - } - else { - header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $id); - exit; - } -} elseif ($action=='setref') { - $cancelbutton = GETPOST('cancel'); - - if (!$cancelbutton) { - $result = $object->fetch($id); - if ($result < 0) { - setEventMessage($object->errors, 'errors'); - } - - $result = $object->setValueFrom('ref',GETPOST('ref','alpha'));; - if ($result < 0) { - setEventMessage($object->errors, 'errors'); - $action = 'editref'; - } else { - header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); - exit; - } - } - else { - header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $id); - exit; - } -} - -// Generation doc (depuis lien ou depuis cartouche doc) -else if ($action == 'builddoc' && $user->rights->contrat->creer) { - if (GETPOST('model')) { - $object->setDocModel($user, GETPOST('model')); - } - - // Define output language - $outputlangs = $langs; - if (! empty($conf->global->MAIN_MULTILANGS)) { - $outputlangs = new Translate("", $conf); - $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->thirdparty->default_lang); - $outputlangs->setDefaultLang($newlang); - } - $ret = $object->fetch($id); // Reload to get new records - $result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); - if ($result <= 0) - { - setEventMessages($object->error, $object->errors, 'errors'); - $action=''; - } -} - -// Remove file in doc form -else if ($action == 'remove_file' && $user->rights->contrat->creer) { - if ($object->id > 0) { - require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; - - $langs->load("other"); - $upload_dir = $conf->contrat->dir_output; - $file = $upload_dir . '/' . GETPOST('file'); - $ret = dol_delete_file($file, 0, 0, 0, $object); - if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('file'))); - else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), 'errors'); - } -} - -if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->contrat->creer) -{ - if ($action == 'addcontact') - { - $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); - $result = $object->add_contact($contactid, GETPOST('type'), GETPOST('source')); - - if ($result >= 0) + if (GETPOST('newcid') > 0) { - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; - } - else - { - if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') + $contractline = new ContratLigne($db); + $result=$contractline->fetch(GETPOST('lineid')); + $contractline->fk_contrat = GETPOST('newcid'); + $result=$contractline->update($user,1); + if ($result >= 0) { - $langs->load("errors"); - setEventMessage($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"),'errors'); + header("Location: ".$_SERVER['PHP_SELF']."?id=".$id); + return; } else { setEventMessage($object->error,'errors'); } } - } - - // bascule du statut d'un contact - else if ($action == 'swapstatut') - { - $result=$object->swapContactStatus(GETPOST('ligne')); - } - - // Efface un contact - else if ($action == 'deletecontact') - { - $result = $object->delete_contact(GETPOST('lineid')); - - if ($result >= 0) + else { - header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); - exit; + setEventMessage($langs->trans("ErrorFieldRequired",$langs->transnoentities("RefNewContract")),'errors'); } - else { + } else if ($action == 'update_extras') { + // Fill array 'array_options' with data from update form + $extralabels = $extrafields->fetch_name_optionals_label($object->table_element); + $ret = $extrafields->setOptionalsFromPost($extralabels, $object, GETPOST('attribute')); + if ($ret < 0) + $error ++; + + if (! $error) { + + $result = $object->insertExtraFields(); + if ($result < 0) { + $error ++; + } + } else if ($reshook < 0) + $error ++; + + if ($error) { + $action = 'edit_extras'; setEventMessage($object->error,'errors'); } + } elseif ($action=='setref_supplier') { + $cancelbutton = GETPOST('cancel'); + + if (!$cancelbutton) { + + $result = $object->fetch($id); + if ($result < 0) { + setEventMessage($object->errors, 'errors'); + } + + $result = $object->setValueFrom('ref_supplier',GETPOST('ref_supplier','alpha')); + if ($result < 0) { + setEventMessage($object->errors, 'errors'); + $action = 'editref_supplier'; + } else { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + } + else { + header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $id); + exit; + } + } elseif ($action=='setref') { + $cancelbutton = GETPOST('cancel'); + + if (!$cancelbutton) { + $result = $object->fetch($id); + if ($result < 0) { + setEventMessage($object->errors, 'errors'); + } + + $result = $object->setValueFrom('ref',GETPOST('ref','alpha'));; + if ($result < 0) { + setEventMessage($object->errors, 'errors'); + $action = 'editref'; + } else { + header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $object->id); + exit; + } + } + else { + header("Location: " . $_SERVER['PHP_SELF'] . "?id=" . $id); + exit; + } + } + + // Generation doc (depuis lien ou depuis cartouche doc) + else if ($action == 'builddoc' && $user->rights->contrat->creer) { + if (GETPOST('model')) { + $object->setDocModel($user, GETPOST('model')); + } + + // Define output language + $outputlangs = $langs; + if (! empty($conf->global->MAIN_MULTILANGS)) { + $outputlangs = new Translate("", $conf); + $newlang = (GETPOST('lang_id') ? GETPOST('lang_id') : $object->thirdparty->default_lang); + $outputlangs->setDefaultLang($newlang); + } + $ret = $object->fetch($id); // Reload to get new records + $result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result <= 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + $action=''; + } + } + + // Remove file in doc form + else if ($action == 'remove_file' && $user->rights->contrat->creer) { + if ($object->id > 0) { + require_once DOL_DOCUMENT_ROOT . '/core/lib/files.lib.php'; + + $langs->load("other"); + $upload_dir = $conf->contrat->dir_output; + $file = $upload_dir . '/' . GETPOST('file'); + $ret = dol_delete_file($file, 0, 0, 0, $object); + if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('file'))); + else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('file')), 'errors'); + } + } + + if (! empty($conf->global->MAIN_DISABLE_CONTACTS_TAB) && $user->rights->contrat->creer) + { + if ($action == 'addcontact') + { + $contactid = (GETPOST('userid') ? GETPOST('userid') : GETPOST('contactid')); + $result = $object->add_contact($contactid, GETPOST('type'), GETPOST('source')); + + if ($result >= 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else + { + if ($object->error == 'DB_ERROR_RECORD_ALREADY_EXISTS') + { + $langs->load("errors"); + setEventMessage($langs->trans("ErrorThisContactIsAlreadyDefinedAsThisType"),'errors'); + } + else + { + setEventMessage($object->error,'errors'); + } + } + } + + // bascule du statut d'un contact + else if ($action == 'swapstatut') + { + $result=$object->swapContactStatus(GETPOST('ligne')); + } + + // Efface un contact + else if ($action == 'deletecontact') + { + $result = $object->delete_contact(GETPOST('lineid')); + + if ($result >= 0) + { + header("Location: ".$_SERVER['PHP_SELF']."?id=".$object->id); + exit; + } + else { + setEventMessage($object->error,'errors'); + } + } } } - /* * View */ diff --git a/htdocs/core/actions_builddoc.inc.php b/htdocs/core/actions_builddoc.inc.php new file mode 100644 index 00000000000..27e5d8f602b --- /dev/null +++ b/htdocs/core/actions_builddoc.inc.php @@ -0,0 +1,108 @@ + + * + * 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/actions_builddoc.inc.php + * \brief Code for actions on building or deleting documents + */ + + +// $action must be defined +// $id must be defined +// $object must be defined and must have a method generateDocument. +// $permissioncreate must be defined +// $upload_dir must be defined (example $conf->projet->dir_output . "/";) +// $hidedetails, $hidedesc and $hideref may have been set or not. + + +// Build doc +if ($action == 'builddoc' && $permissioncreate) +{ + if (is_numeric(GETPOST('model'))) + { + $error=$langs->trans("ErrorFieldRequired",$langs->transnoentities("Model")); + } + else + { + // Reload to get all modified line records and be ready for hooks + $ret = $object->fetch($id); + $ret = $object->fetch_thirdparty(); + /*if (empty($object->id) || ! $object->id > 0) + { + dol_print_error('Object must have been loaded by a fetch'); + exit; + }*/ + + // Save last template used to generate document + if (GETPOST('model')) $object->setDocModel($user, GETPOST('model','alpha')); + + // Special case for invoices + if (property_exists($object, 'fk_bank')) + { + if (GETPOST('fk_bank')) { // this field may come from an external module + $object->fk_bank = GETPOST('fk_bank'); + } else { + $object->fk_bank = $object->fk_account; + } + } + + $outputlangs = $langs; + $newlang=''; + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && GETPOST('lang_id')) $newlang=GETPOST('lang_id'); + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && isset($object->client->default_lang)) $newlang=$object->client->default_lang; // for proposal, order, invoice, ... + if ($conf->global->MAIN_MULTILANGS && empty($newlang) && isset($object->default_lang)) $newlang=$object->default_lang; // for thirdparty + if (! empty($newlang)) + { + $outputlangs = new Translate("",$conf); + $outputlangs->setDefaultLang($newlang); + } + + // To be sure vars is defined + if (empty($hidedetails)) $hidedetails=0; + if (empty($hidedesc)) $hidedesc=0; + if (empty($hideref)) $hideref=0; + + $result= $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); + if ($result <= 0) + { + setEventMessages($object->error, $object->errors, 'errors'); + $action=''; + } + } +} + +// Delete file in doc form +if ($action == 'remove_file' && $permissioncreate) +{ + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + if (empty($object->id) || ! $object->id > 0) + { + // Reload to get all modified line records and be ready for hooks + $ret = $object->fetch($id); + $ret = $object->fetch_thirdparty(); + } + + $langs->load("other"); + $filetodelete=GETPOST('file','alpha'); + $file = $upload_dir . '/' . $filetodelete; + $ret=dol_delete_file($file,0,0,0,$object); + if ($ret) setEventMessage($langs->trans("FileWasRemoved", $filetodelete)); + else setEventMessage($langs->trans("ErrorFailToDeleteFile", $filetodelete), 'errors'); +} + diff --git a/htdocs/core/actions_dellink.inc.php b/htdocs/core/actions_dellink.inc.php index 1ba98a8435a..45fb8c5f9ec 100644 --- a/htdocs/core/actions_dellink.inc.php +++ b/htdocs/core/actions_dellink.inc.php @@ -25,6 +25,7 @@ // $action must be defined // $object must be defined // $permissiondellink must be defined +// $uploaddir (example $conf->projet->dir_output . "/";) $dellinkid = GETPOST('dellinkid','int'); @@ -34,3 +35,5 @@ if ($action == 'dellink' && ! empty($permissiondellink) && ! GETPOST('cancel') & $result=$object->deleteObjectLinked(0, '', 0, '', $dellinkid); if ($result < 0) setEventMessages($object->error,$object->errors,'errors'); } + + diff --git a/htdocs/core/actions_sendmails.inc.php b/htdocs/core/actions_sendmails.inc.php index d27e6e59fb4..67458fd401d 100644 --- a/htdocs/core/actions_sendmails.inc.php +++ b/htdocs/core/actions_sendmails.inc.php @@ -47,7 +47,7 @@ if (GETPOST('addfile')) /* * Remove file in email form */ -if (! empty($_POST['removedfile'])) +if (! empty($_POST['removedfile']) && empty($_POST['removAll'])) { require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; @@ -60,11 +60,41 @@ if (! empty($_POST['removedfile'])) $action='presend'; } +/* + * Remove all files in email form + */ + +if(! empty($_POST['removAll'])) +{ + $listofpaths=array(); + $listofnames=array(); + $listofmimes=array(); + if (! empty($_SESSION["listofpaths"])) $listofpaths=explode(';',$_SESSION["listofpaths"]); + if (! empty($_SESSION["listofnames"])) $listofnames=explode(';',$_SESSION["listofnames"]); + if (! empty($_SESSION["listofmimes"])) $listofmimes=explode(';',$_SESSION["listofmimes"]); + + include_once DOL_DOCUMENT_ROOT.'/core/class/html.formmail.class.php'; + $formmail = new FormMail($db); + + foreach($listofpaths as $key => $value) + { + $pathtodelete = $value; + $filetodelete = $listofnames[$key]; + $result = dol_delete_file($pathtodelete,1); // Delete uploded Files + + $langs->load("other"); + setEventMessage($langs->trans("FileWasRemoved",$filetodelete)); + + $formmail->remove_attached_files($key); // Update Session + } +} + /* * Send mail */ -if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_POST['removedfile'] && ! $_POST['cancel'] && !$_POST['modelselected']) +if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_POST['removAll'] && ! $_POST['removedfile'] && ! $_POST['cancel'] && !$_POST['modelselected']) { + if($conf->dolimail->enabled) $langs->load("dolimail@dolimail"); $langs->load('mails'); $subject='';$actionmsg='';$actionmsg2=''; @@ -81,7 +111,37 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO else if ($object->element == 'societe') { $thirdparty=$object; - $sendtosocid=$thirdparty->id; + if ($thirdparty->id > 0) $sendtosocid=$thirdparty->id; + elseif($conf->dolimail->enabled) + { + $dolimail = new Dolimail($db); + $possibleaccounts=$dolimail->get_societe_by_email($_POST['sendto'],"1"); + $possibleuser=$dolimail->get_from_user_by_mail($_POST['sendto'],"1"); // suche in llx_societe and socpeople + if (!$possibleaccounts && !$possibleuser) + { + setEventMessage($langs->trans('ErrorFailedToFindSocieteRecord',$_POST['sendto']),'errors'); + } + elseif (count($possibleaccounts)>1) + { + $sendtosocid=$possibleaccounts[1]['id']; + $result=$object->fetch($sendtosocid); + + setEventMessage($langs->trans('ErrorFoundMoreThanOneRecordWithEmail',$_POST['sendto'],$object->name)); + } + else + { + if($possibleaccounts){ + $sendtosocid=$possibleaccounts[1]['id']; + $result=$object->fetch($sendtosocid); + }elseif($possibleuser){ + $sendtosocid=$possibleuser[0]['id']; + + $result=$uobject->fetch($sendtosocid); + $object=$uobject; + } + + } + } } else dol_print_error('','Use actions_sendmails.in.php for a type that is not supported'); @@ -163,6 +223,46 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO $trackid = GETPOST('trackid','aZ'); + if($conf->dolimail->enabled) + { + $mailfromid = explode ("#", $_POST['frommail'],3); + if (count($mailfromid)==0) $from = $_POST['fromname'] . ' <' . $_POST['frommail'] .'>'; + else + { + $mbid = $mailfromid[1]; + + /*IMAP Postbox*/ + $mailboxconfig = new IMAP($db); + $mailboxconfig->fetch($mbid); + if ($mailboxconfig->mailbox_imap_host) $ref=$mailboxconfig->get_ref(); + + $mailboxconfig->folder_id=$mailboxconfig->mailbox_imap_outbox; + $mailboxconfig->userfolder_fetch(); + + if ($mailboxconfig->mailbox_save_sent_mails == 1) + { + + $folder=str_replace($ref, '', $mailboxconfig->folder_cache_key); + if (!$folder) $folder = "Sent"; + + $mailboxconfig->mbox = imap_open($mailboxconfig->get_connector_url().$folder, $mailboxconfig->mailbox_imap_login, $mailboxconfig->mailbox_imap_password); + if (FALSE === $mailboxconfig->mbox) + { + $info = FALSE; + $err = $langs->trans('Error3_Imap_Connection_Error'); + setEventMessage($err,$mailboxconfig->element,'errors'); + } + else + { + $mailboxconfig->mailboxid=$_POST['frommail']; + $mailboxconfig->foldername=$folder; + $from = $mailfromid[0] . $mailfromid[2]; + $imap=1; + } + + } + } + } // Send mail require_once DOL_DOCUMENT_ROOT.'/core/class/CMailFile.class.php'; $mailfile = new CMailFile($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,$sendtobcc,$deliveryreceipt,-1,'','',$trackid); @@ -176,7 +276,26 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO if ($result) { $error=0; - + if($conf->dolimail->enabled) + { + $mid = (GETPOST('mid','int') ? GETPOST('mid','int') : 0); + if ($mid) + { + // set imap flag answered if it is a answered mail + + $dolimail=new DoliMail($db); + $dolimail->id = $mid; + $res=$dolimail->set_prop($user, 'answered',1); + } + if ($imap==1) + { + // write mail to IMAP Server + $movemail = $mailboxconfig->putMail($subject,$sendto,$from,$message,$filepath,$mimetype,$filename,$sendtocc,$folder,$deliveryreceipt,$mailfile); + if ($movemail) setEventMessage($langs->trans("MailMovedToImapFolder",$folder),'mesgs'); + else setEventMessage($langs->trans("MailMovedToImapFolder_Warning",$folder),'warnings'); + } + } + // Initialisation donnees $object->socid = $sendtosocid; // To link to a company $object->sendtoid = $sendtoid; // To link to a contact/address @@ -205,24 +324,27 @@ if (($action == 'send' || $action == 'relance') && ! $_POST['addfile'] && ! $_PO // This avoid sending mail twice if going out and then back to page $mesg=$langs->trans('MailSuccessfulySent',$mailfile->getValidAddress($from,2),$mailfile->getValidAddress($sendto,2)); setEventMessage($mesg); - header('Location: '.$_SERVER["PHP_SELF"].'?'.($paramname?$paramname:'id').'='.$object->id); + if($conf->dolimail->enabled) header('Location: '.$_SERVER["PHP_SELF"].'?'.($paramname?$paramname:'id').'='.$object->id.'&'.($paramname2?$paramname2:'mid').'='.$parm2val); + else header('Location: '.$_SERVER["PHP_SELF"].'?'.($paramname?$paramname:'id').'='.$object->id); exit; } } else { $langs->load("other"); + $mesg='
'; if ($mailfile->error) { - $mesg=''; $mesg.=$langs->trans('ErrorFailedToSendMail',$from,$sendto); $mesg.='
'.$mailfile->error; - setEventMessage($mesg,'errors'); } else { - setEventMessage('No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS', 'warnings'); + $mesg.='No mail sent. Feature is disabled by option MAIN_DISABLE_ALL_MAILS'; } + $mesg.='
'; + + setEventMessage($mesg,'warnings'); $action = 'presend'; } } diff --git a/htdocs/core/ajax/box.php b/htdocs/core/ajax/box.php index 2d14a319a80..63f96a0c513 100644 --- a/htdocs/core/ajax/box.php +++ b/htdocs/core/ajax/box.php @@ -27,6 +27,7 @@ if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); +if (! defined('NOREQUIREHOOK')) define('NOREQUIREHOOK','1'); require '../../main.inc.php'; require_once DOL_DOCUMENT_ROOT.'/core/class/infobox.class.php'; diff --git a/htdocs/core/ajax/security.php b/htdocs/core/ajax/security.php index 5bdd45c75d4..28a53a87679 100644 --- a/htdocs/core/ajax/security.php +++ b/htdocs/core/ajax/security.php @@ -1,5 +1,5 @@ +/* Copyright (C) 2011-2015 Regis Houssin * * 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,7 +17,8 @@ /** * \file htdocs/core/ajax/security.php - * \brief File for return security data + * \brief This ajax component is used to generated has keys for security purposes + * like key to use into URL to protect them. */ if (! defined('NOTOKENRENEWAL')) define('NOTOKENRENEWAL','1'); // Disables token renewal @@ -26,6 +27,7 @@ if (! defined('NOREQUIREHTML')) define('NOREQUIREHTML','1'); if (! defined('NOREQUIREAJAX')) define('NOREQUIREAJAX','1'); if (! defined('NOREQUIRESOC')) define('NOREQUIRESOC','1'); if (! defined('NOREQUIRETRAN')) define('NOREQUIRETRAN','1'); +if (! defined('NOREQUIREHOOK')) define('NOREQUIREHOOK','1'); require '../../main.inc.php'; @@ -33,10 +35,6 @@ require '../../main.inc.php'; * View */ -// Ajout directives pour resoudre bug IE -//header('Cache-Control: Public, must-revalidate'); -//header('Pragma: public'); - //top_htmlhead("", "", 1); // Replaced with top_httphead. An ajax page does not need html header. top_httphead(); @@ -48,7 +46,7 @@ if (isset($_GET['action']) && ! empty($_GET['action'])) if ($_GET['action'] == 'getrandompassword' && $user->admin) { require_once DOL_DOCUMENT_ROOT.'/core/lib/security2.lib.php'; - $generic = $_GET['generic']; + $generic = $_GET['generic'] ? true : false; echo getRandomPassword($generic); } } diff --git a/htdocs/core/boxes/box_contacts.php b/htdocs/core/boxes/box_contacts.php index 4695be5eaa0..dde2a559cd3 100644 --- a/htdocs/core/boxes/box_contacts.php +++ b/htdocs/core/boxes/box_contacts.php @@ -105,7 +105,7 @@ class box_contacts extends ModeleBoxes $this->info_box_contents[$line][] = array( 'td' => 'align="left"', - 'text' => $societestatic->getNomUrl(1), + 'text' => ($objp->fk_soc > 0 ? $societestatic->getNomUrl(1) : ''), 'asis' => 1, ); diff --git a/htdocs/core/boxes/box_factures.php b/htdocs/core/boxes/box_factures.php index d04c3e48a3b..f50bff34a86 100644 --- a/htdocs/core/boxes/box_factures.php +++ b/htdocs/core/boxes/box_factures.php @@ -108,12 +108,18 @@ class box_factures extends ModeleBoxes $facturestatic->total_ht = $objp->total_ht; $facturestatic->total_tva = $objp->total_tva; $facturestatic->total_ttc = $objp->total_ttc; + $facturestatic->statut = $objp->fk_statut; + $facturestatic->date_lim_reglement = $db->jdate($objp->datelimite); + $societestatic->id = $objp->socid; $societestatic->name = $objp->name; $societestatic->code_client = $objp->code_client; + $late = ''; - if ($objp->paye == 0 && ($objp->fk_statut != 2 && $objp->fk_statut != 3) && $datelimite < ($now - $conf->facture->client->warning_delay)) { $late = img_warning(sprintf($l_due_date,dol_print_date($datelimite,'day')));} + if ($facturestatic->hasDelay()) { + $late = img_warning(sprintf($l_due_date,dol_print_date($datelimite,'day'))); + } $this->info_box_contents[$line][] = array( 'td' => 'align="left"', diff --git a/htdocs/core/boxes/box_factures_fourn.php b/htdocs/core/boxes/box_factures_fourn.php index 2f31fa61f78..7c90bb69683 100644 --- a/htdocs/core/boxes/box_factures_fourn.php +++ b/htdocs/core/boxes/box_factures_fourn.php @@ -93,7 +93,6 @@ class box_factures_fourn extends ModeleBoxes if ($result) { $num = $db->num_rows($result); - $now=dol_now(); $line = 0; $l_due_date = $langs->trans('Late').' ('.$langs->trans('DateEcheance').': %s)'; @@ -108,6 +107,8 @@ class box_factures_fourn extends ModeleBoxes $facturestatic->total_ht = $objp->total_ht; $facturestatic->total_tva = $objp->total_tva; $facturestatic->total_ttc = $objp->total_ttc; + $facturestatic->date_echeance = $datelimite; + $facturestatic->statut = $objp->fk_statut; $thirdpartytmp->id = $objp->socid; $thirdpartytmp->name = $objp->name; $thirdpartytmp->fournisseur = 1; @@ -115,7 +116,10 @@ class box_factures_fourn extends ModeleBoxes $thirdpartytmp->logo = $objp->logo; $late = ''; - if ($objp->paye == 0 && $datelimite && $datelimite < ($now - $conf->facture->fournisseur->warning_delay)) $late=img_warning(sprintf($l_due_date, dol_print_date($datelimite,'day'))); + + if ($facturestatic->hasDelay()) { + $late=img_warning(sprintf($l_due_date, dol_print_date($datelimite,'day'))); + } $this->info_box_contents[$line][] = array( 'td' => 'align="left"', diff --git a/htdocs/core/boxes/box_factures_fourn_imp.php b/htdocs/core/boxes/box_factures_fourn_imp.php index ecea4a27fd1..9bf302b2e18 100644 --- a/htdocs/core/boxes/box_factures_fourn_imp.php +++ b/htdocs/core/boxes/box_factures_fourn_imp.php @@ -86,11 +86,12 @@ class box_factures_fourn_imp extends ModeleBoxes if ($result) { $num = $db->num_rows($result); - $now=dol_now(); $line = 0; $l_due_date = $langs->trans('Late').' ('.$langs->trans('DateEcheance').': %s)'; + $facturestatic = new FactureFournisseur($db); + while ($line < $num) { $objp = $db->fetch_object($result); @@ -99,9 +100,13 @@ class box_factures_fourn_imp extends ModeleBoxes $thirdpartytmp->name = $objp->name; $thirdpartytmp->code_client = $objp->code_client; $thirdpartytmp->logo = $objp->logo; + $facturestatic->date_echeance = $datelimite; + $facturestatic->statut = $objp->fk_statut; $late=''; - if ($datelimite && $datelimite < ($now - $conf->facture->fournisseur->warning_delay)) $late=img_warning(sprintf($l_due_date,dol_print_date($datelimite,'day'))); + if ($facturestatic->hasDelay()) { + $late=img_warning(sprintf($l_due_date,dol_print_date($datelimite,'day'))); + } $tooltip = $langs->trans('SupplierInvoice') . ': ' . ($objp->ref?$objp->ref:$objp->facid) . '
' . $langs->trans('RefSupplier') . ': ' . $objp->ref_supplier; $this->info_box_contents[$line][] = array( diff --git a/htdocs/core/boxes/box_factures_imp.php b/htdocs/core/boxes/box_factures_imp.php index 42e889138cc..63ce986e181 100644 --- a/htdocs/core/boxes/box_factures_imp.php +++ b/htdocs/core/boxes/box_factures_imp.php @@ -108,6 +108,8 @@ class box_factures_imp extends ModeleBoxes $facturestatic->total_ht = $objp->total_ht; $facturestatic->total_tva = $objp->total_tva; $facturestatic->total_ttc = $objp->total_ttc; + $facturestatic->statut = $objp->fk_statut; + $facturestatic->date_lim_reglement = $db->jdate($objp->datelimite); $societestatic->id = $objp->socid; $societestatic->name = $objp->name; $societestatic->client = 1; @@ -115,7 +117,9 @@ class box_factures_imp extends ModeleBoxes $societestatic->logo = $objp->logo; $late=''; - if ($datelimite < ($now - $conf->facture->client->warning_delay)) $late = img_warning(sprintf($l_due_date,dol_print_date($datelimite,'day'))); + if ($facturestatic->hasDelay()) { + $late = img_warning(sprintf($l_due_date,dol_print_date($datelimite,'day'))); + } $this->info_box_contents[$line][] = array( 'td' => 'align="left"', diff --git a/htdocs/core/boxes/box_prospect.php b/htdocs/core/boxes/box_prospect.php index b3f2144b28b..3895a27a9f1 100644 --- a/htdocs/core/boxes/box_prospect.php +++ b/htdocs/core/boxes/box_prospect.php @@ -155,7 +155,6 @@ class box_prospect extends ModeleBoxes ); } } else { - dol_syslog("box_prospect::loadBox not allowed de read this box content",LOG_ERR); $this->info_box_contents[0][0] = array( 'td' => 'align="left"', 'text' => $langs->trans("ReadPermissionNotAllowed"), diff --git a/htdocs/core/boxes/box_task.php b/htdocs/core/boxes/box_task.php index 8ee42c44731..d6a65884ffb 100644 --- a/htdocs/core/boxes/box_task.php +++ b/htdocs/core/boxes/box_task.php @@ -82,7 +82,7 @@ class box_task extends ModeleBoxes $sql = "SELECT pt.fk_statut, count(pt.rowid) as nb, sum(ptt.task_duration) as durationtot, sum(pt.planned_workload) as plannedtot"; $sql.= " FROM ".MAIN_DB_PREFIX."projet_task as pt, ".MAIN_DB_PREFIX."projet_task_time as ptt"; - $sql.= " WHERE DATE_FORMAT(pt.datec,'%Y') = ".date("Y")." "; + $sql.= " WHERE DATE_FORMAT(pt.datec,'%Y') = '".date("Y")."' "; $sql.= " AND pt.rowid = ptt.fk_task"; $sql.= " GROUP BY pt.fk_statut "; $sql.= " ORDER BY pt.fk_statut DESC"; diff --git a/htdocs/core/class/CMailFile.class.php b/htdocs/core/class/CMailFile.class.php index 2c58848fe4f..b3da46ff366 100644 --- a/htdocs/core/class/CMailFile.class.php +++ b/htdocs/core/class/CMailFile.class.php @@ -375,19 +375,19 @@ class CMailFile if (empty($conf->global->MAIN_DISABLE_ALL_MAILS)) { - - dol_include_once('/core/class/hookmanager.class.php'); - $hookmanager=new HookManager($db); - $hookmanager->initHooks(array('maildao')); - $reshook=$hookmanager->executeHooks('doactions',$parameters,$this,$action); // Note that $action and $object may have been modified by some hooks - if (!empty($reshook)) - { + dol_include_once('/core/class/hookmanager.class.php'); + $hookmanager = new HookManager($db); + $hookmanager->initHooks(array( + 'maildao' + )); + $reshook = $hookmanager->executeHooks('doactions', $parameters, $this, $action); // Note that $action and $object may have been modified by some hooks + if (! empty($reshook)) + { + $this->error = "Error in hook maildao doactions " . $reshook; + dol_syslog("CMailFile::sendfile: mail end error=" . $this->error, LOG_ERR); - $this->error="Error in hook maildao doactions ".$reshook; - dol_syslog("CMailFile::sendfile: mail end error=".$this->error, LOG_ERR); - - return $reshook; - } + return $reshook; + } // Action according to choosed sending method if ($conf->global->MAIN_MAIL_SENDMODE == 'mail') diff --git a/htdocs/core/class/commonobject.class.php b/htdocs/core/class/commonobject.class.php index 58597862f8c..41a0b045a75 100644 --- a/htdocs/core/class/commonobject.class.php +++ b/htdocs/core/class/commonobject.class.php @@ -53,6 +53,11 @@ abstract class CommonObject */ public $error; + /** + * @var string[] Array of error strings + */ + public $errors=array(); + /** * @var string Key value used to track if data is coming from import wizard */ @@ -82,11 +87,6 @@ abstract class CommonObject // Following vars are used by some objects only. We keep this property here in CommonObject to be able to provide common method using them. - /** - * @var string[] Array of error strings - */ - public $errors=array(); - /** * @var string[] Can be used to pass information when only object is provided to method */ @@ -2159,11 +2159,11 @@ abstract class CommonObject $sourcetype = (! empty($sourcetype) ? $sourcetype : $this->element); $targettype = (! empty($targettype) ? $targettype : $this->element); - if (empty($sourceid) && empty($targetid)) + /*if (empty($sourceid) && empty($targetid)) { dol_syslog('Bad usage of function. No source nor target id defined (nor as parameter nor as object id)', LOG_ERR); return -1; - } + }*/ // Links between objects are stored in table element_element $sql = 'SELECT rowid, fk_source, sourcetype, fk_target, targettype'; @@ -3432,7 +3432,6 @@ abstract class CommonObject require_once $file; $obj = new $classname($this->db); - //$obj->message = $message; // If generator is ODT, we must have srctemplatepath defined, if not we set it. if ($obj->type == 'odt' && empty($srctemplatepath)) @@ -3470,11 +3469,20 @@ abstract class CommonObject if (empty($srctemplatepath)) { - $this->error='ErrorGenerationAskedForOdtTemplateWithNoSrcFileFound'; + $this->error='ErrorGenerationAskedForOdtTemplateWithSrcFileNotDefined'; return -1; } } + if ($obj->type == 'odt' && ! empty($srctemplatepath)) + { + if (! dol_is_file($srctemplatepath)) + { + $this->error='ErrorGenerationAskedForOdtTemplateWithSrcFileNotFound'; + return -1; + } + } + // We save charset_output to restore it because write_file can change it if needed for // output format that does not support UTF8. $sav_charset_output=$outputlangs->charset_output; @@ -3588,6 +3596,11 @@ abstract class CommonObject { if (empty($rowid)) $rowid=$this->id; + //To avoid SQL errors. Probably not the better solution though + if (!$this->table_element) { + return 0; + } + if (! is_array($optionsArray)) { // optionsArray not already loaded, so we load it @@ -3794,7 +3807,7 @@ abstract class CommonObject */ function showOptionals($extrafields, $mode='view', $params=null, $keyprefix='') { - global $_POST, $conf; + global $_POST, $conf, $langs; $out = ''; @@ -3852,7 +3865,7 @@ abstract class CommonObject if($extrafields->attribute_required[$key]) $label = ''.$label.''; - $out .= '
'; + $out .= ''; $out .=''; switch($mode) { diff --git a/htdocs/core/class/conf.class.php b/htdocs/core/class/conf.class.php index 13d2881563f..b3e5b843c28 100644 --- a/htdocs/core/class/conf.class.php +++ b/htdocs/core/class/conf.class.php @@ -110,6 +110,7 @@ class Conf $this->bank = new stdClass(); $this->notification = new stdClass(); $this->mailing = new stdClass(); + $this->expensereport = new stdClass(); } @@ -345,6 +346,9 @@ class Conf // Module contrat $this->contrat->dir_output=$rootfordata."/contracts"; $this->contrat->dir_temp =$rootfordata."/contracts/temp"; + // Module bank + $this->bank->dir_output=$rootfordata."/bank"; + $this->bank->dir_temp =$rootfordata."/bank/temp"; // Set some default values @@ -474,6 +478,7 @@ class Conf $this->adherent->cotisation = new stdClass(); $this->bank->rappro = new stdClass(); $this->bank->cheque = new stdClass(); + $this->expensereport->payment = new stdClass(); $this->actions->warning_delay=(isset($this->global->MAIN_DELAY_ACTIONS_TODO)?$this->global->MAIN_DELAY_ACTIONS_TODO:7)*24*60*60; $this->commande->client->warning_delay=(isset($this->global->MAIN_DELAY_ORDERS_TO_PROCESS)?$this->global->MAIN_DELAY_ORDERS_TO_PROCESS:2)*24*60*60; $this->commande->fournisseur->warning_delay=(isset($this->global->MAIN_DELAY_SUPPLIER_ORDERS_TO_PROCESS)?$this->global->MAIN_DELAY_SUPPLIER_ORDERS_TO_PROCESS:7)*24*60*60; @@ -486,6 +491,7 @@ class Conf $this->adherent->cotisation->warning_delay=(isset($this->global->MAIN_DELAY_MEMBERS)?$this->global->MAIN_DELAY_MEMBERS:0)*24*60*60; $this->bank->rappro->warning_delay=(isset($this->global->MAIN_DELAY_TRANSACTIONS_TO_CONCILIATE)?$this->global->MAIN_DELAY_TRANSACTIONS_TO_CONCILIATE:0)*24*60*60; $this->bank->cheque->warning_delay=(isset($this->global->MAIN_DELAY_CHEQUES_TO_DEPOSIT)?$this->global->MAIN_DELAY_CHEQUES_TO_DEPOSIT:0)*24*60*60; + $this->expensereport->payment->warning_delay=(isset($this->global->MAIN_DELAY_EXPENSEREPORTS_TO_PAY)?$this->global->MAIN_DELAY_EXPENSEREPORTS_TO_PAY:0)*24*60*60; // For modules that want to disable top or left menu if (! empty($this->global->MAIN_HIDE_TOP_MENU)) $this->dol_hide_topmenu=$this->global->MAIN_HIDE_TOP_MENU; diff --git a/htdocs/core/class/extrafields.class.php b/htdocs/core/class/extrafields.class.php index ebac8ccd797..0807bbcec75 100644 --- a/htdocs/core/class/extrafields.class.php +++ b/htdocs/core/class/extrafields.class.php @@ -567,7 +567,7 @@ class ExtraFields /** * Load array this->attribute_xxx like attribute_label, attribute_type, ... * - * @param string $elementtype Type of element ('adherent', 'commande', thirdparty', 'facture', 'propal', 'product', ...) + * @param string $elementtype Type of element ('adherent', 'commande', 'thirdparty', 'facture', 'propal', 'product', ...) * @param boolean $forceload Force load of extra fields whatever is option MAIN_EXTRAFIELDS_DISABLED * @return array Array of attributes for all extra fields */ @@ -631,13 +631,15 @@ class ExtraFields /** * Return HTML string to put an input field into a page * - * @param string $key Key of attribute - * @param string $value Value to show (for date type it must be in timestamp format) - * @param string $moreparam To add more parametes on html input tag - * @param string $keyprefix Prefix string to add into name and id of field (can be used to avoid duplicate names) - * @return string + * @param string $key Key of attribute + * @param string $value Value to show (for date type it must be in timestamp format) + * @param string $moreparam To add more parametes on html input tag + * @param string $keyprefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keysuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @param int $showsize Value for size attribute + * @return string */ - function showInputField($key,$value,$moreparam='',$keyprefix='') + function showInputField($key,$value,$moreparam='',$keyprefix='',$keysuffix='',$showsize=0) { global $conf,$langs; @@ -651,24 +653,27 @@ class ExtraFields $perms=$this->attribute_perms[$key]; $list=$this->attribute_list[$key]; - if ($type == 'date') + if (empty($showsize)) { - $showsize=10; + if ($type == 'date') + { + $showsize=10; + } + elseif ($type == 'datetime') + { + $showsize=19; + } + elseif (in_array($type,array('int','double'))) + { + $showsize=10; + } + else + { + $showsize=round($size); + if ($showsize > 48) $showsize=48; + } } - elseif ($type == 'datetime') - { - $showsize=19; - } - elseif (in_array($type,array('int','double'))) - { - $showsize=10; - } - else - { - $showsize=round($size); - if ($showsize > 48) $showsize=48; - } - + if (in_array($type,array('date','datetime'))) { $tmp=explode(',',$size); @@ -684,22 +689,22 @@ class ExtraFields if (! is_object($form)) $form=new Form($this->db); // TODO Must also support $moreparam - $out = $form->select_date($value, 'options_'.$key.$keyprefix, $showtime, $showtime, $required, '', 1, 1, 1, 0, 1); + $out = $form->select_date($value, $keysuffix.'options_'.$key.$keyprefix, $showtime, $showtime, $required, '', 1, 1, 1, 0, 1); } elseif (in_array($type,array('int'))) { $tmp=explode(',',$size); $newsize=$tmp[0]; - $out=''; + $out=''; } elseif ($type == 'varchar') { - $out=''; + $out=''; } elseif ($type == 'text') { require_once DOL_DOCUMENT_ROOT.'/core/class/doleditor.class.php'; - $doleditor=new DolEditor('options_'.$key.$keyprefix,$value,'',200,'dolibarr_notes','In',false,false,! empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE,5,100); + $doleditor=new DolEditor($keysuffix.'options_'.$key.$keyprefix,$value,'',200,'dolibarr_notes','In',false,false,! empty($conf->fckeditor->enabled) && $conf->global->FCKEDITOR_ENABLE_SOCIETE,5,100); $out=$doleditor->Create(1); } elseif ($type == 'boolean') @@ -710,26 +715,26 @@ class ExtraFields } else { $checked=' value="1" '; } - $out=''; + $out=''; } elseif ($type == 'mail') { - $out=''; + $out=''; } elseif ($type == 'phone') { - $out=''; + $out=''; } elseif ($type == 'price') { - $out=' '.$langs->getCurrencySymbol($conf->currency); + $out=' '.$langs->getCurrencySymbol($conf->currency); } elseif ($type == 'double') { if (!empty($value)) { $value=price($value); } - $out=' '; + $out=' '; } elseif ($type == 'select') { @@ -737,10 +742,10 @@ class ExtraFields if (! empty($conf->use_javascript_ajax) && ! empty($conf->global->COMPANY_USE_SEARCH_TO_SELECT) && ! $forcecombo) { include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; - $out.= ajax_combobox('options_'.$key.$keyprefix, array(), $conf->global->COMPANY_USE_SEARCH_TO_SELECT); + $out.= ajax_combobox($keysuffix.'options_'.$key.$keyprefix, array(), $conf->global->COMPANY_USE_SEARCH_TO_SELECT); } - $out.=''; $out.=''; foreach ($param['options'] as $key=>$val ) { @@ -758,10 +763,10 @@ class ExtraFields if ($conf->use_javascript_ajax && $conf->global->COMPANY_USE_SEARCH_TO_SELECT && ! $forcecombo) { include_once DOL_DOCUMENT_ROOT . '/core/lib/ajax.lib.php'; - $out.= ajax_combobox('options_'.$key.$keyprefix, array(), $conf->global->COMPANY_USE_SEARCH_TO_SELECT); + $out.= ajax_combobox($keysuffix.'options_'.$key.$keyprefix, array(), $conf->global->COMPANY_USE_SEARCH_TO_SELECT); } - $out.=''; if (is_array($param['options'])) { $param_list=array_keys($param['options']); @@ -907,7 +912,7 @@ class ExtraFields foreach ($param['options'] as $keyopt=>$val ) { - $out.='$val ) { - $out.=''; @@ -1018,7 +1023,7 @@ class ExtraFields $labeltoshow = dol_trunc($obj->$field_toshow, 18) . ' '; } } - $out .= 'rowid . '"'; $out .= 'checked'; @@ -1037,7 +1042,7 @@ class ExtraFields $labeltoshow = '(not defined)'; if (is_array($value_arr) && in_array($obj->rowid, $value_arr)) { - $out .= 'rowid . '"'; $out .= 'checked'; @@ -1050,7 +1055,7 @@ class ExtraFields $parent = $parentName . ':' . $obj->{$parentField}; } - $out .= 'rowid . '"'; $out .= ((is_array($value_arr) && in_array($obj->rowid, $value_arr)) ? ' checked ' : ''); @@ -1080,7 +1085,7 @@ class ExtraFields dol_include_once($InfoFieldList[1]); $object = new $InfoFieldList[0]($this->db); $object->fetch($value); - $out=''; + $out=''; } /* Add comments @@ -1417,14 +1422,16 @@ class ExtraFields return 0; } } + /** * return array_options array for object by extrafields value (using for data send by forms) * - * @param array $extralabels $array of extrafields - * @param string $keyprefix Prefix string to add into name and id of field (can be used to avoid duplicate names) - * @return int 1 if array_options set / 0 if no value + * @param array $extralabels $array of extrafields + * @param string $keyprefix Prefix string to add into name and id of field (can be used to avoid duplicate names) + * @param string $keysuffix Suffix string to add into name and id of field (can be used to avoid duplicate names) + * @return int 1 if array_options set / 0 if no value */ - function getOptionalsFromPost($extralabels,$keyprefix='') + function getOptionalsFromPost($extralabels,$keyprefix='',$keysuffix='') { global $_POST; @@ -1439,24 +1446,24 @@ class ExtraFields if (in_array($key_type,array('date','datetime'))) { // Clean parameters - $value_key=dol_mktime($_POST["options_".$key.$keyprefix."hour"], $_POST["options_".$key.$keyprefix."min"], 0, $_POST["options_".$key.$keyprefix."month"], $_POST["options_".$key.$keyprefix."day"], $_POST["options_".$key.$keyprefix."year"]); + $value_key=dol_mktime($_POST[$keysuffix."options_".$key.$keyprefix."hour"], $_POST[$keysuffix."options_".$key.$keyprefix."min"], 0, $_POST[$keysuffix."options_".$key.$keyprefix."month"], $_POST[$keysuffix."options_".$key.$keyprefix."day"], $_POST[$keysuffix."options_".$key.$keyprefix."year"]); } else if (in_array($key_type,array('checkbox'))) { - $value_arr=GETPOST("options_".$key.$keyprefix); + $value_arr=GETPOST($keysuffix."options_".$key.$keyprefix); $value_key=implode($value_arr,','); } else if (in_array($key_type,array('price','double'))) { - $value_arr=GETPOST("options_".$key.$keyprefix); + $value_arr=GETPOST($keysuffix."options_".$key.$keyprefix); $value_key=price2num($value_arr); } else { - $value_key=GETPOST("options_".$key.$keyprefix); + $value_key=GETPOST($keysuffix."options_".$key.$keyprefix); } - $array_options["options_".$key]=$value_key; // No keyprefix here. keyprefix is used only for read. + $array_options[$keysuffix."options_".$key]=$value_key; // No keyprefix here. keyprefix is used only for read. } return $array_options; diff --git a/htdocs/core/class/html.form.class.php b/htdocs/core/class/html.form.class.php index 7efae8effc3..fe4852d839b 100644 --- a/htdocs/core/class/html.form.class.php +++ b/htdocs/core/class/html.form.class.php @@ -364,7 +364,8 @@ class Form } /** - * Show a text and picto with tooltip on text or picto + * Show a text and picto with tooltip on text or picto. + * Can be called by an instancied $form->textwithtooltip or by a static call Form::textwithtooltip * * @param string $text Text to show * @param string $htmltext HTML content of tooltip. Must be HTML/UTF8 encoded. @@ -4406,7 +4407,7 @@ class Form * @param string $htmlname Name of html select area. Must start with "multi" if this is a multiselect * @param array $array Array with key+value * @param string|string[] $id Preselected key or preselected keys for multiselect - * @param int $show_empty 0 no empty value allowed, 1 to add an empty value into list (value is '' or ' '). + * @param int $show_empty 0 no empty value allowed, 1 to add an empty value into list (value is '' or ' '), <0 to add an empty value with key that is this value. * @param int $key_in_label 1 pour afficher la key dans la valeur "[key] value" * @param int $value_as_key 1 to use value as key * @param string $moreparam Add more parameters onto the select tag @@ -4455,7 +4456,7 @@ class Form { $textforempty=' '; if (! empty($conf->use_javascript_ajax)) $textforempty=' '; // If we use ajaxcombo, we need   here to avoid to have an empty element that is too small. - $out.=''."\n"; + $out.=''."\n"; // id is -2 because -1 is already "do not contact" } if (is_array($array)) diff --git a/htdocs/core/class/html.formother.class.php b/htdocs/core/class/html.formother.class.php index 8e9ca33b2a0..437637c3bdf 100644 --- a/htdocs/core/class/html.formother.class.php +++ b/htdocs/core/class/html.formother.class.php @@ -303,13 +303,14 @@ class FormOther * Return select list for categories (to use in form search selectors) * * @param int $type Type of categories (0=product, 1=suppliers, 2=customers, 3=members) - * @param integer $selected Preselected value - * @param string $htmlname Name of combo list + * @param integer $selected Preselected value + * @param string $htmlname Name of combo list * @param int $nocateg Show also an entry "Not categorized" + * @param int $showempty Add also an empty line * @return string Html combo list code * @see select_all_categories */ - function select_categories($type,$selected=0,$htmlname='search_categ',$nocateg=0) + function select_categories($type,$selected=0,$htmlname='search_categ',$nocateg=0,$showempty=1) { global $conf, $langs; require_once DOL_DOCUMENT_ROOT.'/categories/class/categorie.class.php'; @@ -331,7 +332,7 @@ class FormOther // Print a select with each of them $moreforfilter.=''; if ($showempty) $sellist.= ''; + if ($showallnone) $sellist.= ''; + if ($showallnone) $sellist.= ''; while ($i < $num) { $obj = $this->db->fetch_object($resql); diff --git a/htdocs/core/class/smtps.class.php b/htdocs/core/class/smtps.class.php index 5cc62c56bc6..51d9dd621dc 100644 --- a/htdocs/core/class/smtps.class.php +++ b/htdocs/core/class/smtps.class.php @@ -522,7 +522,7 @@ class SMTPs * @param mixed $_strConfigPath path to config file or VOID * @return void */ - function setConfig ( $_strConfigPath = null ) + function setConfig($_strConfigPath = null) { /** * Returns constructed SELECT Object string or boolean upon failure @@ -736,7 +736,7 @@ class SMTPs * @param string $_strTransEncode Content-Transfer-Encoding * @return void */ - function setTransEncode ( $_strTransEncode ) + function setTransEncode($_strTransEncode) { if (array_search($_strTransEncode, $this->_smtpsTransEncodeTypes)) $this->_smtpsTransEncode = $_strTransEncode; @@ -830,7 +830,7 @@ class SMTPs * @return void * */ - function _buildAddrList( $_type, $_addrList ) + function _buildAddrList($_type, $_addrList) { // Pull existing list $aryHost = $this->_msgRecipients; diff --git a/htdocs/core/class/stats.class.php b/htdocs/core/class/stats.class.php index f29d737eadf..1dc405ecbad 100644 --- a/htdocs/core/class/stats.class.php +++ b/htdocs/core/class/stats.class.php @@ -383,11 +383,11 @@ abstract class Stats $row = $this->db->fetch_object($resql); $result[$i]['year'] = $row->year; $result[$i]['nb'] = $row->nb; - if($i>0) $result[$i-1]['nb_diff'] = ($result[$i-1]['nb'] - $row->nb) / $row->nb * 100; + if($i>0 && $row->nb) $result[$i-1]['nb_diff'] = ($result[$i-1]['nb'] - $row->nb) / $row->nb * 100; $result[$i]['total'] = $row->total; - if($i>0) $result[$i-1]['total_diff'] = ($result[$i-1]['total'] - $row->total) / $row->total * 100; + if($i>0 && $row->total) $result[$i-1]['total_diff'] = ($result[$i-1]['total'] - $row->total) / $row->total * 100; $result[$i]['avg'] = $row->avg; - if($i>0) $result[$i-1]['avg_diff'] = ($result[$i-1]['avg'] - $row->avg) / $row->avg * 100; + if($i>0 && $row->avg) $result[$i-1]['avg_diff'] = ($result[$i-1]['avg'] - $row->avg) / $row->avg * 100; $i++; } $this->db->free($resql); diff --git a/htdocs/core/class/translate.class.php b/htdocs/core/class/translate.class.php index 37846bf2421..5d06586fb16 100644 --- a/htdocs/core/class/translate.class.php +++ b/htdocs/core/class/translate.class.php @@ -234,7 +234,8 @@ class Translate if ($usecachekey) { //dol_syslog('Translate::Load we will cache result into usecachekey '.$usecachekey); - + //global $aaa; $aaa+=1; + //print $aaa." ".$usecachekey."\n"; require_once DOL_DOCUMENT_ROOT .'/core/lib/memory.lib.php'; $tmparray=dol_getcache($usecachekey); if (is_array($tmparray) && count($tmparray)) @@ -421,7 +422,11 @@ class Translate } } - if (! preg_match('/^Format/',$key)) $str=sprintf($str,$param1,$param2,$param3,$param4); // Replace %s and %d except for FormatXXX strings. + if (! preg_match('/^Format/',$key)) + { + //print $str; + $str=sprintf($str,$param1,$param2,$param3,$param4); // Replace %s and %d except for FormatXXX strings. + } if ($maxsize) $str=dol_trunc($str,$maxsize); @@ -497,7 +502,11 @@ class Translate } } - if (! preg_match('/^Format/',$key)) $str=sprintf($str,$param1,$param2,$param3,$param4); // Replace %s and %d except for FormatXXX strings. + if (! preg_match('/^Format/',$key)) + { + //print $str; + $str=sprintf($str,$param1,$param2,$param3,$param4); // Replace %s and %d except for FormatXXX strings. + } return $str; } @@ -819,3 +828,8 @@ class Translate } } + +function warning_handler($errno, $errstr, $errfile, $errline, array $errcontext) { + global $str; + print 'str='.$str; +} diff --git a/htdocs/core/lib/accounting.lib.php b/htdocs/core/lib/accounting.lib.php index 196dcfe0997..6e6da6bd686 100644 --- a/htdocs/core/lib/accounting.lib.php +++ b/htdocs/core/lib/accounting.lib.php @@ -47,12 +47,12 @@ function admin_accounting_prepare_head(AccountingAccount $object=null) // $this->tabs = array('entity:-tabname); to remove a tab complete_head_from_modules($conf, $langs, $object, $head, $h, 'accounting_admin'); - $head[$h][0] = dol_buildpath('/accountancy/admin/journaux.php', 1); + $head[$h][0] = DOL_URL_ROOT.'/accountancy/admin/journal.php'; $head[$h][1] = $langs->trans("Journaux"); $head[$h][2] = 'journal'; $h ++; - $head[$h][0] = dol_buildpath('/accountancy/admin/export.php', 1); + $head[$h][0] = DOL_URL_ROOT.'/accountancy/admin/export.php'; $head[$h][1] = $langs->trans("Export"); $head[$h][2] = 'export'; $h ++; @@ -75,7 +75,7 @@ function accounting_prepare_head(AccountingAccount $object) $h = 0; $head = array (); - $head[$h][0] = dol_buildpath('/accountancy/admin/card.php', 1) . '?id=' . $object->id; + $head[$h][0] = DOL_URL_ROOT.'/accountancy/admin/card.php?id=' . $object->id; $head[$h][1] = $langs->trans("Card"); $head[$h][2] = 'card'; $h ++; diff --git a/htdocs/core/lib/admin.lib.php b/htdocs/core/lib/admin.lib.php index d59e3c9a864..9490f3a7b7d 100644 --- a/htdocs/core/lib/admin.lib.php +++ b/htdocs/core/lib/admin.lib.php @@ -1,7 +1,8 @@ - * Copyright (C) 2005-2012 Regis Houssin - * Copyright (C) 2012 J. Fernando Lagrange +/* Copyright (C) 2008-2011 Laurent Destailleur + * Copyright (C) 2005-2012 Regis Houssin + * Copyright (C) 2012 J. Fernando Lagrange + * Copyright (C) 2015 Raphaël Doursenaud * * 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 @@ -23,6 +24,7 @@ * \brief Library of admin functions */ +require_once DOL_DOCUMENT_ROOT . '/core/lib/functions2.lib.php'; /** * Renvoi une version en chaine depuis une version en tableau @@ -676,29 +678,7 @@ function activateModule($value,$withdeps=1) $ret=''; $modName = $value; $modFile = $modName . ".class.php"; - - // Loop on each directory to fill $modulesdir - $modulesdir = array(); - foreach ($conf->file->dol_document_root as $type => $dirroot) - { - $modulesdir[] = $dirroot."/core/modules/"; - - $handle=@opendir(dol_osencode($dirroot)); - if (is_resource($handle)) - { - while (($file = readdir($handle))!==false) - { - if (is_dir($dirroot.'/'.$file) && substr($file, 0, 1) <> '.' && substr($file, 0, 3) <> 'CVS' && $file != 'includes') - { - if (is_dir($dirroot . '/' . $file . '/core/modules/')) - { - $modulesdir[] = $dirroot . '/' . $file . '/core/modules/'; - } - } - } - closedir($handle); - } - } + $modulesdir = dolGetModulesDirs(); // Loop on each directory $found=false; @@ -795,29 +775,7 @@ function unActivateModule($value, $requiredby=1) $ret=''; $modName = $value; $modFile = $modName . ".class.php"; - - // Loop on each directory to fill $modulesdir - $modulesdir = array(); - foreach ($conf->file->dol_document_root as $type => $dirroot) - { - $modulesdir[] = $dirroot."/core/modules/"; - - $handle=@opendir(dol_osencode($dirroot)); - if (is_resource($handle)) - { - while (($file = readdir($handle))!==false) - { - if (is_dir($dirroot.'/'.$file) && substr($file, 0, 1) <> '.' && substr($file, 0, 3) <> 'CVS' && $file != 'includes') - { - if (is_dir($dirroot . '/' . $file . '/core/modules/')) - { - $modulesdir[] = $dirroot . '/' . $file . '/core/modules/'; - } - } - } - closedir($handle); - } - } + $modulesdir = dolGetModulesDirs(); // Loop on each directory $found=false; @@ -838,13 +796,13 @@ function unActivateModule($value, $requiredby=1) } else { - // TODO Replace this afte DolibarrModules is moved as abstract class with a try catch to show module is bugged + // TODO Replace this after DolibarrModules is moved as abstract class with a try catch to show module is bugged $genericMod = new DolibarrModules($db); $genericMod->name=preg_replace('/^mod/i','',$modName); $genericMod->rights_class=strtolower(preg_replace('/^mod/i','',$modName)); $genericMod->const_name='MAIN_MODULE_'.strtoupper(preg_replace('/^mod/i','',$modName)); dol_syslog("modules::unActivateModule Failed to find module file, we use generic function with name " . $modName); - $genericMod->_remove(); + $genericMod->_remove(''); } // Desactivation des modules qui dependent de lui @@ -853,6 +811,7 @@ function unActivateModule($value, $requiredby=1) $countrb=count($objMod->requiredby); for ($i = 0; $i < $countrb; $i++) { + //var_dump($objMod->requiredby[$i]); unActivateModule($objMod->requiredby[$i]); } } @@ -883,36 +842,10 @@ function complete_dictionary_with_modules(&$taborder,&$tabname,&$tablib,&$tabsql global $db, $modules, $conf, $langs; // Search modules - $filename = array(); - $modules = array(); - $orders = array(); - $categ = array(); - $dirmod = array(); - $modulesdir = array(); + $modulesdir = dolGetModulesDirs(); $i = 0; // is a sequencer of modules found $j = 0; // j is module number. Automatically affected if module number not defined. - foreach ($conf->file->dol_document_root as $type => $dirroot) - { - $modulesdir[$dirroot . '/core/modules/'] = $dirroot . '/core/modules/'; - - $handle=@opendir($dirroot); - if (is_resource($handle)) - { - while (($file = readdir($handle))!==false) - { - if (is_dir($dirroot.'/'.$file) && substr($file, 0, 1) <> '.' && substr($file, 0, 3) <> 'CVS' && $file != 'includes') - { - if (is_dir($dirroot . '/' . $file . '/core/modules/')) - { - $modulesdir[$dirroot . '/' . $file . '/core/modules/'] = $dirroot . '/' . $file . '/core/modules/'; - } - } - } - closedir($handle); - } - } - foreach ($modulesdir as $dir) { // Load modules attributes in arrays (name, numero, orders) from dir directory @@ -962,14 +895,6 @@ function complete_dictionary_with_modules(&$taborder,&$tabname,&$tablib,&$tabsql } } - $modules[$i] = $objMod; - $filename[$i]= $modName; - $orders[$i] = $objMod->family."_".$j; // Tri par famille puis numero module - //print "x".$modName." ".$orders[$i]."\n
"; - if (isset($categ[$objMod->special])) $categ[$objMod->special]++; // Array of all different modules categories - else $categ[$objMod->special]=1; - $dirmod[$i] = $dirroot; - // Complete arrays //&$tabname,&$tablib,&$tabsql,&$tabsqlsort,&$tabfield,&$tabfieldvalue,&$tabfieldinsert,&$tabrowid,&$tabcond if (empty($objMod->dictionaries) && ! empty($objMod->dictionnaries)) $objMod->dictionaries=$objMod->dictionnaries; // For backward compatibility diff --git a/htdocs/core/lib/bank.lib.php b/htdocs/core/lib/bank.lib.php index bca5b2f1bdf..66dab46b47a 100644 --- a/htdocs/core/lib/bank.lib.php +++ b/htdocs/core/lib/bank.lib.php @@ -72,6 +72,11 @@ function bank_prepare_head(Account $object) $h++; } + $head[$h][0] = DOL_URL_ROOT . "/compta/bank/document.php?account=" . $object->id; + $head[$h][1] = $langs->trans("Documents"); + $head[$h][2] = 'document'; + $h++; + // Show more tabs from modules // Entries must be declared in modules descriptor with line // $this->tabs = array('entity:+tabname:Title:@mymodule:/mymodule/mypage.php?id=__ID__'); to add new tab diff --git a/htdocs/core/lib/date.lib.php b/htdocs/core/lib/date.lib.php index 67c7df4be5b..931f30ce998 100644 --- a/htdocs/core/lib/date.lib.php +++ b/htdocs/core/lib/date.lib.php @@ -144,7 +144,7 @@ function convertTime2Seconds($iHours=0,$iMinutes=0,$iSeconds=0) /** Return, in clear text, value of a number of seconds in days, hours and minutes * * @param int $iSecond Number of seconds - * @param string $format Output format ('all': total delay days hour:min like "2 days 12:30"", 'allhourmin': total delay hours:min like "60:30", 'allhour': total delay hours without min/sec like "60:30", 'fullhour': total delay hour decimal like "60.5" for 60:30, 'hour': only hours part "12", 'min': only minutes part "30", 'sec': only seconds part, 'month': only month part, 'year': only year part); + * @param string $format Output format ('all': total delay days hour:min like "2 days 12:30", 'allwithouthour': total delay days without hour part like "2 days", 'allhourmin': total delay with format hours:min like "60:30", 'allhour': total delay hours without min/sec like "60:30", 'fullhour': total delay hour decimal like "60.5" for 60:30, 'hour': only hours part "12", 'min': only minutes part "30", 'sec': only seconds part, 'month': only month part, 'year': only year part); * @param int $lengthOfDay Length of day (default 86400 seconds for 1 day, 28800 for 8 hour) * @param int $lengthOfWeek Length of week (default 7) * @return string Formated text of duration @@ -157,7 +157,7 @@ function convertSecondToTime($iSecond, $format='all', $lengthOfDay=86400, $lengt if (empty($lengthOfDay)) $lengthOfDay = 86400; // 1 day = 24 hours if (empty($lengthOfWeek)) $lengthOfWeek = 7; // 1 week = 7 days - if ($format == 'all' || $format == 'allhour' || $format == 'allhourmin') + if ($format == 'all' || $format == 'allwithouthour' || $format == 'allhour' || $format == 'allhourmin') { if ($iSecond === 0) return '0'; // This is to avoid having 0 return a 12:00 AM for en_US diff --git a/htdocs/core/lib/files.lib.php b/htdocs/core/lib/files.lib.php index 2f197d8b645..8f6471f4af0 100644 --- a/htdocs/core/lib/files.lib.php +++ b/htdocs/core/lib/files.lib.php @@ -202,6 +202,329 @@ function dol_dir_list($path, $types="all", $recursive=0, $filter="", $excludefil } } +/** + * Scan a directory and return a array of files/directories from a selection. + * Content for string is UTF8 and dir separator is "/". + * + * @param int $fk_soc select socid - for your selection in array + * @param string $module_get Starting path from which to search + * @param string $sortorder SORT_ASC or SORT_DESC + * @param array $excludefiles Array of Regex for exclude filter (example: array('(\.meta|_preview\.png)$','^\.')) + * @return array Array of array( filefolder=> array( filelabel=> array( file=> array('name'=>'xxx','date'=>'yyy','size'=>99,'type'=>'dir|file')))) + */ +function get_soc_file_array($fk_soc, $module_get = false, $sortorder = false, $excludefiles = false) +{ + global $user, $conf, $db; + + $sortfield = "date"; + + if(!$sortorder){ + $sorting = SORT_DESC; + }else{ + $sorting = $sortorder; + } + + $ar_modules_get = array(); + if (is_array($module_get)) $ar_modules_get = $module_get; + elseif (strlen($module_get) > 0) $ar_modules_get[$module_get] = $module_get; + else + { + $ar_modules_get['company'] = 'company'; + $ar_modules_get['dolimail'] = 'dolimail'; + $ar_modules_get['actions'] = 'actions'; + $ar_modules_get['invoice'] = 'invoice'; + $ar_modules_get['order'] = 'order'; + $ar_modules_get['propal'] = 'propal'; + $ar_modules_get['contract'] = 'contract'; + $ar_modules_get['project'] = 'project'; + $ar_modules_get['invoice_supplier'] = 'invoice_supplier'; + $ar_modules_get['order_supplier'] = 'order_supplier'; + } + + + // rights + if (count($ar_modules_get) > 0) + foreach($ar_modules_get as $curmodule) + { + switch($curmodule) + { + case 'company': + if (! empty($conf->societe->enabled)) // Recht Alle oder nur die Vertriebspartneradressen + $ar_modules_secure['company']['outputdir'] = $conf->societe->dir_output; + break; + case 'dolimail': + if (! empty($conf->dolimail->enabled) && ($user->rights->dolimail->read || $user->admin)) + $ar_modules_secure[$curmodule]['outputdir']=$conf->dolimail->dir_output.'/attachments'; + break; + case 'actions': + if (! empty($conf->agenda->enabled) || ($user->rights->agenda->allactions->read || $user->admin)) + $ar_modules_secure[$curmodule]['outputdir']=$conf->agenda->dir_output; + break; + case 'invoice': + if (! empty($conf->facture->enabled) && ($user->rights->facture->lire || $user->admin)) + $ar_modules_secure[$curmodule]['outputdir']=$conf->facture->dir_output; + break; + case 'order': + if (!empty($conf->commande->enabled) && ($user->rights->commande->lire || $user->admin)) + $ar_modules_secure[$curmodule]['outputdir']=$conf->commande->dir_output; + break; + case 'propal': + if (!empty($conf->propal->enabled) && ($user->rights->propale->lire || $user->admin)) + $ar_modules_secure[$curmodule]['outputdir']=$conf->propal->dir_output; + break; + case 'project': + if (! empty($conf->projet->enabled) && ($user->rights->projet->lire || $user->admin)) + $ar_modules_secure[$curmodule]['outputdir']=$conf->projet->dir_output; + break; + case 'invoice_supplier': + if (! empty($conf->fournisseur->enabled) && ($user->rights->fournisseur->facture->lire || $user->admin)) + $ar_modules_secure[$curmodule]['outputdir']=$conf->fournisseur->dir_output.'/facture'; + break; + case 'order_supplier': + if (! empty($conf->fournisseur->enabled) && ($user->rights->fournisseur->commande->lire || $user->admin)) + $ar_modules_secure[$curmodule]['outputdir']=$conf->fournisseur->dir_output.'/commande'; + break; + } + } + /* TODO make a outputdir*/ + //unset($ar_modules_secure['dolimail']); + unset($ar_modules_secure['project']); // project (list with project) is "ref" + unset($ar_modules_secure['actions']); + unset($ar_modules_secure['contract']); + /* TODO make a outputdir*/ + unset($curmodule); + + if($fk_soc > 0) + $ar_modules_get = $ar_modules_secure; + + $xy=0; + if (count($ar_modules_get)>0) + foreach($ar_modules_get as $curmodule => $myarray) + { + if($fk_soc > 0 && $curmodule != "company") + { + + // SQL to find documents (ref number) + + if($curmodule == "invoice") $sql = "SELECT facnumber as refstr FROM ".MAIN_DB_PREFIX."facture"; + elseif($curmodule == "order") $sql = "SELECT ref as refstr FROM ".MAIN_DB_PREFIX."commande"; + elseif($curmodule == "invoice_supplier") $sql = "SELECT rowid as refstr FROM ".MAIN_DB_PREFIX."facture_fourn"; + elseif($curmodule == "order_supplier") $sql = "SELECT ref as refstr FROM ".MAIN_DB_PREFIX."commande_fournisseur"; + elseif($curmodule == "propal") $sql = "SELECT ref as refstr FROM ".MAIN_DB_PREFIX."propal"; + elseif($curmodule == "contract") $sql = "SELECT ref as refstr FROM ".MAIN_DB_PREFIX."contrat"; + elseif($curmodule == "dolimail") $sql = "SELECT uid as refstr, subject FROM ".MAIN_DB_PREFIX."mails"; + + $sql.= ' WHERE entity IN ('.getEntity('societe', 1).')'; + $sql.= " AND fk_soc = '".$fk_soc."'"; + + + $res = $db->query($sql); + if ($res && $db->num_rows($res) > 0) + { + while($obj = $db->fetch_object($res)) + { + $ar_modules_secure[$curmodule]['socref'][] = $obj->refstr; + if($curmodule == "dolimail") $ar_modules_secure['dolimail']['subject'][$obj->refstr] = $obj->subject; + } + } + else + { + unset($ar_modules_secure[$curmodule]); + continue; + $errors[]="SQL Error: ".$sql; + $error++; + } + + + }else{ + if($curmodule == "dolimail") $sql = "SELECT uid as refstr, subject FROM ".MAIN_DB_PREFIX."mails"; + + $res = $db->query($sql); + if ($res && $db->num_rows($res) > 0) + { + while($obj = $db->fetch_object($res)) + { + if($curmodule == "dolimail") $ar_modules_secure['dolimail']['subject'][$obj->refstr] = $obj->subject; + } + } + } + + // Data in Array + // Get Array from ar_module + + $output[$curmodule]=dol_dir_list($myarray['outputdir'],"files",1,'', $excludefiles, $sortfield, $sorting,1); + if($fk_soc > 0) + { + if($curmodule == "company") + { + foreach($output["company"] as $label => $filedata) + { + if($filedata['level1name'] != $fk_soc) + { + unset($output['company'][$label]); + } + } + } + + elseif($curmodule == "invoice") + { + if (! is_array($ar_modules_secure[$curmodule]['socref'])) { unset($output[$curmodule]); continue; } // wenn no file exsit + foreach($output["invoice"] as $label => $filedata) + { + if (! in_array($filedata['level1name'], $ar_modules_secure[$curmodule]['socref'])) + { + unset($output[$curmodule][$label]); // throw all ref number who are not in ($fac_supp_N_arr) array + } + + } + } + elseif($curmodule == "invoice_supplier") + { + if (! is_array($ar_modules_secure[$curmodule]['socref'])) { unset($output[$curmodule]); } // throw all ref number who are not in ($fac_invoice_arr) array + foreach($output["invoice_supplier"] as $label => $filedata) + { + if (! in_array($filedata['level1name'], $ar_modules_secure[$curmodule]['socref'])) { + unset($output[$curmodule][$label]); // throw all ref number who are not in ($fac_supp_N_arr) array + } + } + } + elseif($curmodule == "order") + { + if (! is_array($ar_modules_secure[$curmodule]['socref'])) { unset($output[$curmodule]); continue; } // throw all ref number who are not in ($fac_invoice_arr) array + foreach($output["order"] as $label => $filedata) + { + if (! in_array($filedata['level1name'], $ar_modules_secure[$curmodule]['socref'])) { + unset($output[$curmodule][$label]); // throw all ref number who are not in ($ref_order_arr) array + } + } + } + elseif($curmodule == "order_supplier") + { + if (! is_array($ar_modules_secure[$curmodule]['socref'])) { unset($output[$curmodule]); continue; } // throw all ref number who are not in ($fac_invoice_arr) array + foreach($output["order_supplier"] as $label => $filedata) + { + if (! in_array($filedata['level1name'], $ar_modules_secure[$curmodule]['socref'])) { + unset($output[$curmodule][$label]); // throw all ref number who are not in ($ref_order_supp_arr) array + } + } + } + elseif($curmodule == "propal") + { + if (! is_array($ar_modules_secure[$curmodule]['socref'])) { unset($output[$curmodule]); continue; } // throw all ref number who are not in ($fac_invoice_arr) array + foreach($output["propal"] as $label => $filedata) + { + if (! in_array($filedata['level1name'], $ar_modules_secure[$curmodule]['socref'])) { + unset($output[$curmodule][$label]); // throw all ref number who are not in ($ref_propal_arr) array + } + } + } + elseif($curmodule == "contract") + { + if (! is_array($ar_modules_secure[$curmodule]['socref'])) { unset($output[$curmodule]); continue; } // throw all ref number who are not in ($fac_invoice_arr) array + foreach($output["contract"] as $label => $filedata) + { + if (! in_array($filedata['level1name'], $ar_modules_secure[$curmodule]['socref'])) { + unset($output[$curmodule][$label]); // throw all ref number who are not in ($ref_contract_arr) array + } + } + } + elseif($curmodule == "dolimail") + { + + if (! is_array($ar_modules_secure[$curmodule]['socref'])) { unset($output[$curmodule]); continue; } // throw all ref number who are not in ($fac_invoice_arr) array + foreach($output["dolimail"] as $label => $filedata) + { + if($filedata['name'] == "winmail.dat" || $filedata['name'] == "smime.p7s") unset($output[$curmodule][$label]); + else + if (! in_array($filedata['level1name'], $ar_modules_secure[$curmodule]['socref'])) { + unset($output[$curmodule][$label]); // throw all ref number who are not in ($ref_propal_arr) array + } + } + } + // Error if ther isn't any File + if(count($output[$curmodule]) == 0) + { + $error++; + $errors[]="Error [404]: No File found for User: ".$fk_soc." in module: ".$curmodule; + unset($output[$curmodule]); + } + } + + // Extra for Mail attachments + if($curmodule == "dolimail" && count($output["dolimail"])>0) + { + foreach($output["dolimail"] as $label => $filedata) + { + $output[$curmodule][$label]['subject'] = $ar_modules_secure['dolimail']['subject'][$filedata['level1name']]; + } + } + + // Extra for Mail attachments + if($curmodule == "invoice" && count($output["invoice"])>0) + { + foreach($output["invoice"] as $label => $filedata) + { + $output[$curmodule][$label]['subject'] = $filedata['level1name']; + } + } + + // Extra for Mail attachments + if($curmodule == "invoice_supplier" && count($output["invoice_supplier"])>0) + { + foreach($output["invoice_supplier"] as $label => $filedata) + { + $output[$curmodule][$label]['subject'] = $filedata['level1name']; + } + } + + // Extra for Mail attachments + if($curmodule == "contract" && count($output["contract"])>0) + { + foreach($output["contract"] as $label => $filedata) + { + $output[$curmodule][$label]['subject'] = $filedata['level1name']; + } + } + + $xy++; + } + + if(count($output) > 0) + { + return $output; + } + else + { + return -1; + } +} + +/** + * Calculate Bytes to kb, mb and translate it to current language + * + * @param int $byt Bytes + * @return string calculated string + */ +function calculate_byte($byt) +{ + global $langs; + + if ($byt < 1024) { + $unit = ' '.$langs->trans("b"); + $mailsize=$byt; + } else if ($byt / 1024 > 1024) { + $mailsize = $byt / 1024 / 1024; + $unit = ' '.$langs->trans("Mb"); + } else { + $mailsize = $byt / 1024; + $unit = ' '.$langs->trans("Kb"); + } + + $val = number_format($mailsize, 2).$unit; + + return $val; +} + /** * Fast compare of 2 files identified by their properties ->name, ->date and ->size * diff --git a/htdocs/core/lib/functions.lib.php b/htdocs/core/lib/functions.lib.php index e0a7ec1b9f2..93d15eb74f4 100644 --- a/htdocs/core/lib/functions.lib.php +++ b/htdocs/core/lib/functions.lib.php @@ -142,14 +142,14 @@ function getEntity($element=false, $shared=0) */ function getBrowserInfo($user_agent) { - include_once DOL_DOCUMENT_ROOT.'/includes/mobiledetect/mobiledetect.class.php'; + include_once DOL_DOCUMENT_ROOT.'/includes/mobiledetect/mobiledetectlib/Mobile_Detect.php'; $name='unknown'; $version=''; $os='unknown'; $phone = ''; - $detectmobile = new MobileDetect(null, $user_agent); + $detectmobile = new Mobile_Detect(null, $user_agent); $tablet = $detectmobile->isTablet(); if ($detectmobile->isMobile()) { @@ -302,7 +302,7 @@ function dol_getprefix() * * @param string $relpath Relative path to file (Ie: mydir/myfile, ../myfile, ...) * @param string $classname Class name - * @return bool + * @return bool True if load is a success, False if it fails */ function dol_include_once($relpath, $classname='') { @@ -2766,7 +2766,7 @@ function print_fiche_titre($title, $mesg='', $picto='title_generic.png', $pictoi * @param int $id To force an id on html objects * @return string */ -function load_fiche_titre($titre, $mesg='', $picto='title.png', $pictoisfullpath=0, $id=0) +function load_fiche_titre($titre, $mesg='', $picto='title_generic.png', $pictoisfullpath=0, $id=0) { global $conf; @@ -3743,7 +3743,7 @@ function yn($yesno, $case=1, $color=0) * * @param string $num Id of object * @param int $level Level of subdirs to return (1, 2 or 3 levels) - * @param int $alpha Use alpha ref + * @param int $alpha 0=Keep number only to forge path, 1=Use alpha part afer the - (By default, use 0). * @param int $withoutslash 0=With slash at end, 1=without slash at end (except if '/', we return '') * @param Object $object Object * @param string $modulepart Type of object ('invoice_supplier, 'donation', 'invoice', ...') diff --git a/htdocs/core/lib/functions2.lib.php b/htdocs/core/lib/functions2.lib.php index 9c77729ac5a..651e4ea54ac 100644 --- a/htdocs/core/lib/functions2.lib.php +++ b/htdocs/core/lib/functions2.lib.php @@ -1,9 +1,10 @@ - * Copyright (C) 2008-2012 Regis Houssin - * Copyright (C) 2008 Raphael Bertrand (Resultic) +/* Copyright (C) 2008-2011 Laurent Destailleur + * Copyright (C) 2008-2012 Regis Houssin + * Copyright (C) 2008 Raphael Bertrand (Resultic) * Copyright (C) 2014 Marcos García * Copyright (C) 2015 Ferran Marcet + * Copyright (C) 2015 Raphaël Doursenaud * * 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 @@ -104,7 +105,9 @@ function dolGetModulesDirs($subdir='') foreach ($conf->file->dol_document_root as $type => $dirroot) { // Default core/modules dir - $modulesdir[$dirroot . '/core/modules'.$subdir.'/'] = $dirroot . '/core/modules'.$subdir.'/'; + if ($type === 'main') { + $modulesdir[$dirroot . '/core/modules' . $subdir . '/'] = $dirroot . '/core/modules' . $subdir . '/'; + } // Scan dir from external modules $handle=@opendir($dirroot); diff --git a/htdocs/core/lib/geturl.lib.php b/htdocs/core/lib/geturl.lib.php index af0c6b91da0..682ddb1b1d1 100644 --- a/htdocs/core/lib/geturl.lib.php +++ b/htdocs/core/lib/geturl.lib.php @@ -24,12 +24,12 @@ /** * Function get content from an URL (use proxy if proxy defined) * - * @param string $url URL to call. - * @param string $postorget 'POST', 'GET', 'HEAD' - * @param string $param Parameters of URL (x=value1&y=value2) - * @param string $followlocation 1=Follow location, 0=Do not follow - * @param array $addheaders Array of string to add into header. Example: array('Accept: application/xrds+xml', ....) - * @return array Returns an associative array containing the response from the server array('content'=>response,'curl_error_no'=>errno,'curl_error_msg'=>errmsg...) + * @param string $url URL to call. + * @param string $postorget 'POST', 'GET', 'HEAD', 'PUT', 'PUTALREADYFORMATED', 'DELETE' + * @param string $param Parameters of URL (x=value1&y=value2) or may be a formated content with PUTALREADYFORMATED + * @param string $followlocation 1=Follow location, 0=Do not follow + * @param array $addheaders Array of string to add into header. Example: ('Accept: application/xrds+xml', ....) + * @return array Returns an associative array containing the response from the server array('content'=>response,'curl_error_no'=>errno,'curl_error_msg'=>errmsg...) */ function getURLContent($url,$postorget='GET',$param='',$followlocation=1,$addheaders=array()) { @@ -74,7 +74,18 @@ function getURLContent($url,$postorget='GET',$param='',$followlocation=1,$addhea else if ($postorget == 'PUT') { curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); // HTTP request is 'PUT' - curl_setopt($ch, CURLOPT_POSTFIELDS, $param); // Setting param x=a&y=z as PUT fields + if (! is_array($param)) parse_str($param, $array_param); + else + { + dol_syslog("parameter param must be a string", LOG_WARNING); + $array_param=$param; + } + curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($array_param)); // Setting param x=a&y=z as PUT fields + } + else if ($postorget == 'PUTALREADYFORMATED') + { + curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); // HTTP request is 'PUT' + curl_setopt($ch, CURLOPT_POSTFIELDS, $param); // param = content of post, like a xml string } else if ($postorget == 'HEAD') { diff --git a/htdocs/core/lib/memory.lib.php b/htdocs/core/lib/memory.lib.php index b68016c3a46..69c127f915c 100644 --- a/htdocs/core/lib/memory.lib.php +++ b/htdocs/core/lib/memory.lib.php @@ -47,14 +47,19 @@ function dol_setcache($memoryid,$data) // Using a memcached server if (! empty($conf->memcached->enabled) && class_exists('Memcached')) { - $memoryid=session_name().'_'.$memoryid; - $m=new Memcached(); - $tmparray=explode(':',$conf->global->MEMCACHED_SERVER); - $result=$m->addServer($tmparray[0], $tmparray[1]?$tmparray[1]:11211); - //$m->setOption(Memcached::OPT_COMPRESSION, false); - //print "Add memoryid=".$memoryid; - $m->add($memoryid,$data); // This fails if key already exists - $rescode=$m->getResultCode(); + global $dolmemcache; + if (empty($dolmemcache) || ! is_object($dolmemcache)) + { + $dolmemcache=new Memcached(); + $tmparray=explode(':',$conf->global->MEMCACHED_SERVER); + $result=$dolmemcache->addServer($tmparray[0], $tmparray[1]?$tmparray[1]:11211); + if (! $result) return -1; + } + + $memoryid=session_name().'_'.$memoryid; + //$dolmemcache->setOption(Memcached::OPT_COMPRESSION, false); + $dolmemcache->add($memoryid,$data); // This fails if key already exists + $rescode=$dolmemcache->getResultCode(); if ($rescode == 0) { return count($data); @@ -66,12 +71,18 @@ function dol_setcache($memoryid,$data) } else if (! empty($conf->memcached->enabled) && class_exists('Memcache')) { - $memoryid=session_name().'_'.$memoryid; - $m=new Memcache(); - $tmparray=explode(':',$conf->global->MEMCACHED_SERVER); - $result=$m->addServer($tmparray[0], $tmparray[1]?$tmparray[1]:11211); - //$m->setOption(Memcached::OPT_COMPRESSION, false); - $result=$m->add($memoryid,$data); // This fails if key already exists + global $dolmemcache; + if (empty($dolmemcache) || ! is_object($dolmemcache)) + { + $dolmemcache=new Memcache(); + $tmparray=explode(':',$conf->global->MEMCACHED_SERVER); + $result=$dolmemcache->addServer($tmparray[0], $tmparray[1]?$tmparray[1]:11211); + if (! $result) return -1; + } + + $memoryid=session_name().'_'.$memoryid; + //$dolmemcache->setOption(Memcached::OPT_COMPRESSION, false); + $result=$dolmemcache->add($memoryid,$data); // This fails if key already exists if ($result) { return count($data); @@ -103,10 +114,16 @@ function dol_getcache($memoryid) // Using a memcached server if (! empty($conf->memcached->enabled) && class_exists('Memcached')) { + global $m; + if (empty($m) || ! is_object($m)) + { + $m=new Memcached(); + $tmparray=explode(':',$conf->global->MEMCACHED_SERVER); + $result=$m->addServer($tmparray[0], $tmparray[1]?$tmparray[1]:11211); + if (! $result) return -1; + } + $memoryid=session_name().'_'.$memoryid; - $m=new Memcached(); - $tmparray=explode(':',$conf->global->MEMCACHED_SERVER); - $result=$m->addServer($tmparray[0], $tmparray[1]?$tmparray[1]:11211); //$m->setOption(Memcached::OPT_COMPRESSION, false); //print "Get memoryid=".$memoryid; $data=$m->get($memoryid); @@ -124,10 +141,16 @@ function dol_getcache($memoryid) } else if (! empty($conf->memcached->enabled) && class_exists('Memcache')) { - $memoryid=session_name().'_'.$memoryid; - $m=new Memcache(); - $tmparray=explode(':',$conf->global->MEMCACHED_SERVER); - $result=$m->addServer($tmparray[0], $tmparray[1]?$tmparray[1]:11211); + global $m; + if (empty($m) || ! is_object($m)) + { + $m=new Memcache(); + $tmparray=explode(':',$conf->global->MEMCACHED_SERVER); + $result=$m->addServer($tmparray[0], $tmparray[1]?$tmparray[1]:11211); + if (! $result) return -1; + } + + $memoryid=session_name().'_'.$memoryid; //$m->setOption(Memcached::OPT_COMPRESSION, false); $data=$m->get($memoryid); //print "memoryid=".$memoryid." - rescode=".$rescode." - data=".count($data)."\n
"; diff --git a/htdocs/core/lib/pdf.lib.php b/htdocs/core/lib/pdf.lib.php index d294bac5132..8beae962d09 100644 --- a/htdocs/core/lib/pdf.lib.php +++ b/htdocs/core/lib/pdf.lib.php @@ -676,7 +676,8 @@ function pdf_bank(&$pdf,$outputlangs,$curx,$cury,$account,$onlynumber=0,$default if ($account->getCountryCode() == 'IN') $ibankey="IFSC"; if (! empty($account->iban)) { - $ibanDisplay_temp = $outputlangs->convToOutputCharset($account->iban); + //Remove whitespaces to ensure we are dealing with the format we expect + $ibanDisplay_temp = str_replace(' ', '', $outputlangs->convToOutputCharset($account->iban)); $ibanDisplay = ""; for($i = 0; $i < dol_strlen($ibanDisplay_temp); $i++) @@ -744,7 +745,7 @@ function pdf_pagefoot(&$pdf,$outputlangs,$paramfreetext,$fromcompany,$marge_bass // First line of company infos $line1=""; $line2=""; $line3=""; $line4=""; - if ($showdetails && 1) + if ($showdetails) { // Company name if ($fromcompany->name) @@ -788,7 +789,7 @@ function pdf_pagefoot(&$pdf,$outputlangs,$paramfreetext,$fromcompany,$marge_bass $line2.=($line2?" - ":"").$fromcompany->email; } } - if (($showdetails && 2) || ($fromcompany->country_code == 'DE')) + if ($showdetails || ($fromcompany->country_code == 'DE')) { // Managers if ($fromcompany->managers) @@ -1692,64 +1693,61 @@ function pdf_getLinkedObjects($object,$outputlangs) if ($objecttype == 'propal') { $outputlangs->load('propal'); - $num=count($objects); - for ($i=0;$i<$num;$i++) + + foreach($objects as $elementobject) { $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefProposal"); - $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($objects[$i]->ref); + $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref); $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DatePropal"); - $linkedobjects[$objecttype]['date_value'] = dol_print_date($objects[$i]->date,'day','',$outputlangs); + $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date,'day','',$outputlangs); } } else if ($objecttype == 'commande') { $outputlangs->load('orders'); - $num=count($objects); - for ($i=0;$i<$num;$i++) + foreach($objects as $elementobject) { $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder"); - $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($objects[$i]->ref) . ($objects[$i]->ref_client ? ' ('.$objects[$i]->ref_client.')' : ''); + $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref) . ($elementobject->ref_client ? ' ('.$elementobject->ref_client.')' : ''); $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("OrderDate"); - $linkedobjects[$objecttype]['date_value'] = dol_print_date($objects[$i]->date,'day','',$outputlangs); + $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date,'day','',$outputlangs); } } else if ($objecttype == 'contrat') { $outputlangs->load('contracts'); - $num=count($objects); - for ($i=0;$i<$num;$i++) + foreach($objects as $elementobject) { $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefContract"); - $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($objects[$i]->ref); + $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($elementobject->ref); $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DateContract"); - $linkedobjects[$objecttype]['date_value'] = dol_print_date($objects[$i]->date_contrat,'day','',$outputlangs); + $linkedobjects[$objecttype]['date_value'] = dol_print_date($elementobject->date_contrat,'day','',$outputlangs); } } else if ($objecttype == 'shipping') { $outputlangs->load('orders'); $outputlangs->load('sendings'); - $num=count($objects); - for ($i=0;$i<$num;$i++) + foreach($objects as $elementobject) { - $objects[$i]->fetchObjectLinked(); - $order = $objects[$i]->linkedObjects['commande'][0]; + $elementobject->fetchObjectLinked(); + $order = $elementobject->linkedObjects['commande'][0]; if (! empty($object->linkedObjects['commande'])) // There is already a link to order so we show only info of shipment { $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefSending"); - $linkedobjects[$objecttype]['ref_value'].= $outputlangs->transnoentities($objects[$i]->ref); + $linkedobjects[$objecttype]['ref_value'].= $outputlangs->transnoentities($elementobject->ref); $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("DateSending"); - $linkedobjects[$objecttype]['date_value'].= dol_print_date($objects[$i]->date_delivery,'day','',$outputlangs); + $linkedobjects[$objecttype]['date_value'].= dol_print_date($elementobject->date_delivery,'day','',$outputlangs); } else // We show both info of order and shipment { $linkedobjects[$objecttype]['ref_title'] = $outputlangs->transnoentities("RefOrder") . ' / ' . $outputlangs->transnoentities("RefSending"); $linkedobjects[$objecttype]['ref_value'] = $outputlangs->transnoentities($order->ref) . ($order->ref_client ? ' ('.$order->ref_client.')' : ''); - $linkedobjects[$objecttype]['ref_value'].= ' / ' . $outputlangs->transnoentities($objects[$i]->ref); + $linkedobjects[$objecttype]['ref_value'].= ' / ' . $outputlangs->transnoentities($elementobject->ref); $linkedobjects[$objecttype]['date_title'] = $outputlangs->transnoentities("OrderDate") . ' / ' . $outputlangs->transnoentities("DateSending"); $linkedobjects[$objecttype]['date_value'] = dol_print_date($order->date,'day','',$outputlangs); - $linkedobjects[$objecttype]['date_value'].= ' / ' . dol_print_date($objects[$i]->date_delivery,'day','',$outputlangs); + $linkedobjects[$objecttype]['date_value'].= ' / ' . dol_print_date($elementobject->date_delivery,'day','',$outputlangs); } } } diff --git a/htdocs/core/lib/report.lib.php b/htdocs/core/lib/report.lib.php index 79ab5fe0ead..8946449d5ac 100644 --- a/htdocs/core/lib/report.lib.php +++ b/htdocs/core/lib/report.lib.php @@ -61,7 +61,7 @@ function report_header($nom,$variante,$period,$periodlink,$description,$builddat // Ligne de titre print '
'; - print ''; + print ''; if (! $variantexxx) print ''; - print ''; + print ''; if (! $variante) print ''; - print ''; + print ''; print ''; print ''; diff --git a/htdocs/core/lib/security.lib.php b/htdocs/core/lib/security.lib.php index 78f8309a05b..0e7f74b32f7 100644 --- a/htdocs/core/lib/security.lib.php +++ b/htdocs/core/lib/security.lib.php @@ -90,7 +90,7 @@ function dol_hash($chain,$type=0) 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)); - // No enconding defined + // No particular enconding defined, use default return md5($chain); } diff --git a/htdocs/core/lib/security2.lib.php b/htdocs/core/lib/security2.lib.php index 04e0fb133f6..3297047bef5 100644 --- a/htdocs/core/lib/security2.lib.php +++ b/htdocs/core/lib/security2.lib.php @@ -439,7 +439,7 @@ function encodedecode_dbpassconf($level=0) /** * Return a generated password using default module * - * @param boolean $generic true=Create generic password (use default crypt function), false=Use the configured password generation module + * @param boolean $generic true=Create generic password (use md5, sha1 depending on setup), false=Use the configured password generation module * @return string New value for password */ function getRandomPassword($generic=false) diff --git a/htdocs/core/menus/init_menu_auguria.sql b/htdocs/core/menus/init_menu_auguria.sql index 19ada8b9b56..4dd1fd33d0f 100644 --- a/htdocs/core/menus/init_menu_auguria.sql +++ b/htdocs/core/menus/init_menu_auguria.sql @@ -23,6 +23,9 @@ insert into llx_menu (module, enabled, rowid, menu_handler, type, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$user->admin', __HANDLER__, 'left', 100__+MAX_llx_menu__, 'home', 'setup', 1__+MAX_llx_menu__, '/admin/index.php?leftmenu=setup', 'Setup', 0, 'admin', '', '', 2, 0, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 101__+MAX_llx_menu__, 'home', '', 100__+MAX_llx_menu__, '/admin/company.php?leftmenu=setup', 'MenuCompanySetup', 1, 'admin', '', '', 2, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 102__+MAX_llx_menu__, 'home', '', 100__+MAX_llx_menu__, '/admin/ihm.php?leftmenu=setup', 'GUISetup', 1, 'admin', '', '', 2, 4, __ENTITY__); + +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 114__+MAX_llx_menu__, 'home', '', 100__+MAX_llx_menu__, '/admin/translation.php?leftmenu=setup', 'Translation', 1, 'admin', '', '', 2, 4, __ENTITY__); + insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 103__+MAX_llx_menu__, 'home', '', 100__+MAX_llx_menu__, '/admin/modules.php?leftmenu=setup', 'Modules', 1, 'admin', '', '', 2, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 104__+MAX_llx_menu__, 'home', '', 100__+MAX_llx_menu__, '/admin/boxes.php?leftmenu=setup', 'Boxes', 1, 'admin', '', '', 2, 6, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$leftmenu=="setup"', __HANDLER__, 'left', 105__+MAX_llx_menu__, 'home', '', 100__+MAX_llx_menu__, '/admin/menus.php?leftmenu=setup', 'Menus', 1, 'admin', '', '', 2, 3, __ENTITY__); @@ -197,8 +200,8 @@ insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, left insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && $leftmenu=="tax_social"', __HANDLER__, 'left', 2251__+MAX_llx_menu__, 'accountancy', '', 2250__+MAX_llx_menu__, '/compta/sociales/charges.php?leftmenu=tax_social&action=create', 'MenuNewSocialContribution', 2, '', '$user->rights->tax->charges->creer', '', 0, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && $leftmenu=="tax_social"', __HANDLER__, 'left', 2252__+MAX_llx_menu__, 'accountancy', '', 2250__+MAX_llx_menu__, '/compta/charges/index.php?leftmenu=tax_social&mainmenu=accountancy&mode=sconly', 'Payments', 2, '', '$user->rights->tax->charges->lire', '', 0, 3, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && empty($conf->global->TAX_DISABLE_VAT_MENUS)', __HANDLER__, 'left', 2300__+MAX_llx_menu__, 'accountancy', 'tax_vat', 2200__+MAX_llx_menu__, '/compta/tva/index.php?leftmenu=tax_vat&mainmenu=accountancy', 'VAT', 1, 'companies', '$user->rights->tax->charges->lire', '', 0, 7, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && empty($conf->global->TAX_DISABLE_VAT_MENUS) && $leftmenu=="tax_vat"', __HANDLER__, 'left', 2301__+MAX_llx_menu__, 'accountancy', '', 2300__+MAX_llx_menu__, '/compta/tva/card.php?leftmenu=tax_vat&action=create', 'NewPayment', 2, 'companies', '$user->rights->tax->charges->creer', '', 0, 0, __ENTITY__); -insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && empty($conf->global->TAX_DISABLE_VAT_MENUS) && $leftmenu=="tax_vat"', __HANDLER__, 'left', 2302__+MAX_llx_menu__, 'accountancy', '', 2300__+MAX_llx_menu__, '/compta/tva/reglement.php?leftmenu=tax_vat', 'Payments', 2, 'companies', '$user->rights->tax->charges->lire', '', 0, 1, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && empty($conf->global->TAX_DISABLE_VAT_MENUS) && $leftmenu=="tax_vat"', __HANDLER__, 'left', 2301__+MAX_llx_menu__, 'accountancy', '', 2300__+MAX_llx_menu__, '/compta/tva/card.php?leftmenu=tax_vat&action=create', 'New', 2, 'companies', '$user->rights->tax->charges->creer', '', 0, 0, __ENTITY__); +insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && empty($conf->global->TAX_DISABLE_VAT_MENUS) && $leftmenu=="tax_vat"', __HANDLER__, 'left', 2302__+MAX_llx_menu__, 'accountancy', '', 2300__+MAX_llx_menu__, '/compta/tva/reglement.php?leftmenu=tax_vat', 'List', 2, 'companies', '$user->rights->tax->charges->lire', '', 0, 1, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && empty($conf->global->TAX_DISABLE_VAT_MENUS) && $leftmenu=="tax_vat"', __HANDLER__, 'left', 2303__+MAX_llx_menu__, 'accountancy', '', 2300__+MAX_llx_menu__, '/compta/tva/clients.php?leftmenu=tax_vat', 'ReportByCustomers', 2, 'companies', '$user->rights->tax->charges->lire', '', 0, 2, __ENTITY__); insert into llx_menu (module, enabled, menu_handler, type, rowid, mainmenu, leftmenu, fk_menu, url, titre, level, langs, perms, target, usertype, position, entity) values ('', '$conf->tax->enabled && empty($conf->global->TAX_DISABLE_VAT_MENUS) && $leftmenu=="tax_vat"', __HANDLER__, 'left', 2304__+MAX_llx_menu__, 'accountancy', '', 2300__+MAX_llx_menu__, '/compta/tva/quadri_detail.php?leftmenu=tax_vat', 'ReportByQuarter', 2, 'companies', '$user->rights->tax->charges->lire', '', 0, 3, __ENTITY__); -- Ventilation (accounting) diff --git a/htdocs/core/menus/standard/eldy.lib.php b/htdocs/core/menus/standard/eldy.lib.php index 807f6759c51..27756a5b0c2 100644 --- a/htdocs/core/menus/standard/eldy.lib.php +++ b/htdocs/core/menus/standard/eldy.lib.php @@ -488,7 +488,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu $newmenu->add("/admin/modules.php?mainmenu=home", $langs->trans("Modules").$warnpicto,1); $newmenu->add("/admin/menus.php?mainmenu=home", $langs->trans("Menus"),1); $newmenu->add("/admin/ihm.php?mainmenu=home", $langs->trans("GUISetup"),1); - if (! in_array($langs->defaultlang,array('en_US','en_GB','en_NZ','en_AU','fr_FR','fr_BE','es_ES','ca_ES'))) + if (! in_array($langs->defaultlang,array('en_US'))) { $newmenu->add("/admin/translation.php", $langs->trans("Translation"),1); } @@ -734,7 +734,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu if (! empty($conf->ficheinter->enabled)) { $langs->load("interventions"); - $newmenu->add("/fichinter/list.php?leftmenu=ficheinter", $langs->trans("Interventions"), 0, $user->rights->ficheinter->lire, '', $mainmenu, 'ficheinter', 200); + $newmenu->add("/fichinter/index.php?leftmenu=ficheinter", $langs->trans("Interventions"), 0, $user->rights->ficheinter->lire, '', $mainmenu, 'ficheinter', 200); $newmenu->add("/fichinter/card.php?action=create&leftmenu=ficheinter", $langs->trans("NewIntervention"), 1, $user->rights->ficheinter->creer, '', '', '', 201); $newmenu->add("/fichinter/list.php?leftmenu=ficheinter", $langs->trans("List"), 1, $user->rights->ficheinter->lire, '', '', '', 202); } @@ -789,7 +789,7 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu if (empty($leftmenu) || ($leftmenu == 'suppliers_bills')) { $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills&search_status=0", $langs->trans("BillShortStatusDraft"),2,$user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills'); - $newmenu->add("/fourn/facture/impayees.php", $langs->trans("BillShortStatusNotPaid"),2,$user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills'); + $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills&search_status=1", $langs->trans("BillShortStatusNotPaid"),2,$user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills'); $newmenu->add("/fourn/facture/list.php?leftmenu=suppliers_bills&search_status=2", $langs->trans("BillShortStatusPaid"),2,$user->rights->fournisseur->facture->lire, '', $mainmenu, 'suppliers_bills'); } @@ -866,8 +866,8 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu if (empty($conf->global->TAX_DISABLE_VAT_MENUS)) { $newmenu->add("/compta/tva/index.php?leftmenu=tax_vat&mainmenu=accountancy",$langs->trans("VAT"),1,$user->rights->tax->charges->lire, '', $mainmenu, 'tax_vat'); - if (empty($leftmenu) || preg_match('/^tax_vat/i',$leftmenu)) $newmenu->add("/compta/tva/card.php?leftmenu=tax_vat&action=create",$langs->trans("NewPayment"),2,$user->rights->tax->charges->creer); - if (empty($leftmenu) || preg_match('/^tax_vat/i',$leftmenu)) $newmenu->add("/compta/tva/reglement.php?leftmenu=tax_vat",$langs->trans("Payments"),2,$user->rights->tax->charges->lire); + if (empty($leftmenu) || preg_match('/^tax_vat/i',$leftmenu)) $newmenu->add("/compta/tva/card.php?leftmenu=tax_vat&action=create",$langs->trans("New"),2,$user->rights->tax->charges->creer); + if (empty($leftmenu) || preg_match('/^tax_vat/i',$leftmenu)) $newmenu->add("/compta/tva/reglement.php?leftmenu=tax_vat",$langs->trans("List"),2,$user->rights->tax->charges->lire); if (empty($leftmenu) || preg_match('/^tax_vat/i',$leftmenu)) $newmenu->add("/compta/tva/clients.php?leftmenu=tax_vat", $langs->trans("ReportByCustomers"), 2, $user->rights->tax->charges->lire); if (empty($leftmenu) || preg_match('/^tax_vat/i',$leftmenu)) $newmenu->add("/compta/tva/quadri_detail.php?leftmenu=tax_vat", $langs->trans("ReportByQuarter"), 2, $user->rights->tax->charges->lire); global $mysoc; @@ -1190,12 +1190,12 @@ function print_left_eldy_menu($db,$menu_array_before,$menu_array_after,&$tabMenu // Project affected to user $newmenu->add("/projet/index.php?leftmenu=projects&mode=mine", $langs->trans("MyProjects"), 0, $user->rights->projet->lire, '', $mainmenu, 'myprojects'); $newmenu->add("/projet/card.php?leftmenu=projects&action=create&mode=mine", $langs->trans("NewProject"), 1, $user->rights->projet->creer); - $newmenu->add("/projet/list.php?leftmenu=projects&mode=mine", $langs->trans("List"), 1, $user->rights->projet->lire); + $newmenu->add("/projet/list.php?leftmenu=projects&mode=mine&search_status=1", $langs->trans("List"), 1, $user->rights->projet->lire); // All project i have permission on $newmenu->add("/projet/index.php?leftmenu=projects", $langs->trans("Projects"), 0, $user->rights->projet->lire && $user->rights->projet->lire, '', $mainmenu, 'projects'); $newmenu->add("/projet/card.php?leftmenu=projects&action=create", $langs->trans("NewProject"), 1, $user->rights->projet->creer && $user->rights->projet->creer); - $newmenu->add("/projet/list.php?leftmenu=projects", $langs->trans("List"), 1, $user->rights->projet->lire && $user->rights->projet->lire); + $newmenu->add("/projet/list.php?leftmenu=projects&search_status=1", $langs->trans("List"), 1, $user->rights->projet->lire && $user->rights->projet->lire); $newmenu->add("/projet/stats/index.php?leftmenu=projects", $langs->trans("Statistics"), 1, $user->rights->projet->lire && $user->rights->projet->lire); if (empty($conf->global->PROJECT_HIDE_TASKS)) diff --git a/htdocs/core/modules/DolibarrModules.class.php b/htdocs/core/modules/DolibarrModules.class.php index de2870d7a9f..d61296f0cc1 100644 --- a/htdocs/core/modules/DolibarrModules.class.php +++ b/htdocs/core/modules/DolibarrModules.class.php @@ -32,7 +32,7 @@ * * Parent class for module descriptor class files */ -abstract class DolibarrModules +class DolibarrModules // Can not be abstract, because we need to instantiant it into unActivateModule to be able to disable a module whose files were removed. { /** * @var DoliDb Database handler @@ -194,16 +194,21 @@ abstract class DolibarrModules */ public $core_enabled; + /** * Constructor. Define names, constants, directories, boxes, permissions * * @param DoliDB $db Database handler */ - //public function __construct($db); // We should but can't set this as abstract because this will make dolibarr hang // after migration due to old module not implementing. We must wait PHP is able to make // a try catch on Fatal error to manage this correctly. - + function __construct($db) + { + $this->db=$db; + } + + /** * Enables a module. * Inserts all informations into database diff --git a/htdocs/core/modules/cheque/pdf/modules_chequereceipts.php b/htdocs/core/modules/cheque/pdf/modules_chequereceipts.php index 11ff9b509ad..e4d68c525fa 100644 --- a/htdocs/core/modules/cheque/pdf/modules_chequereceipts.php +++ b/htdocs/core/modules/cheque/pdf/modules_chequereceipts.php @@ -71,7 +71,7 @@ abstract class ModeleChequeReceipts extends CommonDocGenerator * @param string $modele Force le modele a utiliser ('' to not force) * @param Translate $outputlangs Object lang a utiliser pour traduction * @return int <0 if KO, >0 if OK - * TODO + * TODO Use commonDocGenerator */ function chequereceipt_pdf_create($db, $id, $message, $modele, $outputlangs) { @@ -103,7 +103,6 @@ function chequereceipt_pdf_create($db, $id, $message, $modele, $outputlangs) require_once $dir.$file; $obj = new $classname($db); - $obj->message = $message; // We save charset_output to restore it because write_file can change it if needed for // output format that does not support UTF8. diff --git a/htdocs/core/modules/cheque/pdf/pdf_blochet.class.php b/htdocs/core/modules/cheque/pdf/pdf_blochet.class.php index d8a4823c785..a7baec4364f 100644 --- a/htdocs/core/modules/cheque/pdf/pdf_blochet.class.php +++ b/htdocs/core/modules/cheque/pdf/pdf_blochet.class.php @@ -1,6 +1,6 @@ - * Copyright (C) 2009 Laurent Destailleur +/* Copyright (C) 2006 Rodolphe Quiedeville + * Copyright (C) 2009-2015 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 @@ -76,14 +76,15 @@ class BordereauChequeBlochet extends ModeleChequeReceipts } /** - * Fonction generant le rapport sur le disque + * Fonction to generate document on disk * - * @param string $_dir Directory - * @param string $number Number - * @param Translate $outputlangs Lang output object - * @return int 1=ok, 0=ko + * @param RemiseCheque $object Object RemiseCheque + * @param string $_dir Directory + * @param string $number Number + * @param Translate $outputlangs Lang output object + * @return int 1=ok, 0=ko */ - function write_file($_dir, $number, $outputlangs) + function write_file($object, $_dir, $number, $outputlangs) { global $user,$conf,$langs,$hookmanager; @@ -98,7 +99,7 @@ class BordereauChequeBlochet extends ModeleChequeReceipts $outputlangs->load("products"); $outputlangs->load("compta"); - $dir = $_dir . "/".get_exdir($number,2,1,0,null,'cheque').$number; + $dir = $_dir . "/".get_exdir($number,0,1,0,$object,'cheque').$number; if (! is_dir($dir)) { diff --git a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php index 20a80cb8be1..cc1e6aeedca 100644 --- a/htdocs/core/modules/commande/doc/pdf_einstein.modules.php +++ b/htdocs/core/modules/commande/doc/pdf_einstein.modules.php @@ -1325,9 +1325,11 @@ class pdf_einstein extends ModelePDFCommandes $pdf->SetFont('','B', $default_font_size); $pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, 'L'); + $posy = $pdf->getY(); + // Show recipient information $pdf->SetFont('','', $default_font_size - 1); - $pdf->SetXY($posx+2,$posy+4+(dol_nboflines_bis($carac_client_name,50)*4)); + $pdf->SetXY($posx+2,$posy); $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); } diff --git a/htdocs/core/modules/commande/doc/pdf_proforma.modules.php b/htdocs/core/modules/commande/doc/pdf_proforma.modules.php index 5afc0fe5c46..603f151fbfd 100644 --- a/htdocs/core/modules/commande/doc/pdf_proforma.modules.php +++ b/htdocs/core/modules/commande/doc/pdf_proforma.modules.php @@ -1217,9 +1217,11 @@ class pdf_proforma extends ModelePDFCommandes $pdf->SetFont('','B', $default_font_size); $pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, 'L'); + $posy = $pdf->getY(); + // Show recipient information $pdf->SetFont('','', $default_font_size - 1); - $pdf->SetXY($posx+2,$posy+4+(dol_nboflines_bis($carac_client_name,50)*4)); + $pdf->SetXY($posx+2,$posy); $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); } diff --git a/htdocs/core/modules/contract/doc/pdf_strato.modules.php b/htdocs/core/modules/contract/doc/pdf_strato.modules.php index e7d6d15b9ea..21944afad4f 100644 --- a/htdocs/core/modules/contract/doc/pdf_strato.modules.php +++ b/htdocs/core/modules/contract/doc/pdf_strato.modules.php @@ -269,18 +269,32 @@ class pdf_strato extends ModelePDFContract // Description of product line - if ($objectligne->datei) { - $datei = dol_print_date($objectligne->datei,'dayhour',false,$outputlangs,true); + if ($objectligne->date_ouverture_prevue) { + $datei = dol_print_date($objectligne->date_ouverture_prevue,'day',false,$outputlangs,true); } else { $datei = $langs->trans("Unknown"); } - if ($objectligne->duration) { - $durationi = convertSecondToTime($objectligne->duration); + if ($objectligne->date_fin_validite) { + $durationi = convertSecondToTime($objectligne->date_fin_validite - $objectligne->date_ouverture_prevue, 'allwithouthour'); + $datee = dol_print_date($objectligne->date_fin_validite,'day',false,$outputlangs,true); } else { $durationi = $langs->trans("Unknown"); + $datee = $langs->trans("Unknown"); } + if ($objectligne->date_ouverture) { + $daters = dol_print_date($objectligne->date_ouverture,'day',false,$outputlangs,true); + } else { + $daters = $langs->trans("Unknown"); + } + + if ($objectligne->date_cloture) { + $datere = dol_print_date($objectligne->date_cloture,'day',false,$outputlangs,true); + } else { + $datere = $langs->trans("Unknown"); + } + $txtpredefinedservice=''; $txtpredefinedservice = $objectligne->product_ref; if ($objectligne->product_label) @@ -289,7 +303,10 @@ class pdf_strato extends ModelePDFContract $txtpredefinedservice .= $objectligne->product_label; } - $txt=''.dol_htmlentitiesbr($outputlangs->transnoentities("Date")." : ".$datei." - ".$outputlangs->transnoentities("Duration")." : ".$durationi,1,$outputlangs->charset_output).''; + $txt=''.dol_htmlentitiesbr($outputlangs->transnoentities("DateStartPlannedShort")." : ".$datei." - ".$outputlangs->transnoentities("DateEndPlanned")." : ".$datee,1,$outputlangs->charset_output).''; + $txt.='
'; + $txt.=''.dol_htmlentitiesbr($outputlangs->transnoentities("DateStartRealShort")." : ".$daters,1,$outputlangs->charset_output); + if ($objectligne->date_cloture) $txt.=dol_htmlentitiesbr(" - ".$outputlangs->transnoentities("DateEndRealShort")." : ".$datere,1,$outputlangs->charset_output).''; $desc=dol_htmlentitiesbr($objectligne->desc,1); $pdf->writeHTMLCell(0, 0, $curX, $curY, dol_concatdesc($txt,dol_concatdesc($txtpredefinedservice,$desc)), 0, 1, 0); @@ -630,9 +647,11 @@ class pdf_strato extends ModelePDFContract $pdf->SetFont('','B', $default_font_size); $pdf->MultiCell($widthrecbox, 4, $this->recipient->name, 0, 'L'); + $posy = $pdf->getY(); + // Show recipient information $pdf->SetFont('','', $default_font_size - 1); - $pdf->SetXY($posx+2,$posy+4+(dol_nboflines_bis($this->recipient->name,50)*4)); + $pdf->SetXY($posx+2,$posy); $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); } } diff --git a/htdocs/core/modules/dons/html_cerfafr.modules.php b/htdocs/core/modules/dons/html_cerfafr.modules.php index 1b3e9822106..ee8951864c0 100644 --- a/htdocs/core/modules/dons/html_cerfafr.modules.php +++ b/htdocs/core/modules/dons/html_cerfafr.modules.php @@ -105,7 +105,7 @@ class html_cerfafr extends ModeleDon else { $donref = dol_sanitizeFileName($don->ref); - $dir = $conf->don->dir_output . "/" . get_exdir($donref,2,0,1,$don,'donation') . "/" . dol_sanitizeFileName($don->ref); + $dir = $conf->don->dir_output . "/" . $donref; $file = $dir . "/" . $donref . ".html"; } diff --git a/htdocs/core/modules/expedition/doc/pdf_merou.modules.php b/htdocs/core/modules/expedition/doc/pdf_merou.modules.php index 3f4315f640c..107dbb783b9 100644 --- a/htdocs/core/modules/expedition/doc/pdf_merou.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_merou.modules.php @@ -650,9 +650,11 @@ class pdf_merou extends ModelePdfExpedition $pdf->SetXY($blDestX,$Yoff); $pdf->MultiCell($blW,3, $carac_client_name, 0, 'L'); + $posy = $pdf->getY(); + // Show recipient information - $pdf->SetFont('','', $default_font_size - 3); - $pdf->SetXY($blDestX,$Yoff+(dol_nboflines_bis($carac_client_name,50)*4)); - $pdf->MultiCell($blW,2, $carac_client, 0, 'L'); + $pdf->SetFont('','', $default_font_size - 1); + $pdf->SetXY($posx+2,$posy); + $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); } } diff --git a/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php index 5123f713a6e..e90e11a952d 100644 --- a/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php +++ b/htdocs/core/modules/expedition/doc/pdf_rouget.modules.php @@ -694,9 +694,11 @@ class pdf_rouget extends ModelePdfExpedition $pdf->SetFont('','B', $default_font_size); $pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, 'L'); + $posy = $pdf->getY(); + // Show recipient information $pdf->SetFont('','', $default_font_size - 1); - $pdf->SetXY($posx+2,$posy+4+(dol_nboflines_bis($carac_client_name,50)*4)); + $pdf->SetXY($posx+2,$posy); $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); } diff --git a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php index a38d64ba826..48be2c907c8 100644 --- a/htdocs/core/modules/facture/doc/pdf_crabe.modules.php +++ b/htdocs/core/modules/facture/doc/pdf_crabe.modules.php @@ -958,9 +958,9 @@ class pdf_crabe extends ModelePDFFactures // If payment mode not forced or forced to VIR, show payment with BAN if (empty($object->mode_reglement_code) || $object->mode_reglement_code == 'VIR') { - if (! empty($object->fk_bank) || ! empty($conf->global->FACTURE_RIB_NUMBER)) + if (! empty($object->fk_account) || ! empty($conf->global->FACTURE_RIB_NUMBER)) { - $bankid=(empty($object->fk_bank)?$conf->global->FACTURE_RIB_NUMBER:$object->fk_bank); + $bankid=(empty($object->fk_account)?$conf->global->FACTURE_RIB_NUMBER:$object->fk_account); $account = new Account($this->db); $account->fetch($bankid); @@ -1611,11 +1611,13 @@ class pdf_crabe extends ModelePDFFactures // Show recipient name $pdf->SetXY($posx+2,$posy+3); $pdf->SetFont('','B', $default_font_size); - $pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, 'L'); + $pdf->MultiCell($widthrecbox, 2, $carac_client_name, 0, 'L'); + + $posy = $pdf->getY(); // Show recipient information $pdf->SetFont('','', $default_font_size - 1); - $pdf->SetXY($posx+2,$posy+4+(dol_nboflines_bis($carac_client_name,50)*4)); + $pdf->SetXY($posx+2,$posy); $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); } diff --git a/htdocs/core/modules/facture/modules_facture.php b/htdocs/core/modules/facture/modules_facture.php index afae663b02b..23d55d0aa96 100644 --- a/htdocs/core/modules/facture/modules_facture.php +++ b/htdocs/core/modules/facture/modules_facture.php @@ -155,8 +155,8 @@ abstract class ModeleNumRefFactures * @param int $hidedesc Hide description * @param int $hideref Hide ref * @return int <0 if KO, >0 if OK - * @deprecated Use the new function generateDocument of Facture class - * @see Facture::generateDocument() + * @deprecated Use the new function generateDocument of Facture class + * @see Facture::generateDocument() */ function facture_pdf_create(DoliDB $db, Facture $object, $modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0) { diff --git a/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php b/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php index 116cab79185..98485be3207 100644 --- a/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php +++ b/htdocs/core/modules/fichinter/doc/pdf_soleil.modules.php @@ -641,9 +641,11 @@ class pdf_soleil extends ModelePDFFicheinter $pdf->SetFont('','B', $default_font_size); $pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, 'L'); + $posy = $pdf->getY(); + // Show recipient information $pdf->SetFont('','', $default_font_size - 1); - $pdf->SetXY($posx+2,$posy+4+(dol_nboflines_bis($carac_client_name,50)*4)); + $pdf->SetXY($posx+2,$posy); $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); } } diff --git a/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php b/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php index b6f674e424d..747401be88c 100644 --- a/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php +++ b/htdocs/core/modules/livraison/doc/pdf_typhon.modules.php @@ -875,9 +875,11 @@ class pdf_typhon extends ModelePDFDeliveryOrder $pdf->SetFont('','B', $default_font_size); $pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, 'L'); + $posy = $pdf->getY(); + // Show recipient information $pdf->SetFont('','', $default_font_size - 1); - $pdf->SetXY($posx+2,$posy+4+(dol_nboflines_bis($carac_client_name,50)*4)); + $pdf->SetXY($posx+2,$posy); $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); } diff --git a/htdocs/core/modules/modAccounting.class.php b/htdocs/core/modules/modAccounting.class.php index d4db6b2e798..0fd9c265bfb 100644 --- a/htdocs/core/modules/modAccounting.class.php +++ b/htdocs/core/modules/modAccounting.class.php @@ -196,6 +196,11 @@ class modAccounting extends DolibarrModules "chaine", "ER" ); + $this->const[23] = array( + "ACCOUNTING_EXPORT_FORMAT", + "chaine", + "csv" + ); // Tabs $this->tabs = array(); diff --git a/htdocs/core/modules/modAdherent.class.php b/htdocs/core/modules/modAdherent.class.php index 1090e8b6939..63fc303162f 100644 --- a/htdocs/core/modules/modAdherent.class.php +++ b/htdocs/core/modules/modAdherent.class.php @@ -31,7 +31,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Adherent + * Class to describe and enable module Adherent */ class modAdherent extends DolibarrModules { @@ -64,33 +64,136 @@ class modAdherent extends DolibarrModules //------------- $this->config_page_url = array("adherent.php@adherents"); - // Dependances + // Dependencies //------------ $this->depends = array(); $this->requiredby = array('modMailmanSpip'); $this->langfiles = array("members","companies"); - // Constantes + // Constants //----------- $this->const = array(); - $this->const[2] = array("MAIN_SEARCHFORM_ADHERENT","yesno","1","Show form for quick member search"); - $this->const[3] = array("ADHERENT_MAIL_RESIL","texte","Votre adhésion vient d'être résiliée.\r\nNous espérons vous revoir très bientôt","Mail de résiliation"); - $this->const[4] = array("ADHERENT_MAIL_VALID","texte","Votre adhésion vient d'être validée. \r\nVoici le rappel de vos coordonnées (toute information erronée entrainera la non validation de votre inscription) :\r\n\r\n%INFOS%\r\n\r\n","Mail de validation"); - $this->const[5] = array("ADHERENT_MAIL_VALID_SUBJECT","chaine","Votre adhésion a été validée","Sujet du mail de validation"); - $this->const[6] = array("ADHERENT_MAIL_RESIL_SUBJECT","chaine","Résiliation de votre adhésion","Sujet du mail de résiliation"); - $this->const[21] = array("ADHERENT_MAIL_FROM","chaine","","From des mails"); - $this->const[22] = array("ADHERENT_MAIL_COTIS","texte","Bonjour %FIRSTNAME%,\r\nCet email confirme que votre cotisation a été reçue\r\net enregistrée","Mail de validation de cotisation"); - $this->const[23] = array("ADHERENT_MAIL_COTIS_SUBJECT","chaine","Reçu de votre cotisation","Sujet du mail de validation de cotisation"); - $this->const[25] = array("ADHERENT_CARD_HEADER_TEXT","chaine","%YEAR%","Texte imprimé sur le haut de la carte adhérent"); - $this->const[26] = array("ADHERENT_CARD_FOOTER_TEXT","chaine","%COMPANY%","Texte imprimé sur le bas de la carte adhérent"); - $this->const[27] = array("ADHERENT_CARD_TEXT","texte","%FULLNAME%\r\nID: %ID%\r\n%EMAIL%\r\n%ADDRESS%\r\n%ZIP% %TOWN%\r\n%COUNTRY%","Text to print on member cards"); - $this->const[28] = array("ADHERENT_MAILMAN_ADMINPW","chaine","","Mot de passe Admin des liste mailman"); - $this->const[31] = array("ADHERENT_BANK_USE_AUTO","yesno","","Insertion automatique des cotisations dans le compte banquaire"); - $this->const[32] = array("ADHERENT_BANK_ACCOUNT","chaine","","ID du Compte banquaire utilise"); - $this->const[33] = array("ADHERENT_BANK_CATEGORIE","chaine","","ID de la catégorie banquaire des cotisations"); - $this->const[34] = array("ADHERENT_ETIQUETTE_TYPE","chaine","L7163","Type of address sheets"); - $this->const[35] = array("ADHERENT_ETIQUETTE_TEXT",'texte',"%FULLNAME%\n%ADDRESS%\n%ZIP% %TOWN%\n%COUNTRY%","Text to print on member address sheets"); - + $r=0; + + $this->const[$r][0] = "MAIN_SEARCHFORM_ADHERENT"; + $this->const[$r][1] = "yesno"; + $this->const[$r][2] = "1"; + $this->const[$r][3] = "Show form for quick member search"; + $this->const[$r][4] = 0; + $r++; + + $this->const[$r][0] = "ADHERENT_MAIL_RESIL"; + $this->const[$r][1] = "texte"; + $this->const[$r][2] = "Votre adhésion vient d'être résiliée.\r\nNous espérons vous revoir très bientôt"; + $this->const[$r][3] = "Mail de résiliation"; + $this->const[$r][4] = 0; + $r++; + + $this->const[$r][0] = "ADHERENT_MAIL_VALID"; + $this->const[$r][1] = "texte"; + $this->const[$r][2] = "Votre adhésion vient d'être validée. \r\nVoici le rappel de vos coordonnées (toute information erronée entrainera la non validation de votre inscription) :\r\n\r\n%INFOS%\r\n\r\n"; + $this->const[$r][3] = "Mail de validation"; + $this->const[$r][4] = 0; + $r++; + + $this->const[$r][0] = "ADHERENT_MAIL_VALID_SUBJECT"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = "Votre adhésion a été validée"; + $this->const[$r][3] = "Sujet du mail de validation"; + $this->const[$r][4] = 0; + $r++; + + $this->const[$r][0] = "ADHERENT_MAIL_RESIL_SUBJECT"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = "Résiliation de votre adhésion"; + $this->const[$r][3] = "Sujet du mail de résiliation"; + $this->const[$r][4] = 0; + $r++; + + $this->const[$r][0] = "ADHERENT_MAIL_FROM"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = ""; + $this->const[$r][3] = "From des mails"; + $this->const[$r][4] = 0; + $r++; + + $this->const[$r][0] = "ADHERENT_MAIL_COTIS"; + $this->const[$r][1] = "texte"; + $this->const[$r][2] = "Bonjour %FIRSTNAME%,\r\nCet email confirme que votre cotisation a été reçue\r\net enregistrée"; + $this->const[$r][3] = "Mail de validation de cotisation"; + $this->const[$r][4] = 0; + $r++; + + $this->const[$r][0] = "ADHERENT_MAIL_COTIS_SUBJECT"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = "Reçu de votre cotisation"; + $this->const[$r][3] = "Sujet du mail de validation de cotisation"; + $this->const[$r][4] = 0; + $r++; + + $this->const[$r][0] = "ADHERENT_CARD_HEADER_TEXT"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = "%YEAR%"; + $this->const[$r][3] = "Texte imprimé sur le haut de la carte adhérent"; + $this->const[$r][4] = 0; + $r++; + + $this->const[$r][0] = "ADHERENT_CARD_FOOTER_TEXT"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = "%COMPANY%"; + $this->const[$r][3] = "Texte imprimé sur le bas de la carte adhérent"; + $this->const[$r][4] = 0; + $r++; + + $this->const[$r][0] = "ADHERENT_CARD_TEXT"; + $this->const[$r][1] = "texte"; + $this->const[$r][2] = "%FULLNAME%\r\nID: %ID%\r\n%EMAIL%\r\n%ADDRESS%\r\n%ZIP% %TOWN%\r\n%COUNTRY%"; + $this->const[$r][3] = "Text to print on member cards"; + $this->const[$r][4] = 0; + $r++; + + $this->const[$r][0] = "ADHERENT_MAILMAN_ADMINPW"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = ""; + $this->const[$r][3] = "Mot de passe Admin des liste mailman"; + $this->const[$r][4] = 0; + $r++; + + $this->const[$r][0] = "ADHERENT_BANK_USE_AUTO"; + $this->const[$r][1] = "yesno"; + $this->const[$r][2] = ""; + $this->const[$r][3] = "Insertion automatique des cotisations dans le compte banquaire"; + $this->const[$r][4] = 0; + $r++; + + $this->const[$r][0] = "ADHERENT_BANK_ACCOUNT"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = ""; + $this->const[$r][3] = "ID du Compte banquaire utilise"; + $this->const[$r][4] = 0; + $r++; + + $this->const[$r][0] = "ADHERENT_BANK_CATEGORIE"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = ""; + $this->const[$r][3] = "ID de la catégorie banquaire des cotisations"; + $this->const[$r][4] = 0; + $r++; + + $this->const[$r][0] = "ADHERENT_ETIQUETTE_TYPE"; + $this->const[$r][1] = "chaine"; + $this->const[$r][2] = "L7163"; + $this->const[$r][3] = "Type of address sheets"; + $this->const[$r][4] = 0; + $r++; + + $this->const[$r][0] = "ADHERENT_ETIQUETTE_TEXT"; + $this->const[$r][1] = "texte"; + $this->const[$r][2] = "%FULLNAME%\n%ADDRESS%\n%ZIP% %TOWN%\n%COUNTRY%"; + $this->const[$r][3] = "Text to print on member address sheets"; + $this->const[$r][4] = 0; + $r++; + // Boxes //------- $this->boxes = array(0=>array('file'=>'box_members.php','enabledbydefaulton'=>'Home')); diff --git a/htdocs/core/modules/modAgenda.class.php b/htdocs/core/modules/modAgenda.class.php index 819ee0c1206..31ca8dcd048 100644 --- a/htdocs/core/modules/modAgenda.class.php +++ b/htdocs/core/modules/modAgenda.class.php @@ -72,7 +72,7 @@ class modAgenda extends DolibarrModules $this->requiredby = array(); $this->langfiles = array("companies"); - // Constantes + // Constants //----------- $this->const = array(); $this->const[15] = array("MAIN_AGENDA_ACTIONAUTO_COMPANY_SENTBYMAIL","chaine","1"); diff --git a/htdocs/core/modules/modAskPriceSupplier.class.php b/htdocs/core/modules/modAskPriceSupplier.class.php index 23d4fb20f42..7c536e33a6f 100644 --- a/htdocs/core/modules/modAskPriceSupplier.class.php +++ b/htdocs/core/modules/modAskPriceSupplier.class.php @@ -31,7 +31,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module AskPriceSupllier + * Class to describe and enable module AskPriceSupllier */ class modAskPriceSupplier extends DolibarrModules { diff --git a/htdocs/core/modules/modBanque.class.php b/htdocs/core/modules/modBanque.class.php index 9222a38ff26..0441cc257b3 100644 --- a/htdocs/core/modules/modBanque.class.php +++ b/htdocs/core/modules/modBanque.class.php @@ -31,7 +31,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Banque + * Class to describe and enable module Banque */ class modBanque extends DolibarrModules { @@ -76,7 +76,7 @@ class modBanque extends DolibarrModules // Constants $this->const = array(); - // Boites + // Boxes $this->boxes = array(0=>array('file'=>'box_comptes.php','enabledbydefaulton'=>'Home')); // Permissions diff --git a/htdocs/core/modules/modBarcode.class.php b/htdocs/core/modules/modBarcode.class.php index 07db8b55832..f28e6307e91 100644 --- a/htdocs/core/modules/modBarcode.class.php +++ b/htdocs/core/modules/modBarcode.class.php @@ -56,7 +56,7 @@ class modBarcode extends DolibarrModules // Data directories to create when module is enabled $this->dirs = array("/barcode/temp"); - // Dependances + // Dependencies $this->depends = array(); // May be used for product or service or third party module $this->requiredby = array(); diff --git a/htdocs/core/modules/modBookmark.class.php b/htdocs/core/modules/modBookmark.class.php index a6585e14d54..5614ceb53ab 100644 --- a/htdocs/core/modules/modBookmark.class.php +++ b/htdocs/core/modules/modBookmark.class.php @@ -28,7 +28,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Bookmark + * Class to describe and enable module Bookmark */ class modBookmark extends DolibarrModules { @@ -66,10 +66,10 @@ class modBookmark extends DolibarrModules // Config pages $this->config_page_url = array('bookmark.php@bookmarks'); - // Constantes + // Constants $this->const = array(); - // Boites + // Boxes $this->boxes = array(0=>array('file'=>'box_bookmarks.php','enabledbydefaulton'=>'Home')); // Permissions diff --git a/htdocs/core/modules/modCashDesk.class.php b/htdocs/core/modules/modCashDesk.class.php index 9b256162597..a76531cd719 100644 --- a/htdocs/core/modules/modCashDesk.class.php +++ b/htdocs/core/modules/modCashDesk.class.php @@ -70,7 +70,7 @@ class modCashDesk extends DolibarrModules $this->need_dolibarr_version = array(2,4); // Minimum version of Dolibarr required by module $this->langfiles = array("cashdesk"); - // Constantes + // Constants $this->const = array(); // Boxes diff --git a/htdocs/core/modules/modCategorie.class.php b/htdocs/core/modules/modCategorie.class.php index e9efbcbe732..5e44e6891d5 100644 --- a/htdocs/core/modules/modCategorie.class.php +++ b/htdocs/core/modules/modCategorie.class.php @@ -28,7 +28,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Categorie + * Class to describe and enable module Categorie */ class modCategorie extends DolibarrModules { @@ -66,7 +66,7 @@ class modCategorie extends DolibarrModules $this->config_page_url = array('categorie.php@categories'); $this->langfiles = array("products","companies","categories"); - // Constantes + // Constants $this->const = array(); $r=0; $this->const[$r][0] = "CATEGORIE_RECURSIV_ADD"; diff --git a/htdocs/core/modules/modClickToDial.class.php b/htdocs/core/modules/modClickToDial.class.php index 518cafa35a4..c0983cc1a8b 100644 --- a/htdocs/core/modules/modClickToDial.class.php +++ b/htdocs/core/modules/modClickToDial.class.php @@ -28,7 +28,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module de Click to Dial + * Class to describe and enable module Click to Dial */ class modClickToDial extends DolibarrModules { diff --git a/htdocs/core/modules/modCommande.class.php b/htdocs/core/modules/modCommande.class.php index 4289bd54932..411463e4137 100644 --- a/htdocs/core/modules/modCommande.class.php +++ b/htdocs/core/modules/modCommande.class.php @@ -73,7 +73,7 @@ class modCommande extends DolibarrModules $this->conflictwith = array(); $this->langfiles = array('orders', 'bills', 'companies','products', 'deliveries'); - // Constantes + // Constants $this->const = array(); $r=0; diff --git a/htdocs/core/modules/modComptabilite.class.php b/htdocs/core/modules/modComptabilite.class.php index e23a04ce548..26aea67d1d0 100644 --- a/htdocs/core/modules/modComptabilite.class.php +++ b/htdocs/core/modules/modComptabilite.class.php @@ -30,7 +30,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Comptabilite + * Class to describe and enable module Comptabilite */ class modComptabilite extends DolibarrModules { @@ -62,13 +62,13 @@ class modComptabilite extends DolibarrModules // Config pages $this->config_page_url = array("compta.php"); - // Dependances + // Dependencies $this->depends = array("modFacture","modBanque"); $this->requiredby = array(); $this->conflictwith = array("modAccounting"); $this->langfiles = array("compta"); - // Constantes + // Constants $this->const = array(); // Data directories to create when module is enabled @@ -78,7 +78,7 @@ class modComptabilite extends DolibarrModules "/comptabilite/bordereau" ); - // Boites + // Boxes $this->boxes = array(); // Permissions diff --git a/htdocs/core/modules/modContrat.class.php b/htdocs/core/modules/modContrat.class.php index c1bcc9fd914..d298c5aa182 100644 --- a/htdocs/core/modules/modContrat.class.php +++ b/htdocs/core/modules/modContrat.class.php @@ -29,7 +29,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Contrat + * Class to describe and enable module Contrat */ class modContrat extends DolibarrModules { @@ -41,7 +41,7 @@ class modContrat extends DolibarrModules */ function __construct($db) { - global $conf; + global $conf, $langs; $this->db = $db; $this->numero = 54; @@ -61,14 +61,14 @@ class modContrat extends DolibarrModules // Data directories to create when module is enabled $this->dirs = array("/contract/temp"); - // Dependances + // Dependencies $this->depends = array("modSociete"); $this->requiredby = array(); // Config pages $this->config_page_url = array("contract.php"); - // Constantes + // Constants $this->const = array(); $this->const[0][0] = "CONTRACT_ADDON"; $this->const[0][1] = "chaine"; @@ -132,6 +132,8 @@ class modContrat extends DolibarrModules // Exports //-------- + $langs->load("contracts"); + $r=1; $this->export_code[$r]=$this->rights_class.'_'.$r; @@ -141,18 +143,18 @@ class modContrat extends DolibarrModules $this->export_fields_array[$r]=array('s.rowid'=>"IdCompany",'s.nom'=>'CompanyName','s.address'=>'Address','s.zip'=>'Zip','s.town'=>'Town','c.code'=>'CountryCode', 's.phone'=>'Phone','s.siren'=>'ProfId1','s.siret'=>'ProfId2','s.ape'=>'ProfId3','s.idprof4'=>'ProfId4','s.code_compta'=>'CustomerAccountancyCode', 's.code_compta_fournisseur'=>'SupplierAccountancyCode','s.tva_intra'=>'VATIntra', - 'co.rowid'=>"contractId",'co.ref'=>"contactRef",'co.datec'=>"contractDateCreation",'co.date_contrat'=>"DateContract",'co.mise_en_service'=>"DateMiseService", - 'co.fin_validite'=>"EndValidity",'co.date_cloture'=>"Cloture",'co.note_private'=>"NotePrivate",'co.note_public'=>"NotePublic", + 'co.rowid'=>"Id",'co.ref'=>"Ref",'co.datec'=>"DateCreation",'co.date_contrat'=>"DateContract",'co.mise_en_service'=>"ContractStartDate", + 'co.fin_validite'=>"ContractEndDate",'co.date_cloture'=>"Closing",'co.note_private'=>"NotePrivate",'co.note_public'=>"NotePublic", 'cod.rowid'=>'LineId','cod.label'=>"LineLabel",'cod.description'=>"LineDescription",'cod.price_ht'=>"LineUnitPrice",'cod.tva_tx'=>"LineVATRate", 'cod.qty'=>"LineQty",'cod.total_ht'=>"LineTotalHT",'cod.total_tva'=>"LineTotalVAT",'cod.total_ttc'=>"LineTotalTTC", - 'cod.date_ouverture'=>"DateStart",'cod.date_ouverture_prevue'=>"DateStartPrevis",'cod.date_fin_validite'=>"EndValidity",'cod.date_cloture'=>"DateEnd", + 'cod.date_ouverture'=>"DateStart",'cod.date_ouverture_prevue'=>"DateStartPlanned",'cod.date_fin_validite'=>"DateEndPlanned",'cod.date_cloture'=>"DateEnd", 'p.rowid'=>'ProductId','p.ref'=>'ProductRef','p.label'=>'ProductLabel'); $this->export_entities_array[$r]=array('s.rowid'=>"company",'s.nom'=>'company','s.address'=>'company','s.zip'=>'company', 's.town'=>'company','c.code'=>'company','s.phone'=>'company','s.siren'=>'company','s.siret'=>'company','s.ape'=>'company', 's.idprof4'=>'company','s.code_compta'=>'company','s.code_compta_fournisseur'=>'company','s.tva_intra'=>'company', - 'co.rowid'=>"Contract",'co.ref'=>"Contract",'co.datec'=>"Contract",'co.date_contrat'=>"Contract",'co.mise_en_service'=>"Contract", - 'co.fin_validite'=>"Contract",'co.date_cloture'=>"Contract",'co.note_private'=>"Contract",'co.note_public'=>"Contract", + 'co.rowid'=>"contract",'co.ref'=>"contract",'co.datec'=>"contract",'co.date_contrat'=>"contract",'co.mise_en_service'=>"contract", + 'co.fin_validite'=>"contract",'co.date_cloture'=>"contract",'co.note_private'=>"contract",'co.note_public'=>"contract", 'cod.rowid'=>'contract_line','cod.label'=>"contract_line",'cod.description'=>"contract_line",'cod.price_ht'=>"contract_line",'cod.tva_tx'=>"contract_line", 'cod.qty'=>"contract_line",'cod.total_ht'=>"contract_line",'cod.total_tva'=>"contract_line",'cod.total_ttc'=>"contract_line", 'cod.date_ouverture'=>"contract_line",'cod.date_ouverture_prevue'=>"contract_line",'cod.date_fin_validite'=>"contract_line",'cod.date_cloture'=>"contract_line", diff --git a/htdocs/core/modules/modCron.class.php b/htdocs/core/modules/modCron.class.php index 90d17882672..86dbb021f26 100644 --- a/htdocs/core/modules/modCron.class.php +++ b/htdocs/core/modules/modCron.class.php @@ -73,7 +73,7 @@ class modCron extends DolibarrModules $this->conflictwith = array(); // List of modules id this module is in conflict with $this->langfiles = array("cron"); - // Constantes + // Constants //----------- $this->const = array( 0=>array( diff --git a/htdocs/core/modules/modDeplacement.class.php b/htdocs/core/modules/modDeplacement.class.php index 08f21ae6c63..e4db402e93e 100644 --- a/htdocs/core/modules/modDeplacement.class.php +++ b/htdocs/core/modules/modDeplacement.class.php @@ -27,7 +27,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Deplacement + * Class to describe and enable module Deplacement */ class modDeplacement extends DolibarrModules { diff --git a/htdocs/core/modules/modDocumentGeneration.class.php b/htdocs/core/modules/modDocumentGeneration.class.php index c312cc37b5a..e64115df9ac 100644 --- a/htdocs/core/modules/modDocumentGeneration.class.php +++ b/htdocs/core/modules/modDocumentGeneration.class.php @@ -29,7 +29,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Document + * Class to describe and enable module Document */ class modDocumentGeneration extends DolibarrModules { @@ -67,11 +67,11 @@ class modDocumentGeneration extends DolibarrModules $this->conflictwith = array(); $this->langfiles = array("orders","bills","companies","mails"); - // Constantes + // Constants $this->const = array(); - // Boites + // Boxes $this->boxes = array(); // Permissions diff --git a/htdocs/core/modules/modDynamicPrices.class.php b/htdocs/core/modules/modDynamicPrices.class.php index 78f56a76ab4..4e5cd3a3f62 100644 --- a/htdocs/core/modules/modDynamicPrices.class.php +++ b/htdocs/core/modules/modDynamicPrices.class.php @@ -66,7 +66,7 @@ class modDynamicPrices extends DolibarrModules $this->requiredby = array(); $this->langfiles = array("other"); - // Constantes + // Constants //----------- $this->const = array(); diff --git a/htdocs/core/modules/modExpedition.class.php b/htdocs/core/modules/modExpedition.class.php index 6e019849ae2..54ac91d00cd 100644 --- a/htdocs/core/modules/modExpedition.class.php +++ b/htdocs/core/modules/modExpedition.class.php @@ -31,7 +31,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Expedition + * Class to describe and enable module Expedition */ class modExpedition extends DolibarrModules { @@ -73,13 +73,13 @@ class modExpedition extends DolibarrModules // Config pages $this->config_page_url = array("confexped.php"); - // Dependances + // Dependencies $this->depends = array("modCommande"); $this->requiredby = array(); $this->conflictwith = array(); $this->langfiles = array('deliveries','sendings'); - // Constantes + // Constants $this->const = array(); $r=0; diff --git a/htdocs/core/modules/modExport.class.php b/htdocs/core/modules/modExport.class.php index 634306ea4db..d57657c3204 100644 --- a/htdocs/core/modules/modExport.class.php +++ b/htdocs/core/modules/modExport.class.php @@ -28,7 +28,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module export + * Class to describe and enable module export */ class modExport extends DolibarrModules { @@ -58,13 +58,13 @@ class modExport extends DolibarrModules // Config pages $this->config_page_url = array(); - // Dependances + // Dependencies $this->depends = array(); $this->requiredby = array(); $this->phpmin = array(4,2,0); $this->phpmax = array(); - // Constantes + // Constants $this->const = array(); // Boxes diff --git a/htdocs/core/modules/modExternalRss.class.php b/htdocs/core/modules/modExternalRss.class.php index 60ed479b34b..7ae60e5e9eb 100644 --- a/htdocs/core/modules/modExternalRss.class.php +++ b/htdocs/core/modules/modExternalRss.class.php @@ -28,7 +28,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module externalrss + * Class to describe and enable module externalrss */ class modExternalRss extends DolibarrModules { @@ -60,13 +60,13 @@ class modExternalRss extends DolibarrModules // Config pages $this->config_page_url = array("external_rss.php"); - // Dependances + // Dependencies $this->depends = array(); $this->requiredby = array(); $this->phpmin = array(4,2,0); $this->phpmax = array(); - // Constantes + // Constants $this->const = array(); // Boxes diff --git a/htdocs/core/modules/modFacture.class.php b/htdocs/core/modules/modFacture.class.php index 54363bc9d80..5a175e8569a 100644 --- a/htdocs/core/modules/modFacture.class.php +++ b/htdocs/core/modules/modFacture.class.php @@ -71,7 +71,7 @@ class modFacture extends DolibarrModules // Config pages $this->config_page_url = array("facture.php"); - // Constantes + // Constants $this->const = array(); $r=0; diff --git a/htdocs/core/modules/modFckeditor.class.php b/htdocs/core/modules/modFckeditor.class.php index 6a5932cca5a..8e9fe195e33 100644 --- a/htdocs/core/modules/modFckeditor.class.php +++ b/htdocs/core/modules/modFckeditor.class.php @@ -29,7 +29,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Fckeditor + * Class to describe and enable module Fckeditor */ class modFckeditor extends DolibarrModules @@ -61,12 +61,12 @@ class modFckeditor extends DolibarrModules // Config pages $this->config_page_url = array("fckeditor.php"); - // Dependances + // Dependencies $this->disabled = (in_array(constant('JS_CKEDITOR'),array('disabled','disabled/'))?1:0); // A condition to disable module (used for native debian packages) $this->depends = array(); $this->requiredby = array(); - // Constantes + // Constants $this->const = array(); $this->const[0] = array("FCKEDITOR_ENABLE_SOCIETE","yesno","1","WYSIWIG for description and note (except products/services)"); $this->const[1] = array("FCKEDITOR_ENABLE_PRODUCTDESC","yesno","1","WYSIWIG for products/services description and note"); @@ -75,7 +75,7 @@ class modFckeditor extends DolibarrModules $this->const[4] = array("FCKEDITOR_ENABLE_USERSIGN","yesno","1","WYSIWIG for user signature"); $this->const[5] = array("FCKEDITOR_ENABLE_MAIL","yesno","1","WYSIWIG for products details lines for all entities"); - // Boites + // Boxes $this->boxes = array(); // Permissions diff --git a/htdocs/core/modules/modFicheinter.class.php b/htdocs/core/modules/modFicheinter.class.php index 91a672fb669..4578a3e60a9 100644 --- a/htdocs/core/modules/modFicheinter.class.php +++ b/htdocs/core/modules/modFicheinter.class.php @@ -32,7 +32,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Ficheinter + * Class to describe and enable module Ficheinter */ class modFicheinter extends DolibarrModules { @@ -73,7 +73,7 @@ class modFicheinter extends DolibarrModules // Config pages $this->config_page_url = array("fichinter.php"); - // Constantes + // Constants $this->const = array(); $r=0; diff --git a/htdocs/core/modules/modFournisseur.class.php b/htdocs/core/modules/modFournisseur.class.php index 0db347f0df2..4f82710d3f5 100644 --- a/htdocs/core/modules/modFournisseur.class.php +++ b/htdocs/core/modules/modFournisseur.class.php @@ -3,7 +3,7 @@ * Copyright (C) 2004-2015 Laurent Destailleur * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2012 Juanjo Menent - * Copyright (C) 2013 Philippe Grand + * Copyright (C) 2013-2015 Philippe Grand * * 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 @@ -20,17 +20,17 @@ */ /** - * \defgroup fournisseur Module suppliers - * \brief Module pour gerer des societes et contacts de type fournisseurs + * \defgroup fournisseur suppliers Module + * \brief Module to manage companies and contacts of supplier type * \file htdocs/core/modules/modFournisseur.class.php * \ingroup fournisseur - * \brief Fichier de description et activation du module Fournisseur + * \brief Description and activation file for module Fournisseur */ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Fournisseur + * Description and activation class for module Fournisseur */ class modFournisseur extends DolibarrModules { @@ -67,7 +67,7 @@ class modFournisseur extends DolibarrModules "/fournisseur/facture/temp" ); - // Dependances + // Dependencies $this->depends = array("modSociete"); $this->requiredby = array(); $this->langfiles = array('bills', 'companies', 'suppliers', 'orders'); @@ -75,7 +75,7 @@ class modFournisseur extends DolibarrModules // Config pages $this->config_page_url = array("supplier_order.php"); - // Constantes + // Constants $this->const = array(); $r=0; diff --git a/htdocs/core/modules/modGeoIPMaxmind.class.php b/htdocs/core/modules/modGeoIPMaxmind.class.php index 164d89243b8..eeb1b482198 100644 --- a/htdocs/core/modules/modGeoIPMaxmind.class.php +++ b/htdocs/core/modules/modGeoIPMaxmind.class.php @@ -27,7 +27,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Import + * Class to describe and enable module Import */ class modGeoIPMaxmind extends DolibarrModules { @@ -66,7 +66,7 @@ class modGeoIPMaxmind extends DolibarrModules // Config pages $this->config_page_url = array("geoipmaxmind.php"); - // D�pendances + // Dependencies $this->depends = array(); $this->requiredby = array(); $this->phpmin = array(4,2,0); @@ -74,7 +74,7 @@ class modGeoIPMaxmind extends DolibarrModules $this->need_dolibarr_version = array(2,7,-1); // Minimum version of Dolibarr required by module $this->need_javascript_ajax = 1; - // Constantes + // Constants $this->const = array(); // Boxes diff --git a/htdocs/core/modules/modImport.class.php b/htdocs/core/modules/modImport.class.php index 5ac3b8928db..ebcd5363e21 100644 --- a/htdocs/core/modules/modImport.class.php +++ b/htdocs/core/modules/modImport.class.php @@ -28,7 +28,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Import + * Class to describe and enable module Import */ class modImport extends DolibarrModules { @@ -59,7 +59,7 @@ class modImport extends DolibarrModules // Config pages $this->config_page_url = array(); - // D�pendances + // Dependencies $this->depends = array(); $this->requiredby = array(); $this->phpmin = array(4,3,0); // Need auto_detect_line_endings php option to solve MAC pbs. @@ -67,7 +67,7 @@ class modImport extends DolibarrModules $this->need_dolibarr_version = array(2,7,-1); // Minimum version of Dolibarr required by module $this->need_javascript_ajax = 1; - // Constantes + // Constants $this->const = array(); // Boxes diff --git a/htdocs/core/modules/modLabel.class.php b/htdocs/core/modules/modLabel.class.php index 3292e2269fb..54f65a83591 100644 --- a/htdocs/core/modules/modLabel.class.php +++ b/htdocs/core/modules/modLabel.class.php @@ -28,7 +28,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Label + * Class to describe and enable module Label */ class modLabel extends DolibarrModules { diff --git a/htdocs/core/modules/modLdap.class.php b/htdocs/core/modules/modLdap.class.php index cb2ad24fef4..31f51d5d956 100644 --- a/htdocs/core/modules/modLdap.class.php +++ b/htdocs/core/modules/modLdap.class.php @@ -28,7 +28,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Ldap + * Class to describe and enable module Ldap */ class modLdap extends DolibarrModules { @@ -83,7 +83,7 @@ class modLdap extends DolibarrModules 13=>array('LDAP_FIELD_MOBILE','chaine','mobile','',0), ); - // Boites + // Boxes $this->boxes = array(); // Permissions diff --git a/htdocs/core/modules/modLoan.class.php b/htdocs/core/modules/modLoan.class.php index 96139ee3fec..19d44ca11cc 100644 --- a/htdocs/core/modules/modLoan.class.php +++ b/htdocs/core/modules/modLoan.class.php @@ -63,7 +63,7 @@ class modLoan extends DolibarrModules // Config pages $this->config_page_url = array('loan.php'); - // Dependances + // Dependencies $this->depends = array(); $this->requiredby = array(); $this->conflictwith = array(); diff --git a/htdocs/core/modules/modMailing.class.php b/htdocs/core/modules/modMailing.class.php index 9930168a218..00ece509285 100644 --- a/htdocs/core/modules/modMailing.class.php +++ b/htdocs/core/modules/modMailing.class.php @@ -29,7 +29,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Mailing + * Class to describe and enable module Mailing */ class modMailing extends DolibarrModules { @@ -56,7 +56,7 @@ class modMailing extends DolibarrModules // Data directories to create when module is enabled $this->dirs = array("/mailing/temp"); - // Dependances + // Dependencies $this->depends = array(); $this->requiredby = array(); $this->langfiles = array("mails"); @@ -64,10 +64,10 @@ class modMailing extends DolibarrModules // Config pages $this->config_page_url = array("mailing.php"); - // Constantes + // Constants $this->const = array(); - // Boites + // Boxes $this->boxes = array(); // Permissions diff --git a/htdocs/core/modules/modMailmanSpip.class.php b/htdocs/core/modules/modMailmanSpip.class.php index 4d96b4e8cd1..2ebff38ef08 100644 --- a/htdocs/core/modules/modMailmanSpip.class.php +++ b/htdocs/core/modules/modMailmanSpip.class.php @@ -28,7 +28,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module de Click to Dial + * Class to describe and enable module Click to Dial */ class modMailmanSpip extends DolibarrModules { diff --git a/htdocs/core/modules/modNotification.class.php b/htdocs/core/modules/modNotification.class.php index 74d7e6dfbcc..c29c77b8f24 100644 --- a/htdocs/core/modules/modNotification.class.php +++ b/htdocs/core/modules/modNotification.class.php @@ -26,7 +26,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Mailing + * Class to describe and enable module Mailing */ class modNotification extends DolibarrModules { @@ -53,7 +53,7 @@ class modNotification extends DolibarrModules // Data directories to create when module is enabled. $this->dirs = array(); - // Dependances + // Dependencies $this->depends = array(); $this->requiredby = array(); $this->langfiles = array("mails"); @@ -61,10 +61,10 @@ class modNotification extends DolibarrModules // Config pages $this->config_page_url = array("notification.php"); - // Constantes + // Constants $this->const = array(); - // Boites + // Boxes $this->boxes = array(); // Permissions diff --git a/htdocs/core/modules/modPrelevement.class.php b/htdocs/core/modules/modPrelevement.class.php index 84bd19712df..107b8e25c16 100644 --- a/htdocs/core/modules/modPrelevement.class.php +++ b/htdocs/core/modules/modPrelevement.class.php @@ -30,7 +30,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Prelevement + * Class to describe and enable module Prelevement */ class modPrelevement extends DolibarrModules { @@ -70,10 +70,10 @@ class modPrelevement extends DolibarrModules // Config pages $this->config_page_url = array("prelevement.php"); - // Constantes + // Constants $this->const = array(); - // Boites + // Boxes $this->boxes = array(); // Permissions diff --git a/htdocs/core/modules/modPrinting.class.php b/htdocs/core/modules/modPrinting.class.php index 26537f97927..a02e8fa0345 100644 --- a/htdocs/core/modules/modPrinting.class.php +++ b/htdocs/core/modules/modPrinting.class.php @@ -66,7 +66,7 @@ class modPrinting extends DolibarrModules // Config pages $this->config_page_url = array("printing.php@printing"); - // Dependances + // Dependencies $this->depends = array(); $this->requiredby = array(); $this->phpmin = array(5,1); // Minimum version of PHP required by module @@ -74,7 +74,7 @@ class modPrinting extends DolibarrModules $this->conflictwith = array(); $this->langfiles = array("printing"); - // Constantes + // Constants $this->const = array(); // Boxes diff --git a/htdocs/core/modules/modProjet.class.php b/htdocs/core/modules/modProjet.class.php index ca66e861862..5891aff607a 100644 --- a/htdocs/core/modules/modProjet.class.php +++ b/htdocs/core/modules/modProjet.class.php @@ -32,7 +32,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Projet + * Class to describe and enable module Projet */ class modProjet extends DolibarrModules { diff --git a/htdocs/core/modules/modPropale.class.php b/htdocs/core/modules/modPropale.class.php index cb297f87a61..78fa9b53211 100644 --- a/htdocs/core/modules/modPropale.class.php +++ b/htdocs/core/modules/modPropale.class.php @@ -31,7 +31,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Propale + * Class to describe and enable module Propale */ class modPropale extends DolibarrModules { diff --git a/htdocs/core/modules/modSalaries.class.php b/htdocs/core/modules/modSalaries.class.php index b4e349d7560..cb6c588ddbf 100644 --- a/htdocs/core/modules/modSalaries.class.php +++ b/htdocs/core/modules/modSalaries.class.php @@ -69,7 +69,7 @@ class modSalaries extends DolibarrModules // Config pages $this->config_page_url = array('salaries.php'); - // Dependances + // Dependencies $this->depends = array(); $this->requiredby = array(); $this->conflictwith = array(); diff --git a/htdocs/core/modules/modService.class.php b/htdocs/core/modules/modService.class.php index 85ab2b03e7d..9af9590933e 100644 --- a/htdocs/core/modules/modService.class.php +++ b/htdocs/core/modules/modService.class.php @@ -30,7 +30,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Service + * Class to describe and enable module Service */ class modService extends DolibarrModules { diff --git a/htdocs/core/modules/modSkype.class.php b/htdocs/core/modules/modSkype.class.php index 68b7619253b..280b871e475 100644 --- a/htdocs/core/modules/modSkype.class.php +++ b/htdocs/core/modules/modSkype.class.php @@ -71,7 +71,7 @@ class modSkype extends DolibarrModules $this->conflictwith = array(); // List of modules id this module is in conflict with $this->langfiles = array(); - // Constantes + // Constants //----------- diff --git a/htdocs/core/modules/modSociete.class.php b/htdocs/core/modules/modSociete.class.php index 68db9ea47f6..b0fc90a2f27 100644 --- a/htdocs/core/modules/modSociete.class.php +++ b/htdocs/core/modules/modSociete.class.php @@ -31,7 +31,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Societe + * Class to describe and enable module Societe */ class modSociete extends DolibarrModules { @@ -65,12 +65,12 @@ class modSociete extends DolibarrModules // Data directories to create when module is enabled $this->dirs = array("/societe/temp"); - // Dependances + // Dependencies $this->depends = array(); $this->requiredby = array("modExpedition","modFacture","modFournisseur","modFicheinter","modPropale","modContrat","modCommande"); $this->langfiles = array("companies"); - // Constantes + // Constants $this->const = array(); $r=0; diff --git a/htdocs/core/modules/modStock.class.php b/htdocs/core/modules/modStock.class.php index 2b8e983372e..7d312a5a2b0 100644 --- a/htdocs/core/modules/modStock.class.php +++ b/htdocs/core/modules/modStock.class.php @@ -30,7 +30,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Stock + * Class to describe and enable module Stock */ class modStock extends DolibarrModules { diff --git a/htdocs/core/modules/modSyncSupplierWebServices.class.php b/htdocs/core/modules/modSyncSupplierWebServices.class.php index b87d7d9ecd5..96403f67ee4 100644 --- a/htdocs/core/modules/modSyncSupplierWebServices.class.php +++ b/htdocs/core/modules/modSyncSupplierWebServices.class.php @@ -65,7 +65,7 @@ class modSyncSupplierWebServices extends DolibarrModules $this->requiredby = array(); $this->langfiles = array("other"); - // Constantes + // Constants //----------- $this->const = array(); diff --git a/htdocs/core/modules/modSyslog.class.php b/htdocs/core/modules/modSyslog.class.php index a635e8f2fdc..fc8ad99abf8 100644 --- a/htdocs/core/modules/modSyslog.class.php +++ b/htdocs/core/modules/modSyslog.class.php @@ -66,14 +66,14 @@ class modSyslog extends DolibarrModules // Config pages $this->config_page_url = array("syslog.php"); - // Dependances + // Dependencies $this->depends = array(); $this->requiredby = array(); - // Constantes + // Constants $this->const = array(); - // Boites + // Boxes $this->boxes = array(); // Permissions diff --git a/htdocs/core/modules/modTax.class.php b/htdocs/core/modules/modTax.class.php index 9e8ee7908d7..d18be36d8f3 100644 --- a/htdocs/core/modules/modTax.class.php +++ b/htdocs/core/modules/modTax.class.php @@ -31,7 +31,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Tax + * Class to describe and enable module Tax */ class modTax extends DolibarrModules { @@ -67,16 +67,16 @@ class modTax extends DolibarrModules // Config pages $this->config_page_url = array("taxes.php"); - // Dependances + // Dependencies $this->depends = array(); $this->requiredby = array(); $this->conflictwith = array(); $this->langfiles = array("compta","bills"); - // Constantes + // Constants $this->const = array(); - // Boites + // Boxes $this->boxes = array(); // Permissions diff --git a/htdocs/core/modules/modUser.class.php b/htdocs/core/modules/modUser.class.php index c55e65e7004..8c510186f06 100644 --- a/htdocs/core/modules/modUser.class.php +++ b/htdocs/core/modules/modUser.class.php @@ -28,7 +28,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module User + * Class to describe and enable module User */ class modUser extends DolibarrModules { diff --git a/htdocs/core/modules/modWebServices.class.php b/htdocs/core/modules/modWebServices.class.php index a22e5a5be64..d7b5edb106d 100644 --- a/htdocs/core/modules/modWebServices.class.php +++ b/htdocs/core/modules/modWebServices.class.php @@ -65,7 +65,7 @@ class modWebServices extends DolibarrModules $this->requiredby = array(); $this->langfiles = array("other"); - // Constantes + // Constants //----------- $this->const = array(); diff --git a/htdocs/core/modules/modWorkflow.class.php b/htdocs/core/modules/modWorkflow.class.php index 0eb447306b4..e793d21e03c 100644 --- a/htdocs/core/modules/modWorkflow.class.php +++ b/htdocs/core/modules/modWorkflow.class.php @@ -27,7 +27,7 @@ include_once DOL_DOCUMENT_ROOT .'/core/modules/DolibarrModules.class.php'; /** - * Classe de description et activation du module Workflow + * Class to describe and enable module Workflow */ class modWorkflow extends DolibarrModules { diff --git a/htdocs/core/modules/propale/doc/pdf_azur.modules.php b/htdocs/core/modules/propale/doc/pdf_azur.modules.php index c3da51fc4c4..d54b175750c 100644 --- a/htdocs/core/modules/propale/doc/pdf_azur.modules.php +++ b/htdocs/core/modules/propale/doc/pdf_azur.modules.php @@ -1517,9 +1517,11 @@ class pdf_azur extends ModelePDFPropales $pdf->SetFont('','B', $default_font_size); $pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, 'L'); + $posy = $pdf->getY(); + // Show recipient information $pdf->SetFont('','', $default_font_size - 1); - $pdf->SetXY($posx+2,$posy+4+(dol_nboflines_bis($carac_client_name,50)*4)); + $pdf->SetXY($posx+2,$posy); $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); } diff --git a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php index 90ced6322b7..8a274f91ac7 100644 --- a/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php +++ b/htdocs/core/modules/societe/doc/doc_generic_odt.modules.php @@ -408,8 +408,18 @@ class doc_generic_odt extends ModeleThirdPartyDoc } } else { - try { - $odfHandler->saveToDisk($file); + try { + $odfHandler->creator = $user->getFullName($outputlangs); + $odfHandler->title = $object->builddoc_filename; + $odfHandler->subject = $object->builddoc_filename; + + if (! empty($conf->global->ODT_ADD_DOLIBARR_ID)) + { + $odfHandler->userdefined['dol_id'] = $object->id; + $odfHandler->userdefined['dol_element'] = $object->element; + } + + $odfHandler->saveToDisk($file); }catch (Exception $e){ $this->error=$e->getMessage(); return -1; diff --git a/htdocs/core/modules/societe/modules_societe.class.php b/htdocs/core/modules/societe/modules_societe.class.php index 72090a581ea..63208b1369c 100644 --- a/htdocs/core/modules/societe/modules_societe.class.php +++ b/htdocs/core/modules/societe/modules_societe.class.php @@ -363,6 +363,28 @@ abstract class ModeleAccountancyCode +/** + * Create a document onto disk according to template module. + * + * @param DoliDB $db Database handler + * @param Facture $object Object invoice + * @param string $message Message (not used, deprecated) + * @param string $modele Force template to use ('' to not force) + * @param Translate $outputlangs objet lang a utiliser pour traduction + * @param int $hidedetails Hide details of lines + * @param int $hidedesc Hide description + * @param int $hideref Hide ref + * @return int <0 if KO, >0 if OK + * @deprecated Use the new function generateDocument of Facture class + * @see Societe::generateDocument() + */ +function thirdparty_doc_create(DoliDB $db, Societe $object, $message, $modele, $outputlangs, $hidedetails=0, $hidedesc=0, $hideref=0) +{ + dol_syslog(__METHOD__ . " is deprecated", LOG_WARNING); + + return $object->generateDocument($modele, $outputlangs, $hidedetails, $hidedesc, $hideref); +} + /** * Create a document for third party @@ -374,7 +396,7 @@ abstract class ModeleAccountancyCode * @param Translate $outputlangs Object lang to use for translation * @return int <0 if KO, >0 if OK */ -function thirdparty_doc_create($db, $object, $message, $modele, $outputlangs) +/*function thirdparty_doc_create($db, $object, $message, $modele, $outputlangs) { global $conf,$langs,$user; $langs->load("bills"); @@ -413,7 +435,6 @@ function thirdparty_doc_create($db, $object, $message, $modele, $outputlangs) require_once $dir.'/'.$file; $obj = new $classname($db); - $obj->message = $message; // We save charset_output to restore it because write_file can change it if needed for // output format that does not support UTF8. @@ -438,5 +459,5 @@ function thirdparty_doc_create($db, $object, $message, $modele, $outputlangs) return -1; } } - +*/ 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 9445d71ce8a..265d43ca1fc 100644 --- a/htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php +++ b/htdocs/core/modules/supplier_invoice/pdf/pdf_canelle.modules.php @@ -1132,9 +1132,11 @@ class pdf_canelle extends ModelePDFSuppliersInvoices $pdf->SetFont('','B', $default_font_size); $pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, 'L'); + $posy = $pdf->getY(); + // Show recipient information $pdf->SetFont('','', $default_font_size - 1); - $pdf->SetXY($posx+2,$posy+4+(dol_nboflines_bis($carac_client_name,50)*4)); + $pdf->SetXY($posx+2,$posy); $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); } } diff --git a/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php b/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php index 8e126dcd18d..b2ca0ee0a60 100644 --- a/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php +++ b/htdocs/core/modules/supplier_order/pdf/pdf_muscadet.modules.php @@ -1184,9 +1184,11 @@ class pdf_muscadet extends ModelePDFSuppliersOrders $pdf->SetFont('','B', $default_font_size); $pdf->MultiCell($widthrecbox, 4, $carac_client_name, 0, 'L'); + $posy = $pdf->getY(); + // Show recipient information $pdf->SetFont('','', $default_font_size - 1); - $pdf->SetXY($posx+2,$posy+4+(dol_nboflines_bis($carac_client_name,50)*4)); + $pdf->SetXY($posx+2,$posy); $pdf->MultiCell($widthrecbox, 4, $carac_client, 0, 'L'); } } diff --git a/htdocs/core/modules/syslog/logHandler.php b/htdocs/core/modules/syslog/logHandler.php index 1701ca2bdce..fa013f4b083 100644 --- a/htdocs/core/modules/syslog/logHandler.php +++ b/htdocs/core/modules/syslog/logHandler.php @@ -28,13 +28,23 @@ class LogHandler /** * Content of the info tooltip. * - * @return false|string + * @return string */ public function getInfo() { - return false; + return ''; } + /** + * Return warning if something is wrong with logger + * + * @return string + */ + public function getWarning() + { + return ''; + } + /** * Version of the module ('x.y.z' or 'dolibarr' or 'experimental' or 'development') * diff --git a/htdocs/core/modules/syslog/logHandlerInterface.php b/htdocs/core/modules/syslog/logHandlerInterface.php index f0d78735155..6f59482a1c0 100644 --- a/htdocs/core/modules/syslog/logHandlerInterface.php +++ b/htdocs/core/modules/syslog/logHandlerInterface.php @@ -48,6 +48,13 @@ interface LogHandlerInterface */ public function getInfo(); + /** + * Return warning if something is wrong with logger + * + * @return string Warning message + */ + public function getWarning(); + /** * Return array of configuration data * diff --git a/htdocs/core/modules/syslog/mod_syslog_chromephp.php b/htdocs/core/modules/syslog/mod_syslog_chromephp.php index 9ea39caaf50..adcaa9d7f00 100644 --- a/htdocs/core/modules/syslog/mod_syslog_chromephp.php +++ b/htdocs/core/modules/syslog/mod_syslog_chromephp.php @@ -32,29 +32,40 @@ class mod_syslog_chromephp extends LogHandler implements LogHandlerInterface /** * Content of the info tooltip. * - * @return false|string + * @return string */ public function getInfo() + { + return ''; + } + + /** + * Return warning if something is wrong with logger + * + * @return string + */ + public function getWarning() { global $langs; return $this->isActive()?'':$langs->trans('ClassNotFoundIntoPathWarning','ChromePhp.class.php'); } - + /** * Is the module active ? * - * @return int + * @return int -1 if not active, 0 if active but lib/path not found, 1 if OK */ public function isActive() { global $conf; try { - if (empty($conf->global->SYSLOG_CHROMEPHP_INCLUDEPATH)) $conf->global->SYSLOG_CHROMEPHP_INCLUDEPATH='/usr/share/php'; + if (empty($conf->global->SYSLOG_CHROMEPHP_INCLUDEPATH)) { + $conf->global->SYSLOG_CHROMEPHP_INCLUDEPATH = DOL_DOCUMENT_ROOT . '/includes/ccampbell/chromephp/'; + } set_include_path($conf->global->SYSLOG_CHROMEPHP_INCLUDEPATH); - //print 'rrrrr'.get_include_path(); $res = @include_once('ChromePhp.php'); if (! $res) $res=@include_once('ChromePhp.class.php'); @@ -64,6 +75,10 @@ class mod_syslog_chromephp extends LogHandler implements LogHandlerInterface { return 1; } + else + { + return 0; + } } catch(Exception $e) { @@ -86,9 +101,9 @@ class mod_syslog_chromephp extends LogHandler implements LogHandlerInterface array( 'name' => $langs->trans('IncludePath','SYSLOG_CHROMEPHP_INCLUDEPATH'), 'constant' => 'SYSLOG_CHROMEPHP_INCLUDEPATH', - 'default' => '/usr/share/php', + 'default' => DOL_DOCUMENT_ROOT . '/includes/ccampbell/chromephp/', 'attr' => 'size="60"', - 'example' => DOL_DOCUMENT_ROOT.'/includes/chromephp' + 'example' =>'/usr/share/php, '.DOL_DOCUMENT_ROOT . '/includes/ccampbell/chromephp/' ) ); } diff --git a/htdocs/core/modules/syslog/mod_syslog_sentry.php b/htdocs/core/modules/syslog/mod_syslog_sentry.php new file mode 100644 index 00000000000..cc0bafa568b --- /dev/null +++ b/htdocs/core/modules/syslog/mod_syslog_sentry.php @@ -0,0 +1,188 @@ + + * Copyright (C) 2004-2009 Laurent Destailleur + * Copyright (C) 2015 Raphaël Doursenaud + * + * 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 . + */ + +require_once DOL_DOCUMENT_ROOT . '/core/modules/syslog/logHandler.php'; +require_once DOL_DOCUMENT_ROOT . '/includes/raven/raven/lib/Raven/Autoloader.php'; +Raven_Autoloader::register(); + +/** + * Class to manage logging to Sentry + * + * @see https://docs.getsentry.com/on-premise/clients/php/ + */ +class mod_syslog_sentry extends LogHandler implements LogHandlerInterface +{ + /** + * @var string Log handler code + */ + public $code = 'sentry'; + + /** + * Return name of logger + * + * @return string Name of logger + */ + public function getName() + { + return 'Sentry'; + } + + /** + * Version of the module ('x.y.z' or 'dolibarr' or 'experimental' or 'development') + * + * @return string + */ + public function getVersion() + { + return 'dolibarr'; + } + + /** + * Content of the info tooltip. + * + * @return false|string + */ + public function getInfo() + { + global $langs; + return $langs->trans('SyslogSentryFromProject'); + } + + /** + * Is the module active ? + * + * @return int + */ + public function isActive() + { + return 1; + } + + /** + * Return array of configuration data + * + * @return array Return array of configuration data + */ + public function configure() + { + global $langs; + return array( + array( + 'constant' => 'SYSLOG_SENTRY_DSN', + 'name' => $langs->trans('SyslogSentryDSN'), + 'default' => '', + 'attr' => 'size="100" placeholder="https://:@app.getsentry.com/"' + ) + ); + } + + /** + * Return if configuration is valid + * + * @return array Array of errors. Empty array if ok. + */ + public function checkConfiguration() + { + global $conf; + + $errors = array(); + + $dsn = $conf->global->SYSLOG_SENTRY_DSN; + + try { + $client = new Raven_Client( + $dsn, + array('curl_method' => 'sync') + ); + } catch (InvalidArgumentException $ex) { + $errors[] = "ERROR: There was an error parsing your DSN:\n " . $ex->getMessage(); + } + + if (!$errors) { + // Send test event and check for errors + $client->captureMessage('TEST: Sentry syslog configuration check', null, Raven_Client::DEBUG); + $last_error = $client->getLastError(); + if ($last_error) { + $errors[] = $last_error; + } + } + + if (!$errors) { + // Install handlers + $error_handler = new Raven_ErrorHandler($client); + $error_handler->registerExceptionHandler(); + $error_handler->registerErrorHandler(); + $error_handler->registerShutdownFunction(); + } + + return $errors; + } + + /** + * Export the message + * + * @param array $content Array containing the info about the message + * @return void + */ + public function export($content) + { + global $conf; + $dsn = $conf->global->SYSLOG_SENTRY_DSN; + $client = new Raven_Client( + $dsn, + array('curl_method' => 'exec') + ); + + $client->user_context(array( + 'username' => ($content['user'] ? $content['user'] : ''), + 'ip_address' => $content['ip'] + )); + + $client->tags_context(array( + 'version' => DOL_VERSION + )); + + $client->registerSeverityMap(array( + LOG_EMERG => Raven_Client::FATAL, + LOG_ALERT => Raven_Client::FATAL, + LOG_CRIT => Raven_Client::ERROR, + LOG_ERR => Raven_Client::ERROR, + LOG_WARNING => Raven_Client::WARNING, + LOG_NOTICE => Raven_Client::WARNING, + LOG_INFO => Raven_Client::INFO, + LOG_DEBUG => Raven_Client::DEBUG, + )); + + if (substr($content['message'], 0, 3) === 'sql') { + global $db; + $query = substr($content['message'], 4, strlen($content['message'])); + $client->captureQuery( + $query, + $client->translateSeverity($content['level']), + $db->type + ); + } else { + $client->captureMessage( + $content['message'], + null, + $client->translateSeverity($content['level']) + ); + } + } +} diff --git a/htdocs/core/tpl/contacts.tpl.php b/htdocs/core/tpl/contacts.tpl.php index 382abbe81c0..1381b34fd44 100644 --- a/htdocs/core/tpl/contacts.tpl.php +++ b/htdocs/core/tpl/contacts.tpl.php @@ -1,6 +1,7 @@ * Copyright (C) 2013-2015 Laurent Destailleur + * 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 @@ -94,6 +95,14 @@ $userstatic=new User($db);
trans("ThirdPartyContacts"); ?>
socid; ?> + fetch($selectedCompany); + echo $companystatic->getNomUrl(2); + } + ?> selectCompaniesForNewContact($object, 'id', $selectedCompany, 'newcompany', '', 0); ?>
diff --git a/htdocs/core/tpl/document_actions_pre_headers.tpl.php b/htdocs/core/tpl/document_actions_pre_headers.tpl.php index 1e4dbc7c5bb..2bb6d930b84 100644 --- a/htdocs/core/tpl/document_actions_pre_headers.tpl.php +++ b/htdocs/core/tpl/document_actions_pre_headers.tpl.php @@ -17,6 +17,11 @@ * or see http://www.gnu.org/ */ + +// TODO This is an action include, not a presentation template. +// Move this file into htdocs/core/actions_document.inc.php + + // Variable $upload_dir must be defined when entering here // Send file/link diff --git a/htdocs/core/tpl/extrafields_view.tpl.php b/htdocs/core/tpl/extrafields_view.tpl.php index 7100453cab5..ca8785acdfb 100644 --- a/htdocs/core/tpl/extrafields_view.tpl.php +++ b/htdocs/core/tpl/extrafields_view.tpl.php @@ -49,7 +49,7 @@ if (empty($reshook) && ! empty($extrafields->attribute_label)) print '
'.$langs->trans("Label").'trans("VATPayment")).'">
'.$langs->trans("Label").'
'.$langs->trans("Amount").'
: '; if ($object->birthday_alert) { - print ''.$label.''.$langs->trans($label).'
'.$langs->trans("ReportName").''.$langs->trans("ReportName").''; else print ''; print $nom; @@ -73,7 +73,7 @@ function report_header($nom,$variante,$period,$periodlink,$description,$builddat if ($calcmode) { print '
'.$langs->trans("CalculationMode").''.$langs->trans("CalculationMode").''; else print ''; print $calcmode; @@ -94,7 +94,7 @@ function report_header($nom,$variante,$period,$periodlink,$description,$builddat // Ligne de description print '
'.$langs->trans("ReportDescription").''.$langs->trans("ReportDescription").''.$description.'
attribute_required[$key])) print ' class="fieldrequired"'; - print '>' . $label . ''; + print '>' . $langs->trans($label) . ''; //TODO Improve element and rights detection //var_dump($user->rights); diff --git a/htdocs/core/tpl/objectline_edit.tpl.php b/htdocs/core/tpl/objectline_edit.tpl.php index e38b8f873bd..4b024175423 100644 --- a/htdocs/core/tpl/objectline_edit.tpl.php +++ b/htdocs/core/tpl/objectline_edit.tpl.php @@ -23,7 +23,7 @@ * $object (invoice, order, ...) * $conf * $langs - * $seller, $nuyer + * $seller, $buyer * $dateSelector * $forceall (0 by default, 1 for supplier invoices/orders) * $senderissupplier (0 by default, 1 for supplier invoices/orders) @@ -239,7 +239,15 @@ if (! empty($conf->margin->enabled)) ?> jQuery(document).ready(function() { - /* Add rule to clear margin when we change price_ht or buying_price, so when we change sell or buy price, margin will be recalculated after submitting form */ + /* Add rule to clear margin when we change some data, so when we change sell or buy price, margin will be recalculated after submitting form */ + jQuery("#tva_tx").click(function() { /* somtimes field is a text, sometimes a combo */ + jQuery("input[name='np_marginRate']:first").val(''); + jQuery("input[name='np_markRate']:first").val(''); + }); + jQuery("#tva_tx").keyup(function() { /* somtimes field is a text, sometimes a combo */ + jQuery("input[name='np_marginRate']:first").val(''); + jQuery("input[name='np_markRate']:first").val(''); + }); jQuery("#price_ht").keyup(function() { jQuery("input[name='np_marginRate']:first").val(''); jQuery("input[name='np_markRate']:first").val(''); @@ -251,7 +259,7 @@ if (! empty($conf->margin->enabled)) /* Init field buying_price and fournprice */ $.post('/fourn/ajax/getSupplierPrices.php', {'idprod': fk_product?$line->fk_product:0; ?>}, function(data) { - if (data && data.length > 0) { + if (data && data.length > 0) { var options = ''; var trouve=false; $(data).each(function() { @@ -294,9 +302,10 @@ if (! empty($conf->margin->enabled)) $('#savelinebutton').click(function (e) { return checkEditLine(e, "np_marginRate"); }); + /* Disabled. We must be able to click on button 'cancel'. Check must be done only on button 'save'. $("input[name='np_marginRate']:first").blur(function(e) { return checkEditLine(e, "np_marginRate"); - }); + });*/ global->DISPLAY_MARK_RATES)) @@ -305,9 +314,10 @@ if (! empty($conf->margin->enabled)) $('#savelinebutton').click(function (e) { return checkEditLine(e, "np_markRate"); }); + /* Disabled. We must be able to click on button 'cancel'. Check must be done only on button 'save'. $("input[name='np_markRate']:first").blur(function(e) { return checkEditLine(e, "np_markRate"); - }); + });*/ @@ -315,25 +325,25 @@ if (! empty($conf->margin->enabled)) /* If margin rate field empty, do nothing. */ - /* Force content of price_ht to 0 or if a discount is set recalculate it from margin rate */ + /* Force content of price_ht to 0 or if a discount is set, recalculate it from margin rate */ function checkEditLine(e, npRate) { var buying_price = $("input[name='buying_price']:first"); var remise = $("input[name='remise_percent']:first"); var rate = $("input[name='"+npRate+"']:first"); - if (rate.val() == '') return true; + if (rate.val() == '' || (typeof rate.val()) == 'undefined' ) return true; - if (! $.isNumeric(rate.val().replace(',','.'))) + if (! $.isNumeric(rate.val().replace(' ','').replace(',','.'))) { - alert('trans("rateMustBeNumeric"); ?>'); + alert('transnoentitiesnoconv("rateMustBeNumeric"); ?>'); e.stopPropagation(); setTimeout(function () { rate.focus() }, 50); return false; } - if (npRate == "markRate" && rate.val() >= 100) + if (npRate == "np_markRate" && rate.val() >= 100) { - alert('trans("markRateShouldBeLesserThan100"); ?>'); + alert('transnoentitiesnoconv("markRateShouldBeLesserThan100"); ?>'); e.stopPropagation(); setTimeout(function () { rate.focus() }, 50); return false; @@ -346,12 +356,20 @@ if (! empty($conf->margin->enabled)) { bpjs=price2numjs(buying_price.val()); ratejs=price2numjs(rate.val()); + /* console.log(npRate+" - "+bpjs+" - "+ratejs); */ - if (npRate == "marginRate") - price = ((bpjs * (1 + ratejs / 100)) / (1 - remisejs / 100)); - else if (npRate == "markRate") - price = ((bpjs / (1 - ratejs / 100)) / (1 - remisejs / 100)); + if (npRate == "np_marginRate") + price = ((bpjs * (1 + (ratejs / 100))) / (1 - remisejs / 100)); + else if (npRate == "np_markRate") + { + if (ratejs != 100) + { + price = ((bpjs / (1 - (ratejs / 100))) / (1 - remisejs / 100)); + } + else price=$("input[name='price_ht']:first").val(); + } } + /* console.log("new price ht = "+price); */ $("input[name='price_ht']:first").val(price); // TODO Must use a function like php price to have here a formated value return true; diff --git a/htdocs/cron/list.php b/htdocs/cron/list.php index 37186686938..d6c0fbd2070 100644 --- a/htdocs/cron/list.php +++ b/htdocs/cron/list.php @@ -208,7 +208,7 @@ print ''; if (count($object->lines) > 0) { // Loop on each active job - $style='impair'; + $style='pair'; foreach($object->lines as $line) { // title profil diff --git a/htdocs/don/card.php b/htdocs/don/card.php index 323f36bd609..b56171b8796 100644 --- a/htdocs/don/card.php +++ b/htdocs/don/card.php @@ -229,6 +229,25 @@ if ($action == 'set_paid') setEventMessage($object->error, 'errors'); } } +// Remove file in doc form +if ($action == 'remove_file') +{ + $object = new Don($db, 0, $_GET['id']); + if ($object->fetch($id)) + { + require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; + + $object->fetch_thirdparty(); + + $langs->load("other"); + $upload_dir = $conf->don->dir_output; + $file = $upload_dir . '/' . GETPOST('file'); + $ret=dol_delete_file($file,0,0,0,$object); + if ($ret) setEventMessage($langs->trans("FileWasRemoved", GETPOST('urlfile'))); + else setEventMessage($langs->trans("ErrorFailToDeleteFile", GETPOST('urlfile')), 'errors'); + $action=''; + } +} /* * Build doc @@ -743,13 +762,11 @@ if (! empty($id) && $action != 'edit') /* * Documents generes */ - $filename=dol_sanitizeFileName($object->id); - $filedir=$conf->don->dir_output . '/' . get_exdir($filename,2,0,1,$object,'donation'). '/'. dol_sanitizeFileName($object->ref); - $urlsource=$_SERVER['PHP_SELF'].'?rowid='.$object->id; - // $genallowed=($fac->statut == 1 && ($fac->paye == 0 || $user->admin) && $user->rights->facture->creer); - // $delallowed=$user->rights->facture->supprimer; - $genallowed=1; - $delallowed=0; + $filename = dol_sanitizeFileName($object->id); + $filedir = $conf->don->dir_output . "/" . dol_sanitizeFileName($object->id); + $urlsource = $_SERVER['PHP_SELF'].'?rowid='.$object->id; + $genallowed = ($object->statut == 2 && ($object->paid == 0 || $user->admin) && $user->rights->don->creer); + $delallowed = $user->rights->don->supprimer; $var=true; diff --git a/htdocs/expedition/card.php b/htdocs/expedition/card.php index e72af4de601..1b871136235 100644 --- a/htdocs/expedition/card.php +++ b/htdocs/expedition/card.php @@ -1597,7 +1597,7 @@ else if ($id || $ref) $result = $object->generateDocument(GETPOST('model')?GETPOST('model'):$object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); if ($result <= 0) { - dol_print_error($db,$result); + dol_print_error($db,$object->error,$object->errors); exit; } $fileparams = dol_most_recent_file($conf->expedition->dir_output . '/sending/' . $ref, preg_quote($ref, '/').'[^\-]+'); diff --git a/htdocs/expedition/class/expedition.class.php b/htdocs/expedition/class/expedition.class.php index b6ba93fe91e..edd8aa0cd39 100644 --- a/htdocs/expedition/class/expedition.class.php +++ b/htdocs/expedition/class/expedition.class.php @@ -628,7 +628,7 @@ class Expedition extends CommonObject // TODO possibilite d'expedier a partir d'une propale ou autre origine $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, edb.fk_origin_stock"; + $sql.= " edb.rowid as edbrowid, edb.eatby, edb.sellby, edb.batch, edb.qty as edbqty, edb.fk_origin_stock"; $sql.= " FROM ".MAIN_DB_PREFIX."commandedet as cd,"; $sql.= " ".MAIN_DB_PREFIX."expeditiondet as ed"; $sql.= " LEFT JOIN ".MAIN_DB_PREFIX."expeditiondet_batch as edb on edb.fk_expeditiondet = ed.rowid"; @@ -639,11 +639,19 @@ class Expedition extends CommonObject $resql=$this->db->query($sql); if ($resql) { - $cpt = $this->db->num_rows($resql); - for ($i = 0; $i < $cpt; $i++) + $cpt = $this->db->num_rows($resql); + for ($i = 0; $i < $cpt; $i++) { $obj = $this->db->fetch_object($resql); - if ($obj->qty <= 0) continue; + if (empty($obj->edbrowid)) + { + $qty = $obj->qty; + } + else + { + $qty = $obj->edbqty; + } + if ($qty <= 0) continue; dol_syslog(get_class($this)."::valid movement index ".$i." ed.rowid=".$obj->rowid." edb.rowid=".$obj->edbrowid); //var_dump($this->lines[$i]); @@ -655,7 +663,7 @@ class Expedition extends CommonObject // line without batch detail // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record - $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $obj->qty, $obj->subprice, $langs->trans("ShipmentValidatedInDolibarr",$numref)); + $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ShipmentValidatedInDolibarr",$numref)); if ($result < 0) { $error++; break; } @@ -665,15 +673,16 @@ class Expedition extends CommonObject // line with batch detail // We decrement stock of product (and sub-products) -> update table llx_product_stock (key of this table is fk_product+fk_entrepot) and add a movement record - $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $obj->qty, $obj->subprice, $langs->trans("ShipmentValidatedInDolibarr",$numref), '', $obj->eatby, $obj->sellby, $obj->batch); + $result=$mouvS->livraison($user, $obj->fk_product, $obj->fk_entrepot, $qty, $obj->subprice, $langs->trans("ShipmentValidatedInDolibarr",$numref), '', $obj->eatby, $obj->sellby, $obj->batch); if ($result < 0) { $error++; break; } // We update content of table llx_product_batch (will be rename into llx_product_stock_batch inantoher version) + // We can set livraison_batch to deprecated and adapt livraison to handle batch too (mouvS->_create also calls mouvS->_create_batch) if (! empty($conf->productbatch->enabled)) { - $result=$mouvS->livraison_batch($obj->fk_origin_stock, $obj->qty); // ->fk_origin_stock = id into table llx_product_batch (will be rename into llx_product_stock_batch in another version) + $result=$mouvS->livraison_batch($obj->fk_origin_stock, $qty); // ->fk_origin_stock = id into table llx_product_batch (will be rename into llx_product_stock_batch in another version) if ($result < 0) { $error++; $this->errors[]=$mouvS->error; break; } } } @@ -860,8 +869,8 @@ class Expedition extends CommonObject // $value['q']=qty to move // $value['id_batch']=id into llx_product_batch of record to move //var_dump($value); - - $linebatch = new ExpeditionLineBatch($this->db); + + $linebatch = new ExpeditionLineBatch($this->db); $ret=$linebatch->fetchFromStock($value['id_batch']); // load serial, sellby, eatby if ($ret<0) { diff --git a/htdocs/expensereport/card.php b/htdocs/expensereport/card.php index e7990631457..1eb5d8d47ba 100644 --- a/htdocs/expensereport/card.php +++ b/htdocs/expensereport/card.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2008 Laurent Destailleur + * Copyright (C) 2004-2015 Laurent Destailleur * Copyright (C) 2005-2009 Regis Houssin * Copyright (C) 2015 Alexandre Spangaro * @@ -166,7 +166,8 @@ if ($action == 'update' && $user->rights->expensereport->creer) $object->fk_c_paiement = GETPOST('fk_c_paiement','int'); $object->note_public = GETPOST('note_public'); $object->note_private = GETPOST('note_private'); - + $object->fk_user_modif = $user->id; + $result = $object->update($user); if ($result > 0) { @@ -1318,30 +1319,35 @@ else { dol_fiche_head($head, 'card', $langs->trans("TripCard"), 0, 'trip'); - if ($action == 'save'): - $ret=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("SaveTrip"),$langs->trans("ConfirmSaveTrip"),"confirm_validate","","",1); - if ($ret == 'html') print '
'; - endif; + if ($action == 'save') + { + $ret=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("SaveTrip"),$langs->trans("ConfirmSaveTrip"),"confirm_validate","","",1); + if ($ret == 'html') print '
'; + } - if ($action == 'save_from_refuse'): - $ret=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("SaveTrip"),$langs->trans("ConfirmSaveTrip"),"confirm_save_from_refuse","","",1); - if ($ret == 'html') print '
'; - endif; + if ($action == 'save_from_refuse') + { + $ret=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("SaveTrip"),$langs->trans("ConfirmSaveTrip"),"confirm_save_from_refuse","","",1); + if ($ret == 'html') print '
'; + } - if ($action == 'delete'): - $ret=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("DeleteTrip"),$langs->trans("ConfirmDeleteTrip"),"confirm_delete","","",1); - if ($ret == 'html') print '
'; - endif; + if ($action == 'delete') + { + $ret=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("DeleteTrip"),$langs->trans("ConfirmDeleteTrip"),"confirm_delete","","",1); + if ($ret == 'html') print '
'; + } - if ($action == 'validate'): - $ret=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("ValideTrip"),$langs->trans("ConfirmValideTrip"),"confirm_approve","","",1); - if ($ret == 'html') print '
'; - endif; + if ($action == 'validate') + { + $ret=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("ValideTrip"),$langs->trans("ConfirmValideTrip"),"confirm_approve","","",1); + if ($ret == 'html') print '
'; + } - if ($action == 'paid'): - $ret=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("PaidTrip"),$langs->trans("ConfirmPaidTrip"),"confirm_paid","","",1); - if ($ret == 'html') print '
'; - endif; + if ($action == 'paid') + { + $ret=$form->form_confirm($_SERVER["PHP_SELF"]."?id=".$id,$langs->trans("PaidTrip"),$langs->trans("ConfirmPaidTrip"),"confirm_paid","","",1); + if ($ret == 'html') print '
'; + } if ($action == 'cancel') { @@ -1968,7 +1974,7 @@ if ($action != 'create' && $action != 'edit') * ET user à droit de "to_paid" * Afficher : "Annuler" / "Payer" / "Supprimer" */ - if ($user->rights->expensereport->to_paid && $object->fk_statut == 5) + if ($user->rights->expensereport->to_paid && ! empty($conf->banque->enabled) && $object->fk_statut == 5) { // Pay if ($remaintopay == 0) @@ -1979,8 +1985,11 @@ if ($action != 'create' && $action != 'edit') { print ''; } - - if (round($remaintopay) == 0 && $object->paid == 0) + } + + if (($user->rights->expensereport->to_paid || empty($conf->banque->enabled)) && $object->fk_statut == 5) + { + if ((round($remaintopay) == 0 || empty($conf->banque->enabled)) && $object->paid == 0) { print '"; } diff --git a/htdocs/expensereport/class/expensereport.class.php b/htdocs/expensereport/class/expensereport.class.php index 9a802ac7f34..78ca120516e 100644 --- a/htdocs/expensereport/class/expensereport.class.php +++ b/htdocs/expensereport/class/expensereport.class.php @@ -61,14 +61,16 @@ class ExpenseReport extends CommonObject var $code_paiement; var $code_statut; - /* - ACTIONS - */ + // ACTIONS - // Enregistrement + // Create var $date_create; var $fk_user_author; + // Update + var $date_modif; + var $fk_user_modif; + // Refus var $date_refuse; var $detail_refuse; @@ -141,6 +143,7 @@ class ExpenseReport extends CommonObject $sql.= ",date_create"; $sql.= ",fk_user_author"; $sql.= ",fk_user_validator"; + $sql.= ",fk_user_modif"; $sql.= ",fk_statut"; $sql.= ",fk_c_paiement"; $sql.= ",paid"; @@ -156,6 +159,7 @@ class ExpenseReport extends CommonObject $sql.= ", '".$this->db->idate($now)."'"; $sql.= ", ".($user->id > 0 ? $user->id:"null"); $sql.= ", ".($this->fk_user_validator > 0 ? $this->fk_user_validator:"null"); + $sql.= ", ".($this->fk_user_modif > 0 ? $this->fk_user_modif:"null"); $sql.= ", ".($this->fk_statut > 1 ? $this->fk_statut:0); $sql.= ", ".($this->modepaymentid?$this->modepaymentid:"null"); $sql.= ", 0"; @@ -240,6 +244,7 @@ class ExpenseReport extends CommonObject $sql.= " , fk_user_author = ".($user->id > 0 ? "'".$user->id."'":"null"); $sql.= " , fk_user_validator = ".($this->fk_user_validator > 0 ? $this->fk_user_validator:"null"); $sql.= " , fk_user_valid = ".($this->fk_user_valid > 0 ? $this->fk_user_valid:"null"); + $sql.= " , fk_user_modif = ".($this->fk_user_modif > 0 ? $this->fk_user_modif:"null"); $sql.= " , fk_statut = ".($this->fk_statut >= 0 ? $this->fk_statut:'0'); $sql.= " , fk_c_paiement = ".($this->fk_c_paiement > 0 ? $this->fk_c_paiement:"null"); $sql.= " , note_public = ".(!empty($this->note_public)?"'".$this->db->escape($this->note_public)."'":"''"); @@ -275,9 +280,10 @@ class ExpenseReport extends CommonObject $sql.= " d.detail_refuse, d.detail_cancel, d.fk_user_refuse, d.fk_user_cancel,"; // ACTIONS $sql.= " d.date_refuse, d.date_cancel,"; // ACTIONS $sql.= " d.total_ht, d.total_ttc, d.total_tva,"; // TOTAUX (int) - $sql.= " d.date_debut, d.date_fin, d.date_create, d.date_valid, d.date_approve,"; // DATES (datetime) - $sql.= " d.fk_user_author, d.fk_user_validator, d.fk_statut as status, d.fk_c_paiement,"; + $sql.= " d.date_debut, d.date_fin, d.date_create, d.tms as date_modif, d.date_valid, d.date_approve,"; // DATES (datetime) + $sql.= " d.fk_user_author, d.fk_user_modif, d.fk_user_validator,"; $sql.= " d.fk_user_valid, d.fk_user_approve,"; + $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 LEFT JOIN ".MAIN_DB_PREFIX."c_paiement as dp ON d.fk_c_paiement = dp.id"; if ($ref) $sql.= " WHERE d.ref = '".$this->db->escape($ref)."'"; @@ -306,16 +312,18 @@ class ExpenseReport extends CommonObject $this->date_valid = $this->db->jdate($obj->date_valid); $this->date_approve = $this->db->jdate($obj->date_approve); $this->date_create = $this->db->jdate($obj->date_create); + $this->date_modif = $this->db->jdate($obj->date_modif); $this->date_refuse = $this->db->jdate($obj->date_refuse); $this->date_cancel = $this->db->jdate($obj->date_cancel); $this->fk_user_author = $obj->fk_user_author; + $this->fk_user_modif = $obj->fk_user_modif; $this->fk_user_validator = $obj->fk_user_validator; $this->fk_user_valid = $obj->fk_user_valid; $this->fk_user_refuse = $obj->fk_user_refuse; $this->fk_user_cancel = $obj->fk_user_cancel; $this->fk_user_approve = $obj->fk_user_approve; - + $user_author = new User($this->db); if ($this->fk_user_author > 0) $user_author->fetch($this->fk_user_author); @@ -496,7 +504,13 @@ class ExpenseReport extends CommonObject $muser->fetch($obj->fk_user_modification); $this->user_modification = $muser; } - + if ($obj->fk_user_approve) + { + $auser = new User($this->db); + $auser->fetch($obj->fk_user_approve); + $this->user_approve = $auser; + } + } $this->db->free($resql); } @@ -869,20 +883,21 @@ class ExpenseReport extends CommonObject if ($this->fk_statut != 2) { + $now = dol_now(); + $sql = 'UPDATE '.MAIN_DB_PREFIX.$this->table_element; - $sql.= " SET ref = '".$this->ref."', fk_statut = 2, fk_user_valid = ".$fuser->id.","; + $sql.= " SET ref = '".$this->ref."', fk_statut = 2, fk_user_valid = ".$fuser->id.", date_valid='".$this->db->idate($now)."',"; $sql.= " ref_number_int = ".$ref_number_int; $sql.= ' WHERE rowid = '.$this->id; - dol_syslog(get_class($this)."::set_save sql=".$sql, LOG_DEBUG); - - if ($this->db->query($sql)) + $resql=$this->db->query($sql); + if ($resql) { return 1; } else { - $this->error=$this->db->error(); + $this->error=$this->db->lasterror(); return -1; } } @@ -1465,6 +1480,89 @@ class ExpenseReport extends CommonObject return $ret; } + /** + * Charge indicateurs this->nb pour le tableau de bord + * + * @return int <0 if KO, >0 if OK + */ + function load_state_board() + { + global $conf; + + $this->nb=array(); + + $sql = "SELECT count(ex.rowid) as nb"; + $sql.= " FROM ".MAIN_DB_PREFIX."expensereport as ex"; + $sql.= " WHERE ex.fk_statut > 0"; + $sql.= " AND ex.entity IN (".getEntity('expensereport', 1).")"; + + $resql=$this->db->query($sql); + if ($resql) + { + while ($obj=$this->db->fetch_object($resql)) + { + $this->nb["expensereports"]=$obj->nb; + } + $this->db->free($resql); + return 1; + } + else + { + dol_print_error($this->db); + $this->error=$this->db->error(); + return -1; + } + + } + + /** + * Load indicators for dashboard (this->nbtodo and this->nbtodolate) + * + * @param User $user Objet user + * @return WorkboardResponse|int <0 if KO, WorkboardResponse if OK + */ + function load_board($user) + { + global $conf, $langs; + + if ($user->societe_id) return -1; // protection pour eviter appel par utilisateur externe + + $now=dol_now(); + + $sql = "SELECT ex.rowid, ex.date_valid"; + $sql.= " FROM ".MAIN_DB_PREFIX."expensereport as ex"; + $sql.= " WHERE ex.fk_statut = 5"; + $sql.= " AND ex.entity IN (".getEntity('expensereport', 1).")"; + + $resql=$this->db->query($sql); + if ($resql) + { + $langs->load("members"); + + $response = new WorkboardResponse(); + $response->warning_delay=$conf->expensereport->payment->warning_delay/60/60/24; + $response->label=$langs->trans("ExpenseReportsToPay"); + $response->url=DOL_URL_ROOT.'/expensereport/list.php?mainmenu=hrm&statut=5'; + $response->img=img_object($langs->trans("ExpenseReports"),"user"); + + while ($obj=$this->db->fetch_object($resql)) + { + $response->nbtodo++; + + if ($this->db->jdate($obj->datevalid) < ($now - $conf->expensereport->payment->warning_delay)) { + $response->nbtodolate++; + } + } + + return $response; + } + else + { + dol_print_error($this->db); + $this->error=$this->db->error(); + return -1; + } + } } @@ -1508,14 +1606,14 @@ class ExpenseReportLine } /** - * fetch record + * Fetch record for expense report detailed line * * @param int $rowid Id of object to load * @return int <0 if KO, >0 if OK */ function fetch($rowid) { - $sql = 'SELECT fde.rowid, fde.ref, fde.fk_expensereport, fde.fk_c_type_fees, fde.fk_projet, fde.date,'; + $sql = 'SELECT fde.rowid, fde.fk_expensereport, fde.fk_c_type_fees, fde.fk_projet, fde.date,'; $sql.= ' fde.tva_tx as vatrate, fde.comments, fde.qty, fde.value_unit, fde.total_ht, fde.total_tva, fde.total_ttc,'; $sql.= ' ctf.code as type_fees_code, ctf.label as type_fees_libelle,'; $sql.= ' pjt.rowid as projet_id, pjt.title as projet_title, pjt.ref as projet_ref'; diff --git a/htdocs/expensereport/class/paymentexpensereport.class.php b/htdocs/expensereport/class/paymentexpensereport.class.php index 96e421c4769..c0777654893 100644 --- a/htdocs/expensereport/class/paymentexpensereport.class.php +++ b/htdocs/expensereport/class/paymentexpensereport.class.php @@ -469,7 +469,7 @@ class PaymentExpenseReport extends CommonObject */ function addPaymentToBank($user,$mode,$label,$accountid,$emetteur_nom,$emetteur_banque) { - global $conf; + global $langs,$conf; $error=0; @@ -482,7 +482,7 @@ class PaymentExpenseReport extends CommonObject $total=$this->total; if ($mode == 'payment_expensereport') $amount=$total; - + // Insert payment into llx_bank $bank_line_id = $acc->addline( $this->datepaid, @@ -519,6 +519,32 @@ class PaymentExpenseReport extends CommonObject dol_print_error($this->db); } } + + // Add link 'user' in bank_url between user and bank transaction + if (! $error) + { + foreach ($this->amounts as $key => $value) // We should have always same third party but we loop in case of. + { + if ($mode == 'payment_expensereport') + { + $euser = new User($this->db); + $euser->fetch($key); + $result=$acc->add_url_line( + $bank_line_id, + $euser->id, + DOL_URL_ROOT.'/user/card.php?id=', + $euser->getFullName($langs), + 'user' + ); + if ($result <= 0) + { + $this->error=$this->db->lasterror(); + dol_syslog(get_class($this).'::addPaymentToBank '.$this->error); + $error++; + } + } + } + } } else { diff --git a/htdocs/expensereport/info.php b/htdocs/expensereport/info.php index c1e0b598e7e..b4302631c78 100644 --- a/htdocs/expensereport/info.php +++ b/htdocs/expensereport/info.php @@ -1,6 +1,6 @@ - * Copyright (C) 2004-2005 Laurent Destailleur + * Copyright (C) 2004-2015 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 @@ -59,6 +59,6 @@ if ($id) print ''; } -$db->close(); - llxFooter(); + +$db->close(); diff --git a/htdocs/expensereport/payment/card.php b/htdocs/expensereport/payment/card.php index 0a9b5a05778..eb5314fbd30 100644 --- a/htdocs/expensereport/payment/card.php +++ b/htdocs/expensereport/payment/card.php @@ -157,19 +157,19 @@ print $form->showrefnav($payment,'id','',1,'rowid','id'); print ''; // Date -print '
'; +print ''; // Mode -print ''; +print ''; // Number -print ''; +print ''; // Amount -print ''; +print ''; // Note -print ''; +print ''; // Bank account if (! empty($conf->banque->enabled)) diff --git a/htdocs/expensereport/payment/payment.php b/htdocs/expensereport/payment/payment.php index 3c61179e1b3..c65e42f709c 100644 --- a/htdocs/expensereport/payment/payment.php +++ b/htdocs/expensereport/payment/payment.php @@ -1,5 +1,6 @@ +/* Copyright (C) 2015 Alexandre Spangaro + * Copyright (C) 2015 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 @@ -31,6 +32,7 @@ $langs->load("bills"); $chid=GETPOST("id"); $action=GETPOST('action'); $amounts = array(); +$accountid=GETPOST('accountid','int'); // Security check $socid=0; @@ -67,7 +69,7 @@ if ($action == 'add_payment') $mesg = $langs->trans("ErrorFieldRequired",$langs->transnoentities("Date")); $error++; } - if (! empty($conf->banque->enabled) && ! $_POST["accountid"] > 0) + if (! empty($conf->banque->enabled) && ! $accountid > 0) { $mesg = $langs->trans("ErrorFieldRequired",$langs->transnoentities("AccountToCredit")); $error++; @@ -76,6 +78,7 @@ if ($action == 'add_payment') if (! $error) { $paymentid = 0; + $total = 0; // Read possible payments foreach ($_POST as $key => $value) @@ -84,6 +87,7 @@ if ($action == 'add_payment') { $other_chid = substr($key,7); $amounts[$other_chid] = price2num($_POST[$key]); + $total += price2num($_POST[$key]); } } @@ -102,6 +106,7 @@ if ($action == 'add_payment') $payment->chid = $chid; $payment->datepaid = $datepaid; $payment->amounts = $amounts; // Tableau de montant + $payment->total = $total; $payment->fk_typepayment = $_POST["fk_typepayment"]; $payment->num_payment = $_POST["num_payment"]; $payment->note = $_POST["note"]; @@ -118,7 +123,7 @@ if ($action == 'add_payment') if (! $error) { - $result=$payment->addPaymentToBank($user,'payment_expensereport','(ExpenseReportPayment)',$_POST['accountid'],'',''); + $result=$payment->addPaymentToBank($user,'payment_expensereport','(ExpenseReportPayment)',$accountid,'',''); if (! $result > 0) { $errmsg=$payment->error; diff --git a/htdocs/exports/export.php b/htdocs/exports/export.php index 452f8474e97..8d1f00eac3b 100644 --- a/htdocs/exports/export.php +++ b/htdocs/exports/export.php @@ -3,6 +3,7 @@ * Copyright (C) 2005-2012 Regis Houssin * Copyright (C) 2012 Marcos García * Copyright (C) 2012 Charles-Fr BENKE + * Copyright (C) 2015 Juanjo Menent * * 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 @@ -63,7 +64,8 @@ $entitytoicon = array( 'shipment' => 'sending', 'shipment_line'=> 'sending', 'expensereport'=> 'trip', - 'expensereport_line'=> 'trip' + 'expensereport_line'=> 'trip', + 'contract_line' => 'contract' ); // Translation code @@ -101,7 +103,9 @@ $entitytolang = array( 'task_time' => 'TaskTimeSpent', 'action' => 'Event', 'expensereport'=> 'ExpenseReport', - 'expensereport_line'=> 'ExpenseReportLine' + 'expensereport_line'=> 'ExpenseReportLine', + 'contract' => 'Contract', + 'contract_line'=> 'ContractLine' ); $array_selected=isset($_SESSION["export_selected_fields"])?$_SESSION["export_selected_fields"]:array(); diff --git a/htdocs/fichinter/index.php b/htdocs/fichinter/index.php new file mode 100644 index 00000000000..6885dca361a --- /dev/null +++ b/htdocs/fichinter/index.php @@ -0,0 +1,365 @@ + + * Copyright (C) 2004-2011 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 + * 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/fichinter/index.php + * \ingroup commande + * \brief Home page of interventional module + */ + +require '../main.inc.php'; +require_once DOL_DOCUMENT_ROOT.'/core/class/html.formfile.class.php'; +require_once DOL_DOCUMENT_ROOT .'/core/class/notify.class.php'; +require_once DOL_DOCUMENT_ROOT .'/fichinter/class/fichinter.class.php'; + +if (!$user->rights->ficheinter->lire) accessforbidden(); + +$langs->load("interventions"); + +// Security check +$socid=GETPOST('socid','int'); +if ($user->societe_id > 0) +{ + $action = ''; + $socid = $user->societe_id; +} + + + +/* + * View + */ + +$fichinterstatic=new Fichinter($db); +$form = new Form($db); +$formfile = new FormFile($db); +$help_url="EN:ModuleFichinters|FR:Module_Fiche_Interventions|ES:Módulo_FichaInterventiones"; + +llxHeader("",$langs->trans("Interventions"),$help_url); + +print_fiche_titre($langs->trans("InterventionsArea")); + +//print '
'.$langs->trans('Date').''.dol_print_date($payment->datep,'day').'
'.$langs->trans('Date').''.dol_print_date($payment->datep,'day').'
'.$langs->trans('Mode').''.$langs->trans("PaymentType".$payment->type_code).'
'.$langs->trans('Mode').''.$langs->trans("PaymentType".$payment->type_code).'
'.$langs->trans('Number').''.$payment->num_payment.'
'.$langs->trans('Numero').''.$payment->num_payment.'
'.$langs->trans('Amount').''.price($payment->amount, 0, $outputlangs, 1, -1, -1, $conf->currency).'
'.$langs->trans('Amount').''.price($payment->amount, 0, $outputlangs, 1, -1, -1, $conf->currency).'
'.$langs->trans('Note').''.nl2br($payment->note).'
'.$langs->trans('Note').''.nl2br($payment->note).'
'; +//print '
'; +print '
'; + + +// Search ficheinter +$var=false; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print ''; +print "
'.$langs->trans("SearchAnIntervention").'
'; +print $langs->trans("Ref").':
'.$langs->trans("Other").':

\n"; + + +/* + * Statistics + */ + +$sql = "SELECT count(f.rowid), f.fk_statut"; +$sql.= " FROM ".MAIN_DB_PREFIX."societe as s"; +$sql.= ", ".MAIN_DB_PREFIX."fichinter as f"; +if (! $user->rights->societe->client->voir && ! $socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; +$sql.= " WHERE f.fk_soc = s.rowid"; +$sql.= " AND f.entity IN (".getEntity('societe', 1).")"; +if ($user->societe_id) $sql.=' AND f.fk_soc = '.$user->societe_id; +if (! $user->rights->societe->client->voir && ! $socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; +$sql.= " GROUP BY f.fk_statut"; +$resql = $db->query($sql); +if ($resql) +{ + $num = $db->num_rows($resql); + $i = 0; + + $total=0; + $totalinprocess=0; + $dataseries=array(); + $vals=array(); + $bool=false; + // -1=Canceled, 0=Draft, 1=Validated, 2=Accepted/On process, 3=Closed (Sent/Received, billed or not) + while ($i < $num) + { + $row = $db->fetch_row($resql); + if ($row) + { + //if ($row[1]!=-1 && ($row[1]!=3 || $row[2]!=1)) + { + $bool=(! empty($row[2])?true:false); + if (! isset($vals[$row[1].$bool])) $vals[$row[1].$bool]=0; + $vals[$row[1].$bool]+=$row[0]; + $totalinprocess+=$row[0]; + } + $total+=$row[0]; + } + $i++; + } + $db->free($resql); + print ''; + print ''."\n"; + $listofstatus=array(0,1,2); + $bool=false; + foreach ($listofstatus as $status) + { + $dataseries[]=array('label'=>$fichinterstatic->LibStatut($status,$bool,1),'data'=>(isset($vals[$status.$bool])?(int) $vals[$status.$bool]:0)); + if ($status==3 && $bool==false) $bool=true; + else $bool=false; + } + if ($conf->use_javascript_ajax) + { + print ''; + } + $var=true; + $bool=false; + foreach ($listofstatus as $status) + { + if (! $conf->use_javascript_ajax) + { + $var=!$var; + print ""; + print ''; + print ''; + print "\n"; + if ($status==3 && $bool==false) $bool=true; + else $bool=false; + } + } + //if ($totalinprocess != $total) + //print ''; + print ''; + print "
'.$langs->trans("Statistics").' - '.$langs->trans("Interventions").'
'; + $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).' '; + print $fichinterstatic->LibStatut($status,$bool,3); + print ''; + print '
'.$langs->trans("Total").' ('.$langs->trans("CustomersOrdersRunning").')'.$totalinprocess.'
'.$langs->trans("Total").''.$total.'

"; +} +else +{ + dol_print_error($db); +} + + +/* + * Draft orders + */ +if (! empty($conf->ficheinter->enabled)) +{ + $sql = "SELECT f.rowid, f.ref, s.nom as name, s.rowid as socid"; + $sql.= " FROM ".MAIN_DB_PREFIX."fichinter as f"; + $sql.= ", ".MAIN_DB_PREFIX."societe as s"; + if (!$user->rights->societe->client->voir && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE f.fk_soc = s.rowid"; + $sql.= " AND f.entity IN (".getEntity('fichinter', 1).")"; + $sql.= " AND f.fk_statut = 0"; + if ($socid) $sql.= " AND f.fk_soc = ".$socid; + if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + + $resql=$db->query($sql); + if ($resql) + { + print ''; + print ''; + print ''; + $langs->load("fichinter"); + $num = $db->num_rows($resql); + if ($num) + { + $i = 0; + $var = true; + while ($i < $num) + { + $var=!$var; + $obj = $db->fetch_object($resql); + print ""; + print '"; + print ''; + $i++; + } + } + print "
'.$langs->trans("DraftFichinter").'
'; + print "rowid."\">".img_object($langs->trans("ShowFichinter"),"intervention").' '.$obj->ref."'.img_object($langs->trans("ShowCompany"),"company").' '.dol_trunc($obj->name,24).'

"; + } +} + + +//print '
'; +print '
'; + + +$max=5; + +/* + * Last modified orders + */ + +$sql = "SELECT f.rowid, f.ref, f.fk_statut, f.date_valid as datec, f.tms as datem,"; +$sql.= " s.nom as name, s.rowid as socid"; +$sql.= " FROM ".MAIN_DB_PREFIX."fichinter as f,"; +$sql.= " ".MAIN_DB_PREFIX."societe as s"; +if (!$user->rights->societe->client->voir && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; +$sql.= " WHERE f.fk_soc = s.rowid"; +$sql.= " AND f.entity IN (".getEntity('commande', 1).")"; +//$sql.= " AND c.fk_statut > 2"; +if ($socid) $sql .= " AND f.fk_soc = ".$socid; +if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; +$sql.= " ORDER BY f.tms DESC"; +$sql.= $db->plimit($max, 0); + +$resql=$db->query($sql); +if ($resql) +{ + print ''; + print ''; + print ''; + + $num = $db->num_rows($resql); + if ($num) + { + $i = 0; + $var = true; + while ($i < $num) + { + $var=!$var; + $obj = $db->fetch_object($resql); + + print ""; + print ''; + + print ''; + print ''; + print ''; + print ''; + $i++; + } + } + print "
'.$langs->trans("LastModifiedInterventions",$max).'
'; + + $fichinterstatic->id=$obj->rowid; + $fichinterstatic->ref=$obj->ref; + + print ''; + print ''; + + print ''; + + print '
'; + print $fichinterstatic->getNomUrl(1); + print ''; + print ' '; + print ''; + $filename=dol_sanitizeFileName($obj->ref); + $filedir=$conf->commande->dir_output . '/' . dol_sanitizeFileName($obj->ref); + $urlsource=$_SERVER['PHP_SELF'].'?id='.$obj->rowid; + print $formfile->getDocumentsLink($fichinterstatic->element, $filename, $filedir); + print '
'; + + print '
'.img_object($langs->trans("ShowCompany"),"company").' '.$obj->name.''.dol_print_date($db->jdate($obj->datem),'day').''.$fichinterstatic->LibStatut($obj->fk_statut,5).'

"; +} +else dol_print_error($db); + + +/* + * Orders to process + */ +if (! empty($conf->commande->enabled)) +{ + $sql = "SELECT f.rowid, f.ref, f.fk_statut, s.nom as name, s.rowid as socid"; + $sql.=" FROM ".MAIN_DB_PREFIX."fichinter as f"; + $sql.= ", ".MAIN_DB_PREFIX."societe as s"; + if (!$user->rights->societe->client->voir && !$socid) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; + $sql.= " WHERE f.fk_soc = s.rowid"; + $sql.= " AND f.entity IN (".getEntity('commande', 1).")"; + $sql.= " AND f.fk_statut = 1"; + if ($socid) $sql.= " AND f.fk_soc = ".$socid; + if (!$user->rights->societe->client->voir && !$socid) $sql.= " AND s.rowid = sc.fk_soc AND sc.fk_user = " .$user->id; + $sql.= " ORDER BY f.rowid DESC"; + + $resql=$db->query($sql); + if ($resql) + { + $num = $db->num_rows($resql); + + print ''; + print ''; + print ''; + + if ($num) + { + $i = 0; + $var = true; + while ($i < $num) + { + $var=!$var; + $obj = $db->fetch_object($resql); + print ""; + print ''; + + print ''; + + print ''; + + print ''; + $i++; + } + } + + print "
'.$langs->trans("OrdersToProcess").' '.$num.'
'; + + $fichinterstatic->id=$obj->rowid; + $fichinterstatic->ref=$obj->ref; + + print ''; + print ''; + + print ''; + + print '
'; + print $fichinterstatic->getNomUrl(1); + print ''; + print ' '; + print ''; + $filename=dol_sanitizeFileName($obj->ref); + $filedir=$conf->commande->dir_output . '/' . dol_sanitizeFileName($obj->ref); + $urlsource=$_SERVER['PHP_SELF'].'?id='.$obj->rowid; + print $formfile->getDocumentsLink($fichinterstatic->element, $filename, $filedir); + print '
'; + + print '
'.img_object($langs->trans("ShowCompany"),"company").' '.dol_trunc($obj->name,24).''.$fichinterstatic->LibStatut($obj->fk_statut,5).'

"; + } + else dol_print_error($db); +} + + + + +//print '
'; +print ''; + + +llxFooter(); + +$db->close(); diff --git a/htdocs/filefunc.inc.php b/htdocs/filefunc.inc.php index beead03469c..08080b9388d 100644 --- a/htdocs/filefunc.inc.php +++ b/htdocs/filefunc.inc.php @@ -30,7 +30,7 @@ * \brief File that include conf.php file and commons lib like functions.lib.php */ -if (! defined('DOL_VERSION')) define('DOL_VERSION','3.8.0-beta'); +if (! defined('DOL_VERSION')) define('DOL_VERSION','3.9.0-beta'); if (! defined('EURO')) define('EURO',chr(128)); @@ -205,11 +205,11 @@ define('MAIN_DB_PREFIX',$dolibarr_main_db_prefix); // Path to root libraries if (! defined('ADODB_PATH')) { define('ADODB_PATH', (!isset($dolibarr_lib_ADODB_PATH))?DOL_DOCUMENT_ROOT.'/includes/adodbtime/':(empty($dolibarr_lib_ADODB_PATH)?'':$dolibarr_lib_ADODB_PATH.'/')); } if (! defined('FPDF_PATH')) { define('FPDF_PATH', (empty($dolibarr_lib_FPDF_PATH))?DOL_DOCUMENT_ROOT.'/includes/fpdf/':$dolibarr_lib_FPDF_PATH.'/'); } // Used only for package that can't include tcpdf -if (! defined('TCPDF_PATH')) { define('TCPDF_PATH', (empty($dolibarr_lib_TCPDF_PATH))?DOL_DOCUMENT_ROOT.'/includes/tcpdf/':$dolibarr_lib_TCPDF_PATH.'/'); } +if (! defined('TCPDF_PATH')) { define('TCPDF_PATH', (empty($dolibarr_lib_TCPDF_PATH))?DOL_DOCUMENT_ROOT.'/includes/tecnick.com/tcpdf/':$dolibarr_lib_TCPDF_PATH.'/'); } if (! defined('FPDI_PATH')) { define('FPDI_PATH', (empty($dolibarr_lib_FPDI_PATH))?DOL_DOCUMENT_ROOT.'/includes/fpdfi/':$dolibarr_lib_FPDI_PATH.'/'); } if (! defined('TCPDI_PATH')) { define('TCPDI_PATH', (empty($dolibarr_lib_TCPDI_PATH))?DOL_DOCUMENT_ROOT.'/includes/tcpdi/':$dolibarr_lib_TCPDI_PATH.'/'); } if (! defined('NUSOAP_PATH')) { define('NUSOAP_PATH', (!isset($dolibarr_lib_NUSOAP_PATH))?DOL_DOCUMENT_ROOT.'/includes/nusoap/lib/':(empty($dolibarr_lib_NUSOAP_PATH)?'':$dolibarr_lib_NUSOAP_PATH.'/')); } -if (! defined('PHPEXCEL_PATH')) { define('PHPEXCEL_PATH', (!isset($dolibarr_lib_PHPEXCEL_PATH))?DOL_DOCUMENT_ROOT.'/includes/phpexcel/':(empty($dolibarr_lib_PHPEXCEL_PATH)?'':$dolibarr_lib_PHPEXCEL_PATH.'/')); } +if (! defined('PHPEXCEL_PATH')) { define('PHPEXCEL_PATH', (!isset($dolibarr_lib_PHPEXCEL_PATH))?DOL_DOCUMENT_ROOT.'/includes/phpoffice/phpexcel/Classes/':(empty($dolibarr_lib_PHPEXCEL_PATH)?'':$dolibarr_lib_PHPEXCEL_PATH.'/')); } if (! defined('GEOIP_PATH')) { define('GEOIP_PATH', (!isset($dolibarr_lib_GEOIP_PATH))?DOL_DOCUMENT_ROOT.'/includes/geoip/':(empty($dolibarr_lib_GEOIP_PATH)?'':$dolibarr_lib_GEOIP_PATH.'/')); } if (! defined('ODTPHP_PATH')) { define('ODTPHP_PATH', (!isset($dolibarr_lib_ODTPHP_PATH))?DOL_DOCUMENT_ROOT.'/includes/odtphp/':(empty($dolibarr_lib_ODTPHP_PATH)?'':$dolibarr_lib_ODTPHP_PATH.'/')); } if (! defined('ODTPHP_PATHTOPCLZIP')) { define('ODTPHP_PATHTOPCLZIP', (!isset($dolibarr_lib_ODTPHP_PATHTOPCLZIP))?DOL_DOCUMENT_ROOT.'/includes/odtphp/zip/pclzip/':(empty($dolibarr_lib_ODTPHP_PATHTOPCLZIP)?'':$dolibarr_lib_ODTPHP_PATHTOPCLZIP.'/')); } diff --git a/htdocs/fourn/card.php b/htdocs/fourn/card.php index 78a78195d37..5a1f38806bb 100644 --- a/htdocs/fourn/card.php +++ b/htdocs/fourn/card.php @@ -4,8 +4,9 @@ * Copyright (C) 2004-2014 Laurent Destailleur * Copyright (C) 2005-2010 Regis Houssin * Copyright (C) 2010-2015 Juanjo Menent - * Copyright (C) 2014 Jean Heimburger + * Copyright (C) 2014 Jean Heimburger * Copyright (C) 2015 Marcos García + * Copyright (C) 2015 Raphaël Doursenaud * * 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 @@ -262,6 +263,12 @@ if ($object->id > 0) print ""; print ''; + // Categories + print '' . $langs->trans("Categories") . ''; + print ''; + print $form->showCategories($object->id, 'supplier', 1); + print ""; + // Other attributes $parameters=array('socid'=>$object->id, 'colspan' => ' colspan="3"', 'colspanvalue' => '3'); $reshook=$hookmanager->executeHooks('formObjectOptions',$parameters,$object,$action); // Note that $action and $object may have been modified by hook diff --git a/htdocs/fourn/class/fournisseur.commande.class.php b/htdocs/fourn/class/fournisseur.commande.class.php index 9bd341e357c..5e207f0b4b6 100644 --- a/htdocs/fourn/class/fournisseur.commande.class.php +++ b/htdocs/fourn/class/fournisseur.commande.class.php @@ -72,7 +72,11 @@ class CommandeFournisseur extends CommonOrder var $date_approve; var $date_approve2; // Used when SUPPLIER_ORDER_DOUBLE_APPROVAL is set var $date_commande; - var $date_livraison; // Date livraison souhaitee + + /** + * Delivery date + */ + var $date_livraison; var $total_ht; var $total_tva; var $total_localtax1; // Total Local tax 1 @@ -2292,7 +2296,7 @@ class CommandeFournisseur extends CommonOrder $resql=$this->db->query($sql); if ($resql) { - $now=dol_now(); + $commandestatic = new CommandeFournisseur($this->db); $response = new WorkboardResponse(); $response->warning_delay=$conf->commande->fournisseur->warning_delay/60/60/24; @@ -2304,8 +2308,11 @@ class CommandeFournisseur extends CommonOrder { $response->nbtodo++; - $date_to_test = empty($obj->delivery_date) ? $obj->datec : $obj->delivery_date; - if ($obj->fk_statut != 3 && $this->db->jdate($date_to_test) < ($now - $conf->commande->fournisseur->warning_delay)) { + $commandestatic->date_livraison = $this->db->jdate($obj->delivery_date); + $commandestatic->date_commande = $this->db->jdate($obj->datec); + $commandestatic->statut = $obj->fk_statut; + + if ($commandestatic->hasDelay()) { $response->nbtodolate++; } } @@ -2447,6 +2454,21 @@ class CommandeFournisseur extends CommonOrder return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + + /** + * Is the supplier order delayed? + * + * @return bool + */ + public function hasDelay() + { + global $conf; + + $now = dol_now(); + $date_to_test = empty($this->date_livraison) ? $this->date_commande : $this->date_livraison; + + return ($this->statut != 3) && $date_to_test < ($now - $conf->commande->fournisseur->warning_delay); + } } diff --git a/htdocs/fourn/class/fournisseur.facture.class.php b/htdocs/fourn/class/fournisseur.facture.class.php index 1bf286ff5aa..c82f3c01941 100644 --- a/htdocs/fourn/class/fournisseur.facture.class.php +++ b/htdocs/fourn/class/fournisseur.facture.class.php @@ -63,7 +63,12 @@ class FactureFournisseur extends CommonInvoice * @see FactureFournisseur::STATUS_DRAFT, FactureFournisseur::STATUS_VALIDATED, FactureFournisseur::STATUS_PAID, FactureFournisseur::STATUS_ABANDONED */ var $statut; - //! 1 si facture payee COMPLETEMENT, 0 sinon (ce champ ne devrait plus servir car insuffisant) + + /** + * Set to 1 if the invoice is completely paid, otherwise is 0 + * @var int + * @deprecated Use statuses stored in self::statut + */ var $paye; var $author; @@ -1151,7 +1156,7 @@ class FactureFournisseur extends CommonInvoice if (empty($txtva)) $txtva=0; if (empty($txlocaltax1)) $txlocaltax1=0; if (empty($txlocaltax2)) $txlocaltax2=0; - + $remise_percent=price2num($remise_percent); $qty=price2num($qty); $pu=price2num($pu); @@ -1197,7 +1202,7 @@ class FactureFournisseur extends CommonInvoice } else { - dol_syslog("Error error=".$this->error, LOG_ERR); + dol_syslog("Error after updateline error=".$this->error, LOG_ERR); $this->db->rollback(); return -1; } @@ -1409,7 +1414,7 @@ class FactureFournisseur extends CommonInvoice { global $conf, $user, $langs; - $sql = 'SELECT ff.rowid, ff.date_lim_reglement as datefin'; + $sql = 'SELECT ff.rowid, ff.date_lim_reglement as datefin, ff.fk_statut'; $sql.= ' FROM '.MAIN_DB_PREFIX.'facture_fourn as ff'; if (!$user->rights->societe->client->voir && !$user->societe_id) $sql.= ", ".MAIN_DB_PREFIX."societe_commerciaux as sc"; $sql.= ' WHERE ff.paye=0'; @@ -1430,10 +1435,16 @@ class FactureFournisseur extends CommonInvoice $response->url=DOL_URL_ROOT.'/fourn/facture/list.php?filtre=paye:0'; $response->img=img_object($langs->trans("Bills"),"bill"); + $facturestatic = new FactureFournisseur($this->db); + while ($obj=$this->db->fetch_object($resql)) { $response->nbtodo++; - if (! empty($obj->datefin) && $this->db->jdate($obj->datefin) < ($now - $conf->facture->fournisseur->warning_delay)) { + + $facturestatic->date_echeance = $this->db->jdate($obj->datefin); + $facturestatic->statut = $obj->fk_statut; + + if ($facturestatic->hasDelay()) { $response->nbtodolate++; } } @@ -1822,6 +1833,24 @@ class FactureFournisseur extends CommonInvoice return CommonObject::commonReplaceThirdparty($db, $origin_id, $dest_id, $tables); } + + /** + * Is the payment of the supplier invoice having a delay? + * + * @return bool + */ + public function hasDelay() + { + global $conf; + + $now = dol_now(); + + if (!$this->date_echeance) { + return false; + } + + return ($this->statut == self::STATUS_VALIDATED) && ($this->date_echeance < ($now - $conf->facture->fournisseur->warning_delay)); + } } @@ -2096,16 +2125,17 @@ class SupplierInvoiceLine extends CommonObjectLine $this->db->begin(); - if ($this->fk_product) { + if (empty($this->fk_product)) + { $fk_product = "null"; } else { $fk_product = $this->fk_product; } - if ($this->fk_unit) { - $fk_unit = "'".$this->db->escape($this->fk_unit)."'"; - } else { + if (empty($this->fk_unit)) { $fk_unit = "null"; + } else { + $fk_unit = "'".$this->db->escape($this->fk_unit)."'"; } $sql = "UPDATE ".MAIN_DB_PREFIX."facture_fourn_det SET"; diff --git a/htdocs/fourn/facture/card.php b/htdocs/fourn/facture/card.php index 38d11843714..b0629909ac0 100644 --- a/htdocs/fourn/facture/card.php +++ b/htdocs/fourn/facture/card.php @@ -526,7 +526,7 @@ if (empty($reshook)) $result = $object->generateDocument($object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); if ($result <= 0) { - dol_print_error($db,$result); + dol_print_error($db,$object->error,$object->errors); exit; } } @@ -1905,7 +1905,9 @@ else // Due date print ''.$form->editfieldkey("DateMaxPayment",'date_lim_reglement',$object->date_echeance,$object,$form_permission,'datepicker').''; print $form->editfieldval("DateMaxPayment",'date_lim_reglement',$object->date_echeance,$object,$form_permission,'datepicker'); - if ($action != 'editdate_lim_reglement' && $object->statut < FactureFournisseur::STATUS_CLOSED && $object->date_echeance && $object->date_echeance < ($now - $conf->facture->fournisseur->warning_delay)) print img_warning($langs->trans('Late')); + if ($action != 'editdate_lim_reglement' && $object->hasDelay()) { + print img_warning($langs->trans('Late')); + } print ''; // Conditions de reglement par defaut @@ -2296,7 +2298,7 @@ else $result = $object->generateDocument(GETPOST('model')?GETPOST('model'):$object->modelpdf, $outputlangs, $hidedetails, $hidedesc, $hideref); if ($result <= 0) { - dol_print_error($db,$result); + dol_print_error($db,$object->error,$object->errors); exit; } $fileparams = dol_most_recent_file($conf->fournisseur->facture->dir_output.'/'.get_exdir($object->id,2,0,0,$object,'invoice_supplier').$ref, preg_quote($ref,'/').'([^\-])+'); diff --git a/htdocs/fourn/facture/impayees.php b/htdocs/fourn/facture/impayees.php index 83d4b830c5f..dbe235cdebc 100644 --- a/htdocs/fourn/facture/impayees.php +++ b/htdocs/fourn/facture/impayees.php @@ -230,6 +230,9 @@ if ($user->rights->fournisseur->facture->lire) { $objp = $db->fetch_object($resql); + $facturestatic->statut = $objp->fk_statut; + $facturestatic->date_echeance = $db->jdate($objp->datelimite); + $var=!$var; print ""; @@ -245,7 +248,9 @@ if ($user->rights->fournisseur->facture->lire) print ''.dol_print_date($db->jdate($objp->df),'day')."\n"; print ''.dol_print_date($db->jdate($objp->datelimite),'day'); - if ($objp->datelimite && $db->jdate($objp->datelimite) < ($now - $conf->facture->fournisseur->warning_delay) && ! $objp->paye && $objp->fk_statut == 1) print img_warning($langs->trans("Late")); + if ($facturestatic->hasDelay()) { + print img_warning($langs->trans("Late")); + } print "\n"; print ''; diff --git a/htdocs/fourn/facture/list.php b/htdocs/fourn/facture/list.php index d93f1c4beea..f5ed63108a6 100644 --- a/htdocs/fourn/facture/list.php +++ b/htdocs/fourn/facture/list.php @@ -305,7 +305,7 @@ if ($resql) print ''; print ''; print ''; - $liststatus=array('paye:0'=>$langs->trans("Unpaid"), 'paye:1'=>$langs->trans("Paid")); + $liststatus=array('fac.fk_statut:0'=>$langs->trans("Draft"),'fac.fk_statut:1,paye:0'=>$langs->trans("Unpaid"), 'paye:1'=>$langs->trans("Paid")); print $form->selectarray('filtre', $liststatus, $filter, 1); print ''; print ''; @@ -323,6 +323,10 @@ if ($resql) while ($i < min($num,$limit)) { $obj = $db->fetch_object($resql); + + $facturestatic->date_echeance = $db->jdate($obj->date_echeance); + $facturestatic->statut = $obj->fk_statut; + $var=!$var; print ""; @@ -342,7 +346,9 @@ if ($resql) print ''.dol_print_date($db->jdate($obj->datef),'day').''; print ''.dol_print_date($db->jdate($obj->date_echeance),'day'); - if (($obj->paye == 0) && ($obj->fk_statut > 0) && $obj->date_echeance && $db->jdate($obj->date_echeance) < ($now - $conf->facture->fournisseur->warning_delay)) print img_picto($langs->trans("Late"),"warning"); + if ($facturestatic->hasDelay()) { + print img_picto($langs->trans("Late"),"warning"); + } print ''; print ''.dol_trunc($obj->libelle,36).''; print ''; diff --git a/htdocs/ftp/index.php b/htdocs/ftp/index.php index 4da37cde779..9b0c2a36e0e 100644 --- a/htdocs/ftp/index.php +++ b/htdocs/ftp/index.php @@ -38,12 +38,13 @@ if ($user->societe_id) $socid=$user->societe_id; $result = restrictedArea($user, 'ftp',''); // Get parameters -$action = isset($_GET["action"])?$_GET["action"]:$_POST['action']; -$section=isset($_GET["section"])?$_GET["section"]:$_POST['section']; +$action=GETPOST('action'); +$section=GETPOST('section'); if (! $section) $section='/'; $numero_ftp = GETPOST("numero_ftp"); -if (! $numero_ftp) $numero_ftp=1; -$file=isset($_GET["file"])?$_GET["file"]:$_POST['file']; +/* if (! $numero_ftp) $numero_ftp=1; */ +$file=GETPOST("file"); +$confirm=GETPOST('confirm'); $upload_dir = $conf->ftp->dir_temp; $download_dir = $conf->ftp->dir_temp; @@ -71,18 +72,19 @@ $ftp_user=$conf->global->$s_ftp_user; $ftp_password=$conf->global->$s_ftp_password; $ftp_passive=$conf->global->$s_ftp_passive; +// For result on connection +$ok=0; $conn_id=null; // FTP connection ID +$mesg=''; -/******************************************************************* +/* * ACTIONS - * - * Put here all code to do according to value of "action" parameter - ********************************************************************/ + */ -// Envoie fichier -if ( $_POST["sendit"] && ! empty($conf->global->MAIN_UPLOAD_DOC)) +// Submit file +if (GETPOST("sendit") && ! empty($conf->global->MAIN_UPLOAD_DOC)) { require_once DOL_DOCUMENT_ROOT.'/core/lib/files.lib.php'; @@ -127,7 +129,7 @@ if ( $_POST["sendit"] && ! empty($conf->global->MAIN_UPLOAD_DOC)) } // Action ajout d'un rep -if ($_POST["action"] == 'add' && $user->rights->ftp->setup) +if ($action == 'add' && $user->rights->ftp->setup) { $ecmdir->ref = $_POST["ref"]; $ecmdir->label = $_POST["label"]; @@ -143,12 +145,12 @@ if ($_POST["action"] == 'add' && $user->rights->ftp->setup) { //TODO: Translate setEventMessage('Error '.$langs->trans($ecmdir->error)); - $_GET["action"] = "create"; + $action = "create"; } } // Remove file -if ($_REQUEST['action'] == 'confirm_deletefile' && $_REQUEST['confirm'] == 'yes') +if ($action == 'confirm_deletefile' && $_REQUEST['confirm'] == 'yes') { // set up a connection or die if (! $conn_id) @@ -246,7 +248,7 @@ if ($_POST["const"] && $_POST["delete"] && $_POST["delete"] == $langs->trans("De } // Remove directory -if ($_REQUEST['action'] == 'confirm_deletesection' && $_REQUEST['confirm'] == 'yes') +if ($action == 'confirm_deletesection' && $confirm == 'yes') { // set up a connection or die if (! $conn_id) @@ -286,7 +288,7 @@ if ($_REQUEST['action'] == 'confirm_deletesection' && $_REQUEST['confirm'] == 'y } // Download directory -if ($_REQUEST['action'] == 'download') +if ($action == 'download') { // set up a connection or die if (! $conn_id) @@ -339,8 +341,7 @@ if ($_REQUEST['action'] == 'download') } else { - //TODO: Translate - setEventMessage('Failed to get file '.$remotefile, 'errors'); + setEventMessages($langs->trans('FailedToGetFile',$remotefile), null, 'errors'); } } @@ -355,11 +356,9 @@ if ($_REQUEST['action'] == 'download') -/******************************************************************* - * PAGE - * - * Put here all code to do according to value of "action" parameter - ********************************************************************/ +/* + * View + */ llxHeader(); @@ -370,11 +369,24 @@ if ($conf->use_javascript_ajax) + trans("FTPArea")); print $langs->trans("FTPAreaDesc")."
"; @@ -397,18 +406,17 @@ if (! function_exists('ftp_connect')) } else { - if (! empty($ftp_server)) + if (! empty($ftp_server)) { - // Confirm remove file - if ($_GET['action'] == 'delete') + if ($action == 'delete') { print $form->formconfirm($_SERVER["PHP_SELF"].'?numero_ftp='.$numero_ftp.'§ion='.urlencode($_REQUEST["section"]).'&file='.urlencode($_GET["file"]), $langs->trans('DeleteFile'), $langs->trans('ConfirmDeleteFile'), 'confirm_deletefile','','',1); } // Confirmation de la suppression d'une ligne categorie - if ($_GET['action'] == 'delete_section') + if ($action == 'delete_section') { print $form->formconfirm($_SERVER["PHP_SELF"].'?numero_ftp='.$numero_ftp.'§ion='.urlencode($_REQUEST["section"]).'&file='.urlencode($_GET["file"]), $langs->trans('DeleteSection'), $langs->trans('ConfirmDeleteSection',$ecmdir->label), 'confirm_deletesection','','',1); @@ -417,8 +425,9 @@ else print $langs->trans("Server").': '.$ftp_server.'
'; print $langs->trans("Port").': '.$ftp_port.' '.($ftp_passive?"(Passive)":"(Active)").'
'; print $langs->trans("User").': '.$ftp_user.'
'; - - print $langs->trans("Directory").': '; + print $langs->trans("FTPs (FTP over SSH)").': '.yn($conf->global->FTP_CONNECT_WITH_SSL).'
'; + print $langs->trans("SFTP (FTP as a subsytem of SSH)").': '.yn($conf->global->FTP_CONNECT_WITH_SFTP).'
'; + print $langs->trans("Directory").': '; $sectionarray=preg_split('|[\/]|',$section); // For / $newsection='/'; @@ -459,30 +468,50 @@ else print ''.$langs->trans("Owner").''."\n"; print ''.$langs->trans("Group").''."\n"; print ''.$langs->trans("Permissions").''."\n"; - print ''; + print ''; + if ($conf->use_javascript_ajax) print ''.$langs->trans("All").' / '.$langs->trans("None").' '; print ''.img_picto($langs->trans("Refresh"),'refresh').' '; print ''."\n"; print ''."\n"; // set up a connection or die - if (! $conn_id) + if (empty($conn_id)) { $resultarray=dol_ftp_connect($ftp_server, $ftp_port, $ftp_user, $ftp_password, $section, $ftp_passive); + $conn_id=$resultarray['conn_id']; $ok=$resultarray['ok']; $mesg=$resultarray['mesg']; - } if ($ok) { //$type = ftp_systype($conn_id); - $newsectioniso=utf8_decode($section); - $buff = ftp_rawlist($conn_id, $newsectioniso); - $contents = ftp_nlist($conn_id, $newsectioniso); // Sometimes rawlist fails but never nlist - //var_dump($contents); - //var_dump($buff); + $newsection=$section; + $newsectioniso=utf8_decode($section); + //$newsection='/home'; + + // List content of directory ($newsection = '/', '/home', ...) + if (! empty($conf->global->FTP_CONNECT_WITH_SFTP)) + { + if ($newsection == '/') $newsection='/./'; // workaround for bug https://bugs.php.net/bug.php?id=64169 + //$dirHandle = opendir("ssh2.sftp://$conn_id".$newsection); + //var_dump($dirHandle); + $contents = scandir('ssh2.sftp://' . $conn_id . $newsection); + $buff=array(); + foreach($contents as $i => $key) + { + $buff[$i]="---------- - root root 1234 Aug 01 2000 ".$key; + } + } + else + { + $buff = ftp_rawlist($conn_id, $newsectioniso); + $contents = ftp_nlist($conn_id, $newsectioniso); // Sometimes rawlist fails but never nlist + //var_dump($contents); + //var_dump($buff); + } $nboflines=count($contents); $var=true; @@ -590,9 +619,16 @@ else } - print ""; + + if (! $ok) + { + print $mesg.'
'."\n"; + setEventMessages($mesg, null, 'errors'); + } + + // Actions /* if ($user->rights->ftp->write && ! empty($section)) @@ -611,20 +647,43 @@ else } else { - print $langs->trans("SetupOfFTPClientModuleNotComplete"); + $s_ftp_server='FTP_SERVER_1'; + if (empty($s_ftp_server)) + { + print $langs->trans("SetupOfFTPClientModuleNotComplete"); + } + else + { + print $langs->trans("ChooseAFTPEntryIntoMenu"); + } } } print '
'; // Close FTP connection -if ($conn_id) ftp_close($conn_id); - -// End of page -$db->close(); +if ($conn_id) +{ + if (! empty($conf->global->FTP_CONNECT_WITH_SFTP)) + { + + } + else if (! empty($conf->global->FTP_CONNECT_WITH_SSL)) + { + ftp_close($conn_id); + } + else + { + ftp_close($conn_id); + } +} + llxFooter(); +$db->close(); + + /** * Connect to FTP server @@ -642,46 +701,90 @@ function dol_ftp_connect($ftp_server, $ftp_port, $ftp_user, $ftp_password, $sect global $langs, $conf; $ok=1; - + $conn_id=null; + if (! is_numeric($ftp_port)) { - $mesg=$langs->trans("FailedToConnectToFTPServer",$ftp_server,$ftp_port); + $mesg=$langs->transnoentitiesnoconv("FailedToConnectToFTPServer",$ftp_server,$ftp_port); $ok=0; } if ($ok) { $connecttimeout=(empty($conf->global->FTP_CONNECT_TIMEOUT)?40:$conf->global->FTP_CONNECT_TIMEOUT); - if (! empty($conf->global->FTP_CONNECT_WITH_SSL)) $conn_id = ftp_ssl_connect($ftp_server, $ftp_port, $connecttimeout); - else $conn_id = ftp_connect($ftp_server, $ftp_port, $connecttimeout); - if ($conn_id) + if (! empty($conf->global->FTP_CONNECT_WITH_SFTP)) + { + dol_syslog('Try to connect with ssh2_ftp'); + $tmp_conn_id = ssh2_connect($ftp_server, $ftp_port); + } + else if (! empty($conf->global->FTP_CONNECT_WITH_SSL)) + { + dol_syslog('Try to connect with ftp_ssl_connect'); + $conn_id = ftp_ssl_connect($ftp_server, $ftp_port, $connecttimeout); + } + else + { + dol_syslog('Try to connect with ftp_connect'); + $conn_id = ftp_connect($ftp_server, $ftp_port, $connecttimeout); + } + if ($conn_id || $tmp_conn_id) { if ($ftp_user) { - if (ftp_login($conn_id, $ftp_user, $ftp_password)) + if (! empty($conf->global->FTP_CONNECT_WITH_SFTP)) { - // Turn on passive mode transfers (must be after a successful login - if ($ftp_passive) ftp_pasv($conn_id, true); - - // Change the dir - $newsectioniso=utf8_decode($section); - ftp_chdir($conn_id, $newsectioniso); - } + if (ssh2_auth_password($tmp_conn_id, $ftp_user, $ftp_password)) + { + // Turn on passive mode transfers (must be after a successful login + //if ($ftp_passive) ftp_pasv($conn_id, true); + + // Change the dir + $newsectioniso=utf8_decode($section); + //ftp_chdir($conn_id, $newsectioniso); + $conn_id = ssh2_sftp($tmp_conn_id); + if (! $conn_id) + { + $mesg=$langs->transnoentitiesnoconv("FailedToConnectToSFTPAfterSSHAuthentication"); + $ok=0; + $error++; + } + } + else + { + $mesg=$langs->transnoentitiesnoconv("FailedToConnectToFTPServerWithCredentials"); + $ok=0; + $error++; + } + } else { - $mesg=$langs->trans("FailedToConnectToFTPServerWithCredentials"); - $ok=0; + if (ftp_login($conn_id, $ftp_user, $ftp_password)) + { + // Turn on passive mode transfers (must be after a successful login + if ($ftp_passive) ftp_pasv($conn_id, true); + + // Change the dir + $newsectioniso=utf8_decode($section); + ftp_chdir($conn_id, $newsectioniso); + } + else + { + $mesg=$langs->transnoentitiesnoconv("FailedToConnectToFTPServerWithCredentials"); + $ok=0; + $error++; + } } } } else { - $mesg=$langs->trans("FailedToConnectToFTPServer",$ftp_server,$ftp_port); + dol_syslog('FailedToConnectToFTPServer '.$ftp_server.' '.$ftp_port, LOG_ERR); + $mesg=$langs->transnoentitiesnoconv("FailedToConnectToFTPServer",$ftp_server,$ftp_port); $ok=0; } } - $arrayresult=array('conn_id'=>$conn_id, 'ok'=>$ok, 'mesg'=>$mesg); + $arrayresult=array('conn_id'=>$conn_id, 'ok'=>$ok, 'mesg'=>$mesg, 'curdir'=>$section, 'curdiriso'=>$newsectioniso); return $arrayresult; } diff --git a/htdocs/holiday/card.php b/htdocs/holiday/card.php index 23c78641462..ebda47dd196 100644 --- a/htdocs/holiday/card.php +++ b/htdocs/holiday/card.php @@ -51,11 +51,12 @@ $now=dol_now(); * Actions */ +// If create a request if ($action == 'create') { $cp = new Holiday($db); - // Si pas le droit de créer une demande + // If no right to create a request if (($userid == $user->id && empty($user->rights->holiday->write)) || ($userid != $user->id && empty($user->rights->holiday->write_all))) { $error++; @@ -83,21 +84,21 @@ if ($action == 'create') $description = trim(GETPOST('description')); $userID = GETPOST('userID'); - // Si pas de date de début + // If no start date if (empty($date_debut)) { header('Location: card.php?action=request&error=nodatedebut'); exit; } - // Si pas de date de fin + // If no end date if (empty($date_fin)) { header('Location: card.php?action=request&error=nodatefin'); exit; } - // Si date de début après la date de fin + // If start date after end date if ($date_debut > $date_fin) { header('Location: card.php?action=request&error=datefin'); @@ -112,7 +113,7 @@ if ($action == 'create') exit; } - // Si aucun jours ouvrés dans la demande + // If there is no Business Days within request $nbopenedday=num_open_day($date_debut_gmt, $date_fin_gmt, 0, 1, $halfday); if($nbopenedday < 0.5) { @@ -120,7 +121,7 @@ if ($action == 'create') exit; } - // Si pas de validateur choisi + // If no validator designated if ($valideur < 1) { header('Location: card.php?action=request&error=Valideur'); @@ -137,7 +138,7 @@ if ($action == 'create') $verif = $cp->create($user); - // Si pas d'erreur SQL on redirige vers la fiche de la demande + // If no SQL error we redirect to the request card if ($verif > 0) { $db->commit(); @@ -149,7 +150,7 @@ if ($action == 'create') { $db->rollback(); - // Sinon on affiche le formulaire de demande avec le message d'erreur SQL + // Otherwise we display the request form with the SQL error message header('Location: card.php?action=request&error=SQL_Create&msg='.$cp->error); exit; } @@ -169,7 +170,7 @@ if ($action == 'update') else if ($starthalfday == 'afternoon') $halfday=-1; else if ($endhalfday == 'morning') $halfday=1; - // Si pas le droit de modifier une demande + // If no right to modify a request if (! $user->rights->holiday->write) { header('Location: card.php?action=request&error=CantUpdate'); @@ -181,40 +182,40 @@ if ($action == 'update') $canedit=(($user->id == $cp->fk_user && $user->rights->holiday->write) || ($user->id != $cp->fk_user && $user->rights->holiday->write_all)); - // Si en attente de validation + // If under validation if ($cp->statut == 1) { - // Si c'est le créateur ou qu'il a le droit de tout lire / modifier + // If this is the requestor or has read/write rights if ($canedit) { $valideur = $_POST['valideur']; $description = trim($_POST['description']); - // Si pas de date de début + // If no start date if (empty($_POST['date_debut_'])) { header('Location: card.php?id='.$_POST['holiday_id'].'&action=edit&error=nodatedebut'); exit; } - // Si pas de date de fin + // If no end date if (empty($_POST['date_fin_'])) { header('Location: card.php?id='.$_POST['holiday_id'].'&action=edit&error=nodatefin'); exit; } - // Si date de début après la date de fin + // If start date after end date if ($date_debut > $date_fin) { header('Location: card.php?id='.$_POST['holiday_id'].'&action=edit&error=datefin'); exit; } - // Si pas de valideur choisi + // If no validator designated if ($valideur < 1) { header('Location: card.php?id='.$_POST['holiday_id'].'&action=edit&error=Valideur'); exit; } - // Si pas de jours ouvrés dans la demande + // If there is no Business Days within request $nbopenedday=num_open_day($date_debut_gmt, $date_fin_gmt, 0, 1, $halfday); if ($nbopenedday < 0.5) { @@ -237,7 +238,7 @@ if ($action == 'update') } else { - // Sinon on affiche le formulaire de demande avec le message d'erreur SQL + // Otherwise we display the request form with the SQL error message header('Location: card.php?id='.$_POST['holiday_id'].'&action=edit&error=SQL_Create&msg='.$cp->error); exit; } @@ -248,7 +249,7 @@ if ($action == 'update') } } -// Si suppression de la demande +// If delete of request if ($action == 'confirm_delete' && GETPOST('confirm') == 'yes' && $user->rights->holiday->delete) { $error=0; @@ -260,7 +261,7 @@ if ($action == 'confirm_delete' && GETPOST('confirm') == 'yes' && $user->rights- $canedit=(($user->id == $cp->fk_user && $user->rights->holiday->write) || ($user->id != $cp->fk_user && $user->rights->holiday->write_all)); - // Si c'est bien un brouillon + // If this is a rough draft if ($cp->statut == 1 || $cp->statut == 3) { // Si l'utilisateur à le droit de lire cette demande, il peut la supprimer diff --git a/htdocs/holiday/list.php b/htdocs/holiday/list.php index f5d67b13517..c350fb003e6 100644 --- a/htdocs/holiday/list.php +++ b/htdocs/holiday/list.php @@ -282,7 +282,7 @@ print "\n"; // FILTRES print ''; print ''; -print ''; +print ''; print ''; // DATE CREATE diff --git a/htdocs/imports/import.php b/htdocs/imports/import.php index 9c48c680c3f..a103a304630 100644 --- a/htdocs/imports/import.php +++ b/htdocs/imports/import.php @@ -1335,10 +1335,10 @@ if ($step == 5 && $datatoimport) continue; } if ($excludefirstline && $sourcelinenb == 1) continue; - + // $result=$obj->import_insert($arrayrecord,$array_match_file_to_database,$objimport,count($fieldssource),$importid); - + if (count($obj->errors)) $arrayoferrors[$sourcelinenb]=$obj->errors; if (count($obj->warnings)) $arrayofwarnings[$sourcelinenb]=$obj->warnings; if (! count($obj->errors) && ! count($obj->warnings)) $nbok++; diff --git a/htdocs/includes/bin/raven b/htdocs/includes/bin/raven new file mode 120000 index 00000000000..9080498f871 --- /dev/null +++ b/htdocs/includes/bin/raven @@ -0,0 +1 @@ +../raven/raven/bin/raven \ No newline at end of file diff --git a/htdocs/includes/chromephp/ChromePhp.php b/htdocs/includes/ccampbell/chromephp/ChromePhp.php old mode 100644 new mode 100755 similarity index 100% rename from htdocs/includes/chromephp/ChromePhp.php rename to htdocs/includes/ccampbell/chromephp/ChromePhp.php diff --git a/htdocs/includes/chromephp/README.md b/htdocs/includes/ccampbell/chromephp/README.md similarity index 100% rename from htdocs/includes/chromephp/README.md rename to htdocs/includes/ccampbell/chromephp/README.md diff --git a/htdocs/includes/chromephp/composer.json b/htdocs/includes/ccampbell/chromephp/composer.json similarity index 100% rename from htdocs/includes/chromephp/composer.json rename to htdocs/includes/ccampbell/chromephp/composer.json diff --git a/htdocs/includes/ckeditor/README.md b/htdocs/includes/ckeditor/README.md deleted file mode 100644 index c5a55cd88f8..00000000000 --- a/htdocs/includes/ckeditor/README.md +++ /dev/null @@ -1,39 +0,0 @@ -CKEditor 4 -========== - -Copyright (c) 2003-2014, CKSource - Frederico Knabben. All rights reserved. -http://ckeditor.com - See LICENSE.md for license information. - -CKEditor is a text editor to be used inside web pages. It's not a replacement -for desktop text editors like Word or OpenOffice, but a component to be used as -part of web applications and websites. - -## Documentation - -The full editor documentation is available online at the following address: -http://docs.ckeditor.com - -## Installation - -Installing CKEditor is an easy task. Just follow these simple steps: - - 1. **Download** the latest version from the CKEditor website: - http://ckeditor.com. You should have already completed this step, but be - sure you have the very latest version. - 2. **Extract** (decompress) the downloaded file into the root of your website. - -**Note:** CKEditor is by default installed in the `ckeditor` folder. You can -place the files in whichever you want though. - -## Checking Your Installation - -The editor comes with a few sample pages that can be used to verify that -installation proceeded properly. Take a look at the `samples` directory. - -To test your installation, just call the following page at your website: - - http:////samples/index.html - -For example: - - http://www.example.com/ckeditor/samples/index.html diff --git a/htdocs/includes/ckeditor/_source/CHANGES.md b/htdocs/includes/ckeditor/_source/CHANGES.md deleted file mode 100644 index a5bec2ba830..00000000000 --- a/htdocs/includes/ckeditor/_source/CHANGES.md +++ /dev/null @@ -1,442 +0,0 @@ -CKEditor 4 Changelog -==================== - -## CKEditor 4.3.3 - -Fixed Issues: - -* [#11500](http://dev.ckeditor.com/ticket/11500): [Webkit/Blink] Fixed: Selection lost when setting data in another inline editor. Additionally, [`selection.removeAllRanges()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-removeAllRanges) is now scoped to selection's [root](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-property-root). -* [#11104](http://dev.ckeditor.com/ticket/11104): [IE] Fixed: Various issues with scrolling and selection when focusing widgets. -* [#11487](http://dev.ckeditor.com/ticket/11487): Moving mouse over the [Enhanced Image](http://ckeditor.com/addon/image2) widget will no longer change the value returned by the [`editor.checkDirty()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-checkDirty) method. -* [#8673](http://dev.ckeditor.com/ticket/8673): [WebKit] Fixed: Cannot select and remove the [Page Break](http://ckeditor.com/addon/pagebreak). -* [#11413](http://dev.ckeditor.com/ticket/11413): Fixed: Incorrect [`editor.execCommand()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-execCommand) behavior. -* [#11438](http://dev.ckeditor.com/ticket/11438): Splitting table cells vertically is no longer changing table structure. -* [#8899](http://dev.ckeditor.com/ticket/8899): Fixed: Links in the [About CKEditor](http://ckeditor.com/addon/about) dialog window now open in a new browser window or tab. -* [#11490](http://dev.ckeditor.com/ticket/11490): Fixed: [Menu button](http://ckeditor.com/addon/menubutton) panel not showing in the source mode. -* [#11417](http://dev.ckeditor.com/ticket/11417): The [`widget.doubleclick`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-event-doubleclick) event is not canceled anymore after editing was triggered. -* [#11253](http://dev.ckeditor.com/ticket/11253): [IE] Fixed: Clipped upload button in the [Enhanced Image](http://ckeditor.com/addon/image2) dialog window. -* [#11359](http://dev.ckeditor.com/ticket/11359): Standardized the way anchors are discovered by the [Link](http://ckeditor.com/addon/link) plugin. -* [#11058](http://dev.ckeditor.com/ticket/11058): [IE8] Fixed: Error when deleting a table row. -* [#11508](http://dev.ckeditor.com/ticket/11508): Fixed: [`htmlDataProcessor`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlDataProcessor) discovering protected attributes within other attributes' values. -* [#11533](http://dev.ckeditor.com/ticket/11533): Widgets: Avoid recurring upcasts if the DOM structure was modified during an upcast. -* [#11400](http://dev.ckeditor.com/ticket/11400): Fixed: The [`domObject.removeAllListeners()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.domObject-method-removeAllListeners) method does not remove custom listeners completely. -* [#11493](http://dev.ckeditor.com/ticket/11493): Fixed: The [`selection.getRanges()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-getRanges) method does not override cached ranges when used with the `onlyEditables` argument. -* [#11390](http://dev.ckeditor.com/ticket/11390): [IE] All [XML](http://ckeditor.com/addon/xml) plugin [methods](http://docs.ckeditor.com/#!/api/CKEDITOR.xml) now work in IE10+. -* [#11542](http://dev.ckeditor.com/ticket/11542): [IE11] Fixed: Blurry toolbar icons when Right-to-Left UI language is set. -* [#11504](http://dev.ckeditor.com/ticket/11504): Fixed: When [`config.fullPage`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-fullPage) is set to `true`, entities are not encoded in editor output. -* [#11004](http://dev.ckeditor.com/ticket/11004): Integrated [Enhanced Image](http://ckeditor.com/addon/image2) dialog window with [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter). -* [#11439](http://dev.ckeditor.com/ticket/11439): Fixed: Properties get cloned in the Cell Properties dialog window if multiple cells are selected. - -## CKEditor 4.3.2 - -Fixed Issues: - -* [#11331](http://dev.ckeditor.com/ticket/11331): A menu button will have a changed label when selected instead of using the `aria-pressed` attribute. -* [#11177](http://dev.ckeditor.com/ticket/11177): Widget drag handler improvements: - * [#11176](http://dev.ckeditor.com/ticket/11176): Fixed: Initial position is not updated when the widget data object is empty. - * [#11001](http://dev.ckeditor.com/ticket/11001): Fixed: Multiple synchronous layout recalculations are caused by initial drag handler positioning causing performance issues. - * [#11161](http://dev.ckeditor.com/ticket/11161): Fixed: Drag handler is not repositioned in various situations. - * [#11281](http://dev.ckeditor.com/ticket/11281): Fixed: Drag handler and mask are duplicated after widget reinitialization. -* [#11207](http://dev.ckeditor.com/ticket/11207): [Firefox] Fixed: Misplaced [Enhanced Image](http://ckeditor.com/addon/image2) resizer in the inline editor. -* [#11102](http://dev.ckeditor.com/ticket/11102): `CKEDITOR.template` improvements: - * [#11102](http://dev.ckeditor.com/ticket/11102): Added newline character support. - * [#11216](http://dev.ckeditor.com/ticket/11216): Added "\\'" substring support. -* [#11121](http://dev.ckeditor.com/ticket/11121): [Firefox] Fixed: High Contrast mode is enabled when the editor is loaded in a hidden iframe. -* [#11350](http://dev.ckeditor.com/ticket/11350): The default value of [`config.contentsCss`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-contentsCss) is affected by [`CKEDITOR.getUrl()`](http://docs.ckeditor.com/#!/api/CKEDITOR-method-getUrl). -* [#11097](http://dev.ckeditor.com/ticket/11097): Improved the [Autogrow](http://ckeditor.com/addon/autogrow) plugin performance when dealing with very big tables. -* [#11290](http://dev.ckeditor.com/ticket/11290): Removed redundant code in the [Source Dialog](http://ckeditor.com/addon/sourcedialog) plugin. -* [#11133](http://dev.ckeditor.com/ticket/11133): [Page Break](http://ckeditor.com/addon/pagebreak) becomes editable if pasted. -* [#11126](http://dev.ckeditor.com/ticket/11126): Fixed: Native Undo executed once the bottom of the snapshot stack is reached. -* [#11131](http://dev.ckeditor.com/ticket/11131): [Div Editing Area](http://ckeditor.com/addon/divarea): Fixed: Error thrown when switching to source mode if the selection was in widget's nested editable. -* [#11139](http://dev.ckeditor.com/ticket/11139): [Div Editing Area](http://ckeditor.com/addon/divarea): Fixed: Elements Path is not cleared after switching to source mode. -* [#10778](http://dev.ckeditor.com/ticket/10778): Fixed a bug with range enlargement. The range no longer expands to visible whitespace. -* [#11146](http://dev.ckeditor.com/ticket/11146): [IE] Fixed: Preview window switches Internet Explorer to Quirks Mode. -* [#10762](http://dev.ckeditor.com/ticket/10762): [IE] Fixed: JavaScript code displayed in preview window's URL bar. -* [#11186](http://dev.ckeditor.com/ticket/11186): Introduced the [`widgets.repository.addUpcastCallback()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-method-addUpcastCallback) method that allows to block upcasting given element to a widget. -* [#11307](http://dev.ckeditor.com/ticket/11307): Fixed: Paste as Plain Text conflict with the [MooTools](http://mootools.net) library. -* [#11140](http://dev.ckeditor.com/ticket/11140): [IE11] Fixed: Anchors are not draggable. -* [#11379](http://dev.ckeditor.com/ticket/11379): Changed default contents `line-height` to unitless values to avoid huge text overlapping (like in [#9696](http://dev.ckeditor.com/ticket/9696)). -* [#10787](http://dev.ckeditor.com/ticket/10787): [Firefox] Fixed: Broken replacement of text while pasting into `div`-based editor. -* [#10884](http://dev.ckeditor.com/ticket/10884): Widgets integration with the [Show Blocks](http://ckeditor.com/addon/showblocks) plugin. -* [#11021](http://dev.ckeditor.com/ticket/11021): Fixed: An error thrown when selecting entire editable contents while fake selection is on. -* [#11086](http://dev.ckeditor.com/ticket/11086): [IE8] Re-enable inline widgets drag&drop in Internet Explorer 8. -* [#11372](http://dev.ckeditor.com/ticket/11372): Widgets: Special characters encoded twice in nested editables. -* [#10068](http://dev.ckeditor.com/ticket/10068): Fixed: Support for protocol-relative URLs. -* [#11283](http://dev.ckeditor.com/ticket/11283): [Enhanced Image](http://ckeditor.com/addon/image2): A `
` element with `text-align: center` and an image inside is not recognised correctly. -* [#11196](http://dev.ckeditor.com/ticket/11196): [Accessibility Instructions](http://ckeditor.com/addon/a11yhelp): Allowed additional keyboard button labels to be translated in the dialog window. - -## CKEditor 4.3.1 - -**Important Notes:** - -* To match the naming convention, the `language` button is now `Language` ([#11201](http://dev.ckeditor.com/ticket/11201)). -* [Enhanced Image](http://ckeditor.com/addon/image2) button, context menu, command, and icon names match those of the [Image](http://ckeditor.com/addon/image) plugin ([#11222](http://dev.ckeditor.com/ticket/11222)). - -Fixed Issues: - -* [#11244](http://dev.ckeditor.com/ticket/11244): Changed: The [`widget.repository.checkWidgets()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-method-checkWidgets) method now fires the [`widget.repository.checkWidgets`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-event-checkWidgets) event, so from CKEditor 4.3.1 it is preferred to use the method rather than fire the event. -* [#11171](http://dev.ckeditor.com/ticket/11171): Fixed: [`editor.insertElement()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertElement) and [`editor.insertText()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertText) methods do not call the [`widget.repository.checkWidgets()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-method-checkWidgets) method. -* [#11085](http://dev.ckeditor.com/ticket/11085): [IE8] Replaced preview generated by the [Mathematical Formulas](http://ckeditor.com/addon/mathjax) widget with a placeholder. -* [#11044](http://dev.ckeditor.com/ticket/11044): Enhanced WAI-ARIA support for the [Language](http://ckeditor.com/addon/language) plugin drop-down menu. -* [#11075](http://dev.ckeditor.com/ticket/11075): With drop-down menu button focused, pressing the *Down Arrow* key will now open the menu and focus its first option. -* [#11165](http://dev.ckeditor.com/ticket/11165): Fixed: The [File Browser](http://ckeditor.com/addon/filebrowser) plugin cannot be removed from the editor. -* [#11159](http://dev.ckeditor.com/ticket/11159): [IE9-10] [Enhanced Image](http://ckeditor.com/addon/image2): Fixed buggy discovery of image dimensions. -* [#11101](http://dev.ckeditor.com/ticket/11101): Drop-down lists no longer break when given double quotes. -* [#11077](http://dev.ckeditor.com/ticket/11077): [Enhanced Image](http://ckeditor.com/addon/image2): Empty undo step recorded when resizing the image. -* [#10853](http://dev.ckeditor.com/ticket/10853): [Enhanced Image](http://ckeditor.com/addon/image2): Widget has paragraph wrapper when de-captioning unaligned image. -* [#11198](http://dev.ckeditor.com/ticket/11198): Widgets: Drag handler is not fully visible when an inline widget is in a heading. -* [#11132](http://dev.ckeditor.com/ticket/11132): [Firefox] Fixed: Caret is lost after drag and drop of an inline widget. -* [#11182](http://dev.ckeditor.com/ticket/11182): [IE10-11] Fixed: Editor crashes (IE11) or works with minor issues (IE10) if a page is loaded in Quirks Mode. See [`env.quirks`](http://docs.ckeditor.com/#!/api/CKEDITOR.env-property-quirks) for more details. -* [#11204](http://dev.ckeditor.com/ticket/11204): Added `figure` and `figcaption` styles to the `contents.css` file so [Enhanced Image](http://ckeditor.com/addon/image2) looks nicer. -* [#11202](http://dev.ckeditor.com/ticket/11202): Fixed: No newline in [BBCode](http://ckeditor.com/addon/bbcode) mode. -* [#10890](http://dev.ckeditor.com/ticket/10890): Fixed: Error thrown when pressing the *Delete* key in a list item. -* [#10055](http://dev.ckeditor.com/ticket/10055): [IE8-10] Fixed: *Delete* pressed on a selected image causes the browser to go back. -* [#11183](http://dev.ckeditor.com/ticket/11183): Fixed: Inserting a horizontal rule or a table in multiple row selection causes a browser crash. Additionally, the [`editor.insertElement()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertElement) method does not insert the element into every range of a selection any more. -* [#11042](http://dev.ckeditor.com/ticket/11042): Fixed: Selection made on an element containing a non-editable element was not auto faked. -* [#11125](http://dev.ckeditor.com/ticket/11125): Fixed: Keyboard navigation through menu and drop-down items will now cycle. -* [#11011](http://dev.ckeditor.com/ticket/11011): Fixed: The [`editor.applyStyle()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-applyStyle) method removes attributes from nested elements. -* [#11179](http://dev.ckeditor.com/ticket/11179): Fixed: [`editor.destroy()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-destroy) does not cleanup content generated by the [Table Resize](http://ckeditor.com/addon/tableresize) plugin for inline editors. -* [#11237](http://dev.ckeditor.com/ticket/11237): Fixed: Table border attribute value is deleted when pasting content from Microsoft Word. -* [#11250](http://dev.ckeditor.com/ticket/11250): Fixed: HTML entities inside the ` - * ... - * CKEDITOR.replace( 'myfield' ); - * - * var textarea = document.body.appendChild( document.createElement( 'textarea' ) ); - * CKEDITOR.replace( textarea ); - * - * @param {Object/String} element The DOM element (textarea), its ID, or name. - * @param {Object} [config] The specific configuration to apply to this - * editor instance. Configuration set here will override the global CKEditor settings - * (see {@link CKEDITOR.config}). - * @returns {CKEDITOR.editor} The editor instance created. - */ - CKEDITOR.replace = function( element, config ) { - return createInstance( element, config, null, CKEDITOR.ELEMENT_MODE_REPLACE ); - }; - - /** - * Creates a new editor instance at the end of a specific DOM element. - * - *
- * ... - * CKEDITOR.appendTo( 'editorSpace' ); - * - * @param {Object/String} element The DOM element, its ID, or name. - * @param {Object} [config] The specific configuration to apply to this - * editor instance. Configuration set here will override the global CKEditor settings - * (see {@link CKEDITOR.config}). - * @param {String} [data] Since 3.3. Initial value for the instance. - * @returns {CKEDITOR.editor} The editor instance created. - */ - CKEDITOR.appendTo = function( element, config, data ) - { - return createInstance( element, config, data, CKEDITOR.ELEMENT_MODE_APPENDTO ); - }; - - /** - * Replaces all ` - data = protectElements( data, protectTextareaRegex ); - - // Before anything, we must protect the URL attributes as the - // browser may changing them when setting the innerHTML later in - // the code. - data = protectAttributes( data ); - - // Protect elements than can't be set inside a DIV. E.g. IE removes - // style tags from innerHTML. (#3710) - data = protectElements( data, protectElementsRegex ); - - // Certain elements has problem to go through DOM operation, protect - // them by prefixing 'cke' namespace. (#3591) - data = protectElementsNames( data ); - - // All none-IE browsers ignore self-closed custom elements, - // protecting them into open-close. (#3591) - data = protectSelfClosingElements( data ); - - // Compensate one leading line break after
 open as browsers
-			// eat it up. (#5789)
-			data = protectPreFormatted( data );
-
-			var fixBin = evtData.context || editor.editable().getName(),
-				isPre;
-
-			// Old IEs loose formats when load html into 
.
-			if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 && fixBin == 'pre' ) {
-				fixBin = 'div';
-				data = '
' + data + '
'; - isPre = 1; - } - - // Call the browser to help us fixing a possibly invalid HTML - // structure. - var el = editor.document.createElement( fixBin ); - // Add fake character to workaround IE comments bug. (#3801) - el.setHtml( 'a' + data ); - data = el.getHtml().substr( 1 ); - - // Restore shortly protected attribute names. - data = data.replace( new RegExp( ' data-cke-' + CKEDITOR.rnd + '-', 'ig' ), ' ' ); - - isPre && ( data = data.replace( /^
|<\/pre>$/gi, '' ) );
-
-			// Unprotect "some" of the protected elements at this point.
-			data = unprotectElementNames( data );
-
-			data = unprotectElements( data );
-
-			// Restore the comments that have been protected, in this way they
-			// can be properly filtered.
-			data = unprotectRealComments( data );
-
-			// Now use our parser to make further fixes to the structure, as
-			// well as apply the filter.
-			evtData.dataValue = CKEDITOR.htmlParser.fragment.fromHtml(
-				data, evtData.context, evtData.fixForBody === false ? false : getFixBodyTag( evtData.enterMode, editor.config.autoParagraph ) );
-		}, null, null, 5 );
-
-		// Filter incoming "data".
-		// Add element filter before htmlDataProcessor.dataFilter when purifying input data to correct html.
-		editor.on( 'toHtml', function( evt ) {
-			if ( evt.data.filter.applyTo( evt.data.dataValue, true, evt.data.dontFilter, evt.data.enterMode ) )
-				editor.fire( 'dataFiltered' );
-		}, null, null, 6 );
-
-		editor.on( 'toHtml', function( evt ) {
-			evt.data.dataValue.filterChildren( that.dataFilter, true );
-		}, null, null, 10 );
-
-		editor.on( 'toHtml', function( evt ) {
-			var evtData = evt.data,
-				data = evtData.dataValue,
-				writer = new CKEDITOR.htmlParser.basicWriter();
-
-			data.writeChildrenHtml( writer );
-			data = writer.getHtml( true );
-
-			// Protect the real comments again.
-			evtData.dataValue = protectRealComments( data );
-		}, null, null, 15 );
-
-
-		editor.on( 'toDataFormat', function( evt ) {
-			var data = evt.data.dataValue;
-
-			// #10854 - we need to strip leading blockless 
which FF adds - // automatically when editable contains only non-editable content. - // We do that for every browser (so it's a constant behavior) and - // not in BR mode, in which chance of valid leading blockless
is higher. - if ( evt.data.enterMode != CKEDITOR.ENTER_BR ) - data = data.replace( /^
/i, '' ); - - evt.data.dataValue = CKEDITOR.htmlParser.fragment.fromHtml( - data, evt.data.context, getFixBodyTag( evt.data.enterMode, editor.config.autoParagraph ) ); - }, null, null, 5 ); - - editor.on( 'toDataFormat', function( evt ) { - evt.data.dataValue.filterChildren( that.htmlFilter, true ); - }, null, null, 10 ); - - // Transform outcoming "data". - // Add element filter after htmlDataProcessor.htmlFilter when preparing output data HTML. - editor.on( 'toDataFormat', function( evt ) { - evt.data.filter.applyTo( evt.data.dataValue, false, true ); - }, null, null, 11 ); - - editor.on( 'toDataFormat', function( evt ) { - var data = evt.data.dataValue, - writer = that.writer; - - writer.reset(); - data.writeChildrenHtml( writer ); - data = writer.getHtml( true ); - - // Restore those non-HTML protected source. (#4475,#4880) - data = unprotectRealComments( data ); - data = unprotectSource( data, editor ); - - evt.data.dataValue = data; - }, null, null, 15 ); - }; - - CKEDITOR.htmlDataProcessor.prototype = { - /** - * Processes the input (potentially malformed) HTML to a purified form which - * is suitable for using in the WYSIWYG editable. - * - * This method fires the {@link CKEDITOR.editor#toHtml} event which makes it possible - * to hook into the process at various stages. - * - * **Note:** Since CKEditor 4.3 the signature of this method changed and all options - * are now grouped in one `options` object. Previously `context`, `fixForBody` and `dontFilter` - * were passed separately. - * - * @param {String} data The raw data. - * @param {Object} [options] The options object. - * @param {String} [options.context] The tag name of a context element within which - * the input is to be processed, default to be the editable element. - * If `null` is passed, then data will be parsed without context (as children of {@link CKEDITOR.htmlParser.fragment}). - * See {@link CKEDITOR.htmlParser.fragment#fromHtml} for more details. - * @param {Boolean} [options.fixForBody=true] Whether to trigger the auto paragraph for non-block contents. - * @param {CKEDITOR.filter} [options.filter] When specified, instead of using the {@link CKEDITOR.editor#filter main filter}, - * passed instance will be used to filter the content. - * @param {Boolean} [options.dontFilter] Do not filter data with {@link CKEDITOR.filter} (note: transformations - * will be still applied). - * @param {Number} [options.enterMode] When specified it will be used instead of the {@link CKEDITOR.editor#enterMode main enterMode}. - * @returns {String} - */ - toHtml: function( data, options, fixForBody, dontFilter ) { - var editor = this.editor, - context, filter, enterMode; - - // Typeof null == 'object', so check truthiness of options too. - if ( options && typeof options == 'object' ) { - context = options.context; - fixForBody = options.fixForBody; - dontFilter = options.dontFilter; - filter = options.filter; - enterMode = options.enterMode; - } - // Backward compatibility. Since CKEDITOR 4.3 every option was a separate argument. - else - context = options; - - // Fall back to the editable as context if not specified. - if ( !context && context !== null ) - context = editor.editable().getName(); - - return editor.fire( 'toHtml', { - dataValue: data, - context: context, - fixForBody: fixForBody, - dontFilter: dontFilter, - filter: filter || editor.filter, - enterMode: enterMode || editor.enterMode - } ).dataValue; - }, - - /** - * See {@link CKEDITOR.dataProcessor#toDataFormat}. - * - * This method fires the {@link CKEDITOR.editor#toDataFormat} event which makes it possible - * to hook into the process at various steps. - * - * @param {String} html - * @param {Object} [options] The options object. - * @param {String} [options.context] The tag name of a context element within which - * the input is to be processed, default to be the editable element. - * @param {CKEDITOR.filter} [options.filter] When specified, instead of using the {@link CKEDITOR.editor#filter main filter}, - * passed instance will be used to apply content transformations to the content. - * @param {Number} [options.enterMode] When specified it will be used instead of the {@link CKEDITOR.editor#enterMode main enterMode}. - * @returns {String} - */ - toDataFormat: function( html, options ) { - var context, filter, enterMode; - - // Do not shorten this to `options && options.xxx`, because - // falsy `options` will be passed instead of undefined. - if ( options ) { - context = options.context; - filter = options.filter; - enterMode = options.enterMode; - } - - // Fall back to the editable as context if not specified. - if ( !context && context !== null ) - context = this.editor.editable().getName(); - - return this.editor.fire( 'toDataFormat', { - dataValue: html, - filter: filter || this.editor.filter, - context: context, - enterMode: enterMode || this.editor.enterMode - } ).dataValue; - } - }; - - // Produce a set of filtering rules that handles bogus and filler node at the - // end of block/pseudo block, in the following consequence: - // 1. elements: - this filter removes any bogus node, then check - // if it's an empty block that requires a filler. - // 2. elements:
- After cleaned with bogus, this filter checks the real - // line-break BR to compensate a filler after it. - // - // Terms definitions: - // filler: An element that's either
or &NBSP; at the end of block that established line height. - // bogus: Whenever a filler is proceeded with inline content, it becomes a bogus which is subjected to be removed. - // - // Various forms of the filler: - // In output HTML: Filler should be consistently &NBSP;
at the end of block is always considered as bogus. - // In Wysiwyg HTML: Browser dependent - see env.needsBrFiller. Either BR for when needsBrFiller is true, or &NBSP; otherwise. - //
is NEVER considered as bogus when needsBrFiller is true. - function createBogusAndFillerRules( editor, type ) { - function createFiller( isOutput ) { - return isOutput || CKEDITOR.env.needsNbspFiller ? - new CKEDITOR.htmlParser.text( '\xa0' ) : - new CKEDITOR.htmlParser.element( 'br', { 'data-cke-bogus': 1 } ); - } - - // This text block filter, remove any bogus and create the filler on demand. - function blockFilter( isOutput, fillEmptyBlock ) { - - return function( block ) { - - // DO NOT apply the filer if it's a fragment node. - if ( block.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT ) - return; - - cleanBogus( block ); - - // [Opera] it's mandatory for the filler to present inside of empty block when in WYSIWYG. - if ( ( ( CKEDITOR.env.opera && !isOutput ) || - ( typeof fillEmptyBlock == 'function' ? fillEmptyBlock( block ) !== false : fillEmptyBlock ) ) && - isEmptyBlockNeedFiller( block ) ) - { - block.add( createFiller( isOutput ) ); - } - }; - } - - // Append a filler right after the last line-break BR, found at the end of block. - function brFilter( isOutput ) { - return function( br ) { - - // DO NOT apply the filer if parent's a fragment node. - if ( br.parent.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT ) - return; - - var attrs = br.attributes; - // Dismiss BRs that are either bogus or eol marker. - if ( 'data-cke-bogus' in attrs || - 'data-cke-eol' in attrs ) { - delete attrs [ 'data-cke-bogus' ]; - return; - } - - // Judge the tail line-break BR, and to insert bogus after it. - var next = getNext( br ), previous = getPrevious( br ); - - if ( !next && isBlockBoundary( br.parent ) ) - append( br.parent, createFiller( isOutput ) ); - else if ( isBlockBoundary( next ) && previous && !isBlockBoundary( previous ) ) - createFiller( isOutput ).insertBefore( next ); - }; - } - - // Determinate whether this node is potentially a bogus node. - function maybeBogus( node, atBlockEnd ) { - - // BR that's not from IE<11 DOM, except for a EOL marker. - if ( !( isOutput && !CKEDITOR.env.needsBrFiller ) && - node.type == CKEDITOR.NODE_ELEMENT && node.name == 'br' && - !node.attributes[ 'data-cke-eol' ] ) - return true; - - var match; - // NBSP, possibly. - if ( node.type == CKEDITOR.NODE_TEXT && - ( match = node.value.match( tailNbspRegex ) ) ) - { - // We need to separate tail NBSP out of a text node, for later removal. - if ( match.index ) { - ( new CKEDITOR.htmlParser.text( node.value.substring( 0, match.index ) ) ).insertBefore( node ); - node.value = match[ 0 ]; - } - - // From IE<11 DOM, at the end of a text block, or before block boundary. - if ( !CKEDITOR.env.needsBrFiller && isOutput && ( !atBlockEnd || node.parent.name in textBlockTags ) ) - return true; - - // From the output. - if ( !isOutput ) { - var previous = node.previous; - - // Following a line-break at the end of block. - if ( previous && previous.name == 'br' ) - return true; - - // Or a single NBSP between two blocks. - if ( !previous || isBlockBoundary( previous ) ) - return true; - } - } - - return false; - } - - // Removes all bogus inside of this block, and to convert fillers into the proper form. - function cleanBogus( block ) { - var bogus = []; - var last = getLast( block ), node, previous; - if ( last ) { - - // Check for bogus at the end of this block. - // e.g.

foo

- maybeBogus( last, 1 ) && bogus.push( last ); - - while ( last ) { - - // Check for bogus at the end of any pseudo block contained. - if ( isBlockBoundary( last ) && - ( node = getPrevious( last ) ) && - maybeBogus( node ) ) - { - // Bogus must have inline proceeding, instead single BR between two blocks, - // is considered as filler, e.g.


- if ( ( previous = getPrevious( node ) ) && !isBlockBoundary( previous ) ) - bogus.push( node ); - // Convert the filler into appropriate form. - else { - createFiller( isOutput ).insertAfter( node ); - node.remove(); - } - } - - last = last.previous; - } - } - - // Now remove all bogus collected from above. - for ( var i = 0 ; i < bogus.length ; i++ ) - bogus[ i ].remove(); - } - - // Judge whether it's an empty block that requires a filler node. - function isEmptyBlockNeedFiller( block ) { - - // DO NOT fill empty editable in IE<11. - if ( !isOutput && !CKEDITOR.env.needsBrFiller && block.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT ) - return false; - - // 1. For IE version >=8, empty blocks are displayed correctly themself in wysiwiyg; - // 2. For the rest, at least table cell and list item need no filler space. (#6248) - if ( !isOutput && !CKEDITOR.env.needsBrFiller && - ( document.documentMode > 7 || - block.name in CKEDITOR.dtd.tr || - block.name in CKEDITOR.dtd.$listItem ) ) { - return false; - } - - var last = getLast( block ); - return !last || block.name == 'form' && last.name == 'input' ; - } - - var rules = { elements: {} }; - var isOutput = type == 'html'; - - // Build the list of text blocks. - var textBlockTags = CKEDITOR.tools.extend( {}, blockLikeTags ); - for ( var i in textBlockTags ) { - if ( !( '#' in dtd[ i ] ) ) - delete textBlockTags[ i ]; - } - - for ( i in textBlockTags ) - rules.elements[ i ] = blockFilter( isOutput, editor.config.fillEmptyBlocks !== false ); - - // Editable element is to be checked separately. - rules.root = blockFilter( isOutput ); - rules.elements.br = brFilter( isOutput ); - return rules; - } - - function getFixBodyTag( enterMode, autoParagraph ) { - return ( enterMode != CKEDITOR.ENTER_BR && autoParagraph !== false ) ? enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p' : false; - } - - // Regex to scan for   at the end of blocks, which are actually placeholders. - // Safari transforms the   to \xa0. (#4172) - var tailNbspRegex = /(?: |\xa0)$/; - - var protectedSourceMarker = '{cke_protected}'; - - function getLast( node ) { - var last = node.children[ node.children.length - 1 ]; - while ( last && isEmpty( last ) ) - last = last.previous; - return last; - } - - function getNext( node ) { - var next = node.next; - while ( next && isEmpty( next ) ) - next = next.next; - return next; - } - - function getPrevious( node ) { - var previous = node.previous; - while ( previous && isEmpty( previous ) ) - previous = previous.previous; - return previous; - } - - // Judge whether the node is an ghost node to be ignored, when traversing. - function isEmpty( node ) { - return node.type == CKEDITOR.NODE_TEXT && - !CKEDITOR.tools.trim( node.value ) || - node.type == CKEDITOR.NODE_ELEMENT && - node.attributes[ 'data-cke-bookmark' ]; - } - - // Judge whether the node is a block-like element. - function isBlockBoundary( node ) { - return node && - ( node.type == CKEDITOR.NODE_ELEMENT && node.name in blockLikeTags || - node.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT ); - } - - function append( parent, node ) { - var last = parent.children[ parent.children.length -1 ]; - parent.children.push( node ); - node.parent = parent; - if ( last ) { - last.next = node; - node.previous = last; - } - } - - function getNodeIndex( node ) { - return node.parent ? node.getIndex() : -1; - } - - var dtd = CKEDITOR.dtd, - // Define orders of table elements. - tableOrder = [ 'caption', 'colgroup', 'col', 'thead', 'tfoot', 'tbody' ], - // List of all block elements. - blockLikeTags = CKEDITOR.tools.extend( {}, dtd.$blockLimit, dtd.$block ); - - // - // DATA filter rules ------------------------------------------------------ - // - - var defaultDataFilterRulesEditableOnly = { - elements: { - input: protectReadOnly, - textarea: protectReadOnly - } - }; - - // These rules will also be applied to non-editable content. - var defaultDataFilterRulesForAll = { - attributeNames: [ - // Event attributes (onXYZ) must not be directly set. They can become - // active in the editing area (IE|WebKit). - [ ( /^on/ ), 'data-cke-pa-on' ], - - // Don't let some old expando enter editor. Concerns only IE8, - // but for consistency remove on all browsers. - [ ( /^data-cke-expando$/ ), '' ] - ] - }; - - // Disable form elements editing mode provided by some browsers. (#5746) - function protectReadOnly( element ) { - var attrs = element.attributes; - - // We should flag that the element was locked by our code so - // it'll be editable by the editor functions (#6046). - if ( attrs.contenteditable != 'false' ) - attrs[ 'data-cke-editable' ] = attrs.contenteditable ? 'true' : 1; - - attrs.contenteditable = 'false'; - } - - // - // HTML filter rules ------------------------------------------------------ - // - - var defaultHtmlFilterRulesEditableOnly = { - elements: { - embed: function( element ) { - var parent = element.parent; - - // If the is child of a , copy the width - // and height attributes from it. - if ( parent && parent.name == 'object' ) { - var parentWidth = parent.attributes.width, - parentHeight = parent.attributes.height; - if ( parentWidth ) - element.attributes.width = parentWidth; - if ( parentHeight ) - element.attributes.height = parentHeight; - } - }, - - // Remove empty link but not empty anchor. (#3829) - a: function( element ) { - if ( !( element.children.length || element.attributes.name || element.attributes[ 'data-cke-saved-name' ] ) ) - return false; - } - } - }; - - // These rules will also be applied to non-editable content. - var defaultHtmlFilterRulesForAll = { - elementNames: [ - // Remove the "cke:" namespace prefix. - [ ( /^cke:/ ), '' ], - - // Ignore tags. - [ ( /^\?xml:namespace$/ ), '' ] - ], - - attributeNames: [ - // Attributes saved for changes and protected attributes. - [ ( /^data-cke-(saved|pa)-/ ), '' ], - - // All "data-cke-" attributes are to be ignored. - [ ( /^data-cke-.*/ ), '' ], - - [ 'hidefocus', '' ] - ], - - elements: { - $: function( element ) { - var attribs = element.attributes; - - if ( attribs ) { - // Elements marked as temporary are to be ignored. - if ( attribs[ 'data-cke-temp' ] ) - return false; - - // Remove duplicated attributes - #3789. - var attributeNames = [ 'name', 'href', 'src' ], - savedAttributeName; - for ( var i = 0; i < attributeNames.length; i++ ) { - savedAttributeName = 'data-cke-saved-' + attributeNames[ i ]; - savedAttributeName in attribs && ( delete attribs[ attributeNames[ i ] ] ); - } - } - - return element; - }, - - // The contents of table should be in correct order (#4809). - table: function( element ) { - // Clone the array as it would become empty during the sort call. - var children = element.children.slice( 0 ); - children.sort( function( node1, node2 ) { - var index1, index2; - - // Compare in the predefined order. - if ( node1.type == CKEDITOR.NODE_ELEMENT && - node2.type == node1.type ) { - index1 = CKEDITOR.tools.indexOf( tableOrder, node1.name ); - index2 = CKEDITOR.tools.indexOf( tableOrder, node2.name ); - } - - // Make sure the sort is stable, if no order can be established above. - if ( !( index1 > -1 && index2 > -1 && index1 != index2 ) ) { - index1 = getNodeIndex( node1 ); - index2 = getNodeIndex( node2 ); - } - - return index1 > index2 ? 1 : -1; - } ); - }, - - // Restore param elements into self-closing. - param: function( param ) { - param.children = []; - param.isEmpty = true; - return param; - }, - - // Remove dummy span in webkit. - span: function( element ) { - if ( element.attributes[ 'class' ] == 'Apple-style-span' ) - delete element.name; - }, - - html: function( element ) { - delete element.attributes.contenteditable; - delete element.attributes[ 'class' ]; - }, - - body: function( element ) { - delete element.attributes.spellcheck; - delete element.attributes.contenteditable; - }, - - style: function( element ) { - var child = element.children[ 0 ]; - if ( child && child.value ) - child.value = CKEDITOR.tools.trim( child.value ); - - if ( !element.attributes.type ) - element.attributes.type = 'text/css'; - }, - - title: function( element ) { - var titleText = element.children[ 0 ]; - - // Append text-node to title tag if not present (i.e. non-IEs) (#9882). - !titleText && append( element, titleText = new CKEDITOR.htmlParser.text() ); - - // Transfer data-saved title to title tag. - titleText.value = element.attributes[ 'data-cke-title' ] || ''; - }, - - input: unprotectReadyOnly, - textarea: unprotectReadyOnly - }, - - attributes: { - 'class': function( value, element ) { - // Remove all class names starting with "cke_". - return CKEDITOR.tools.ltrim( value.replace( /(?:^|\s+)cke_[^\s]*/g, '' ) ) || false; - } - } - }; - - if ( CKEDITOR.env.ie ) { - // IE outputs style attribute in capital letters. We should convert - // them back to lower case, while not hurting the values (#5930) - defaultHtmlFilterRulesForAll.attributes.style = function( value, element ) { - return value.replace( /(^|;)([^\:]+)/g, function( match ) { - return match.toLowerCase(); - } ); - }; - } - - // Disable form elements editing mode provided by some browsers. (#5746) - function unprotectReadyOnly( element ) { - var attrs = element.attributes; - switch ( attrs[ 'data-cke-editable' ] ) { - case 'true': - attrs.contenteditable = 'true'; - break; - case '1': - delete attrs.contenteditable; - break; - } - } - - // - // Preprocessor filters --------------------------------------------------- - // - - var protectElementRegex = /<(a|area|img|input|source)\b([^>]*)>/gi, - // Be greedy while looking for protected attributes. This will let us avoid an unfortunate - // situation when "nested attributes", which may appear valid, are also protected. - // I.e. if we consider the following HTML: - // - // - // - // then the "non-greedy match" returns: - // - // 'href' => '"X"' // It's wrong! Href is not an attribute of . - // - // while greedy match returns: - // - // 'data-x' => '<a href="X"' - // - // which, can be easily filtered out (#11508). - protectAttributeRegex = /([\w-]+)\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|(?:[^ "'>]+))/gi, - protectAttributeNameRegex = /^(href|src|name)$/i; - - // Note: we use lazy star '*?' to prevent eating everything up to the last occurrence of or . - var protectElementsRegex = /(?:])[^>]*>[\s\S]*?<\/style>)|(?:<(:?link|meta|base)[^>]*>)/gi, - protectTextareaRegex = /(])[^>]*>)([\s\S]*?)(?:<\/textarea>)/gi, - encodedElementsRegex = /([^<]*)<\/cke:encoded>/gi; - - var protectElementNamesRegex = /(<\/?)((?:object|embed|param|html|body|head|title)[^>]*>)/gi, - unprotectElementNamesRegex = /(<\/?)cke:((?:html|body|head|title)[^>]*>)/gi; - - var protectSelfClosingRegex = /]*?)\/?>(?!\s*<\/cke:\1)/gi; - - function protectAttributes( html ) { - return html.replace( protectElementRegex, function( element, tag, attributes ) { - return '<' + tag + attributes.replace( protectAttributeRegex, function( fullAttr, attrName ) { - // Avoid corrupting the inline event attributes (#7243). - // We should not rewrite the existed protected attributes, e.g. clipboard content from editor. (#5218) - if ( protectAttributeNameRegex.test( attrName ) && attributes.indexOf( 'data-cke-saved-' + attrName ) == -1 ) - return ' data-cke-saved-' + fullAttr + ' data-cke-' + CKEDITOR.rnd + '-' + fullAttr; - - return fullAttr; - } ) + '>'; - } ); - } - - function protectElements( html, regex ) { - return html.replace( regex, function( match, tag, content ) { - // Encode < and > in textarea because this won't be done by a browser, since - // textarea will be protected during passing data through fix bin. - if ( match.indexOf( '/g, '>' ) + ''; - - return '' + encodeURIComponent( match ) + ''; - } ); - } - - function unprotectElements( html ) { - return html.replace( encodedElementsRegex, function( match, encoded ) { - return decodeURIComponent( encoded ); - } ); - } - - function protectElementsNames( html ) { - return html.replace( protectElementNamesRegex, '$1cke:$2' ); - } - - function unprotectElementNames( html ) { - return html.replace( unprotectElementNamesRegex, '$1$2' ); - } - - function protectSelfClosingElements( html ) { - return html.replace( protectSelfClosingRegex, '' ); - } - - function protectPreFormatted( html ) { - return CKEDITOR.env.opera ? html : html.replace( /(]*>)(\r\n|\n)/g, '$1$2$2' ); - } - - function protectRealComments( html ) { - return html.replace( //g, function( match ) { - return ''; - } ); - } - - function unprotectRealComments( html ) { - return html.replace( //g, function( match, data ) { - return decodeURIComponent( data ); - } ); - } - - function unprotectSource( html, editor ) { - var store = editor._.dataStore; - - return html.replace( //g, function( match, data ) { - return decodeURIComponent( data ); - } ).replace( /\{cke_protected_(\d+)\}/g, function( match, id ) { - return store && store[ id ] || ''; - } ); - } - - function protectSource( data, editor ) { - var protectedHtml = [], - protectRegexes = editor.config.protectedSource, - store = editor._.dataStore || ( editor._.dataStore = { id: 1 } ), - tempRegex = /<\!--\{cke_temp(comment)?\}(\d*?)-->/g; - - var regexes = [ - // Script tags will also be forced to be protected, otherwise - // IE will execute them. - ( //gi ), - - //